blob: 8a94570da6179d70c72e15a333daea34879b30f9 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- RNBRemote.cpp -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Created by Greg Clayton on 12/12/07.
11//
12//===----------------------------------------------------------------------===//
13
14#include "RNBRemote.h"
15
16#include <errno.h>
17#include <unistd.h>
18#include <signal.h>
19#include <mach/exception_types.h>
20#include <sys/sysctl.h>
21
22#include "DNB.h"
23#include "DNBLog.h"
24#include "DNBThreadResumeActions.h"
25#include "RNBContext.h"
26#include "RNBServices.h"
27#include "RNBSocket.h"
Greg Clayton54e7afa2010-07-09 20:39:50 +000028#include "Utility/StringExtractor.h"
Chris Lattner24943d22010-06-08 16:52:24 +000029
30#include <iomanip>
31#include <sstream>
32
33#include <TargetConditionals.h> // for endianness predefines
34
35//----------------------------------------------------------------------
36// std::iostream formatting macros
37//----------------------------------------------------------------------
38#define RAW_HEXBASE std::setfill('0') << std::hex << std::right
39#define HEXBASE '0' << 'x' << RAW_HEXBASE
40#define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)((uint8_t)x))
41#define RAWHEX16 RAW_HEXBASE << std::setw(4)
42#define RAWHEX32 RAW_HEXBASE << std::setw(8)
43#define RAWHEX64 RAW_HEXBASE << std::setw(16)
44#define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x))
45#define HEX16 HEXBASE << std::setw(4)
46#define HEX32 HEXBASE << std::setw(8)
47#define HEX64 HEXBASE << std::setw(16)
48#define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x)*2) << (x)
49#define HEX(x) HEXBASE << std::setw(sizeof(x)*2) << (x)
50#define RAWHEX_SIZE(x, sz) RAW_HEXBASE << std::setw((sz)) << (x)
51#define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x)
52#define STRING_WIDTH(w) std::setfill(' ') << std::setw(w)
53#define LEFT_STRING_WIDTH(s, w) std::left << std::setfill(' ') << std::setw(w) << (s) << std::right
54#define DECIMAL std::dec << std::setfill(' ')
55#define DECIMAL_WIDTH(w) DECIMAL << std::setw(w)
56#define FLOAT(n, d) std::setfill(' ') << std::setw((n)+(d)+1) << std::setprecision(d) << std::showpoint << std::fixed
57#define INDENT_WITH_SPACES(iword_idx) std::setfill(' ') << std::setw((iword_idx)) << ""
58#define INDENT_WITH_TABS(iword_idx) std::setfill('\t') << std::setw((iword_idx)) << ""
59// Class to handle communications via gdb remote protocol.
60
61extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
62
Greg Clayton20d338f2010-11-18 05:57:03 +000063RNBRemote::RNBRemote (bool use_native_regs, const char *arch) :
64 m_ctx (),
65 m_comm (),
66 m_arch (),
Chris Lattner24943d22010-06-08 16:52:24 +000067 m_continue_thread(-1),
68 m_thread(-1),
69 m_mutex(),
70 m_packets_recvd(0),
71 m_packets(),
72 m_rx_packets(),
73 m_rx_partial_data(),
74 m_rx_pthread(0),
75 m_breakpoints(),
76 m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
Greg Clayton20d338f2010-11-18 05:57:03 +000077 m_extended_mode(false),
78 m_noack_mode(false),
Greg Claytonc71899e2011-01-18 19:36:39 +000079 m_thread_suffix_supported (false),
Chris Lattner24943d22010-06-08 16:52:24 +000080 m_use_native_regs (use_native_regs)
81{
82 DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
83 CreatePacketTable ();
Greg Clayton20d338f2010-11-18 05:57:03 +000084 if (arch && arch[0])
85 m_arch.assign (arch);
Chris Lattner24943d22010-06-08 16:52:24 +000086}
87
88
89RNBRemote::~RNBRemote()
90{
91 DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
92 StopReadRemoteDataThread();
93}
94
95void
96RNBRemote::CreatePacketTable ()
97{
98 // Step required to add new packets:
99 // 1 - Add new enumeration to RNBRemote::PacketEnum
100 // 2 - Create a the RNBRemote::HandlePacket_ function if a new function is needed
101 // 3 - Register the Packet definition with any needed callbacks in this fucntion
102 // - If no response is needed for a command, then use NULL for the normal callback
103 // - If the packet is not supported while the target is running, use NULL for the async callback
104 // 4 - If the packet is a standard packet (starts with a '$' character
105 // followed by the payload and then '#' and checksum, then you are done
106 // else go on to step 5
107 // 5 - if the packet is a fixed length packet:
108 // - modify the switch statement for the first character in the payload
109 // in RNBRemote::CommDataReceived so it doesn't reject the new packet
110 // type as invalid
111 // - modify the switch statement for the first character in the payload
112 // in RNBRemote::GetPacketPayload and make sure the payload of the packet
113 // is returned correctly
114
115 std::vector <Packet> &t = m_packets;
116 t.push_back (Packet (ack, NULL, NULL, "+", "ACK"));
117 t.push_back (Packet (nack, NULL, NULL, "-", "!ACK"));
118 t.push_back (Packet (read_memory, &RNBRemote::HandlePacket_m, NULL, "m", "Read memory"));
119 t.push_back (Packet (read_register, &RNBRemote::HandlePacket_p, NULL, "p", "Read one register"));
120 t.push_back (Packet (read_general_regs, &RNBRemote::HandlePacket_g, NULL, "g", "Read registers"));
121 t.push_back (Packet (write_memory, &RNBRemote::HandlePacket_M, NULL, "M", "Write memory"));
122 t.push_back (Packet (write_register, &RNBRemote::HandlePacket_P, NULL, "P", "Write one register"));
123 t.push_back (Packet (write_general_regs, &RNBRemote::HandlePacket_G, NULL, "G", "Write registers"));
124 t.push_back (Packet (insert_mem_bp, &RNBRemote::HandlePacket_z, NULL, "Z0", "Insert memory breakpoint"));
125 t.push_back (Packet (remove_mem_bp, &RNBRemote::HandlePacket_z, NULL, "z0", "Remove memory breakpoint"));
126 t.push_back (Packet (single_step, &RNBRemote::HandlePacket_s, NULL, "s", "Single step"));
127 t.push_back (Packet (cont, &RNBRemote::HandlePacket_c, NULL, "c", "continue"));
128 t.push_back (Packet (single_step_with_sig, &RNBRemote::HandlePacket_S, NULL, "S", "Single step with signal"));
129 t.push_back (Packet (set_thread, &RNBRemote::HandlePacket_H, NULL, "H", "Set thread"));
130 t.push_back (Packet (halt, &RNBRemote::HandlePacket_last_signal, &RNBRemote::HandlePacket_stop_process, "\x03", "^C"));
131// t.push_back (Packet (use_extended_mode, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode"));
132 t.push_back (Packet (why_halted, &RNBRemote::HandlePacket_last_signal, NULL, "?", "Why did target halt"));
133 t.push_back (Packet (set_argv, &RNBRemote::HandlePacket_A, NULL, "A", "Set argv"));
134// t.push_back (Packet (set_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear breakpoint"));
135 t.push_back (Packet (continue_with_sig, &RNBRemote::HandlePacket_C, NULL, "C", "Continue with signal"));
136 t.push_back (Packet (detach, &RNBRemote::HandlePacket_D, NULL, "D", "Detach gdb from remote system"));
137// t.push_back (Packet (step_inferior_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one clock cycle"));
138// t.push_back (Packet (signal_and_step_inf_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then step one clock cyle"));
139 t.push_back (Packet (kill, &RNBRemote::HandlePacket_k, NULL, "k", "Kill"));
140// t.push_back (Packet (restart, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior"));
141// t.push_back (Packet (search_mem_backwards, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory backwards"));
142 t.push_back (Packet (thread_alive_p, &RNBRemote::HandlePacket_T, NULL, "T", "Is thread alive"));
143 t.push_back (Packet (vattach, &RNBRemote::HandlePacket_v, NULL, "vAttach", "Attach to a new process"));
144 t.push_back (Packet (vattachwait, &RNBRemote::HandlePacket_v, NULL, "vAttachWait", "Wait for a process to start up then attach to it"));
Greg Claytonc1d37752010-10-18 01:45:30 +0000145 t.push_back (Packet (vattachname, &RNBRemote::HandlePacket_v, NULL, "vAttachName", "Attach to an existing process by name"));
Chris Lattner24943d22010-06-08 16:52:24 +0000146 t.push_back (Packet (vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, "vCont;", "Verbose resume with thread actions"));
147 t.push_back (Packet (vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, "vCont?", "List valid continue-with-thread-actions actions"));
148 // The X packet doesn't currently work. If/when it does, remove the line above and uncomment out the line below
149// t.push_back (Packet (write_data_to_memory, &RNBRemote::HandlePacket_X, NULL, "X", "Write data to memory"));
150// t.push_back (Packet (insert_hardware_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware breakpoint"));
151// t.push_back (Packet (remove_hardware_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware breakpoint"));
152// t.push_back (Packet (insert_write_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z2", "Insert write watchpoint"));
153// t.push_back (Packet (remove_write_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z2", "Remove write watchpoint"));
154// t.push_back (Packet (insert_read_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z3", "Insert read watchpoint"));
155// t.push_back (Packet (remove_read_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z3", "Remove read watchpoint"));
156// t.push_back (Packet (insert_access_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z4", "Insert access watchpoint"));
157// t.push_back (Packet (remove_access_watch_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z4", "Remove access watchpoint"));
158 t.push_back (Packet (query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL, "qC", "Query current thread ID"));
159// t.push_back (Packet (query_memory_crc, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qCRC:", "Compute CRC of memory region"));
160 t.push_back (Packet (query_thread_ids_first, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo", "Get list of active threads (first req)"));
161 t.push_back (Packet (query_thread_ids_subsequent, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo", "Get list of active threads (subsequent req)"));
162 // APPLE LOCAL: qThreadStopInfo
163 // syntax: qThreadStopInfoTTTT
164 // TTTT is hex thread ID
165 t.push_back (Packet (query_thread_stop_info, &RNBRemote::HandlePacket_qThreadStopInfo, NULL, "qThreadStopInfo", "Get detailed info on why the specified thread stopped"));
166 t.push_back (Packet (query_thread_extra_info, &RNBRemote::HandlePacket_qThreadExtraInfo,NULL, "qThreadExtraInfo", "Get printable status of a thread"));
167// t.push_back (Packet (query_image_offsets, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qOffsets", "Report offset of loaded program"));
168 t.push_back (Packet (query_launch_success, &RNBRemote::HandlePacket_qLaunchSuccess,NULL, "qLaunchSuccess", "Report the success or failure of the launch attempt"));
169 t.push_back (Packet (query_register_info, &RNBRemote::HandlePacket_qRegisterInfo, NULL, "qRegisterInfo", "Dynamically discover remote register context information."));
170 t.push_back (Packet (query_shlib_notify_info_addr, &RNBRemote::HandlePacket_qShlibInfoAddr,NULL, "qShlibInfoAddr", "Returns the address that contains info needed for getting shared library notifications"));
171 t.push_back (Packet (query_step_packet_supported, &RNBRemote::HandlePacket_qStepPacketSupported,NULL, "qStepPacketSupported", "Replys with OK if the 's' packet is supported."));
172 t.push_back (Packet (query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
173// t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups"));
Greg Claytonc71899e2011-01-18 19:36:39 +0000174 t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
175 t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specifc packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
176 t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix"));
177 t.push_back (Packet (set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
178 t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
179 t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_QEnvironment , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
180 t.push_back (Packet (set_disable_aslr, &RNBRemote::HandlePacket_QSetDisableASLR , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet"));
Chris Lattner24943d22010-06-08 16:52:24 +0000181// t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
182 t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
183 t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
184}
185
186
187void
188RNBRemote::FlushSTDIO ()
189{
190 if (m_ctx.HasValidProcessID())
191 {
192 nub_process_t pid = m_ctx.ProcessID();
193 char buf[256];
194 nub_size_t count;
195 do
196 {
197 count = DNBProcessGetAvailableSTDOUT(pid, buf, sizeof(buf));
198 if (count > 0)
199 {
200 SendSTDOUTPacket (buf, count);
201 }
202 } while (count > 0);
203
204 do
205 {
206 count = DNBProcessGetAvailableSTDERR(pid, buf, sizeof(buf));
207 if (count > 0)
208 {
209 SendSTDERRPacket (buf, count);
210 }
211 } while (count > 0);
212 }
213}
214
215rnb_err_t
216RNBRemote::SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer)
217{
218 std::ostringstream packet_sstrm;
219 // Append the header cstr if there was one
220 if (header && header[0])
221 packet_sstrm << header;
222 nub_size_t i;
223 const uint8_t *ubuf8 = (const uint8_t *)buf;
224 for (i=0; i<buf_len; i++)
225 {
226 packet_sstrm << RAWHEX8(ubuf8[i]);
227 }
228 // Append the footer cstr if there was one
229 if (footer && footer[0])
230 packet_sstrm << footer;
231
232 return SendPacket(packet_sstrm.str());
233}
234
235rnb_err_t
236RNBRemote::SendSTDOUTPacket (char *buf, nub_size_t buf_size)
237{
238 if (buf_size == 0)
239 return rnb_success;
240 return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
241}
242
243rnb_err_t
244RNBRemote::SendSTDERRPacket (char *buf, nub_size_t buf_size)
245{
246 if (buf_size == 0)
247 return rnb_success;
248 return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
249}
250
251rnb_err_t
252RNBRemote::SendPacket (const std::string &s)
253{
254 DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, s.c_str());
255 std::string sendpacket = "$" + s + "#";
256 int cksum = 0;
257 char hexbuf[5];
258
259 if (m_noack_mode)
260 {
261 sendpacket += "00";
262 }
263 else
264 {
265 for (int i = 0; i != s.size(); ++i)
266 cksum += s[i];
267 snprintf (hexbuf, sizeof hexbuf, "%02x", cksum & 0xff);
268 sendpacket += hexbuf;
269 }
270
271 rnb_err_t err = m_comm.Write (sendpacket.c_str(), sendpacket.size());
272 if (err != rnb_success)
273 return err;
274
275 if (m_noack_mode)
276 return rnb_success;
277
278 std::string reply;
279 RNBRemote::Packet packet;
280 err = GetPacket (reply, packet, true);
281
282 if (err != rnb_success)
283 {
284 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s (%s) got error trying to get reply...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, sendpacket.c_str());
285 return err;
286 }
287
288 DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) got reply: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, sendpacket.c_str(), reply.c_str());
289
290 if (packet.type == ack)
291 return rnb_success;
292
293 // Should we try to resend the packet at this layer?
294 // if (packet.command == nack)
295 return rnb_err;
296}
297
298/* Get a packet via gdb remote protocol.
299 Strip off the prefix/suffix, verify the checksum to make sure
300 a valid packet was received, send an ACK if they match. */
301
302rnb_err_t
303RNBRemote::GetPacketPayload (std::string &return_packet)
304{
305 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
306
307 PThreadMutex::Locker locker(m_mutex);
308 if (m_rx_packets.empty())
309 {
310 // Only reset the remote command available event if we have no more packets
311 m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available );
312 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s error: no packets available...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
313 return rnb_err;
314 }
315
316 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s has %u queued packets", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, m_rx_packets.size());
317 return_packet.swap(m_rx_packets.front());
318 m_rx_packets.pop_front();
319 locker.Reset(); // Release our lock on the mutex
320
321 if (m_rx_packets.empty())
322 {
323 // Reset the remote command available event if we have no more packets
324 m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available );
325 }
326
327 //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
328
329 switch (return_packet[0])
330 {
331 case '+':
332 case '-':
333 case '\x03':
334 break;
335
336 case '$':
337 {
338 int packet_checksum = 0;
339 if (!m_noack_mode)
340 {
341 for (int i = return_packet.size() - 2; i < return_packet.size(); ++i)
342 {
343 char checksum_char = tolower (return_packet[i]);
344 if (!isxdigit (checksum_char))
345 {
346 m_comm.Write ("-", 1);
347 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s error: packet with invalid checksum characters: %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
348 return rnb_err;
349 }
350 }
351 packet_checksum = strtol (&return_packet[return_packet.size() - 2], NULL, 16);
352 }
353
354 return_packet.erase(0,1); // Strip the leading '$'
355 return_packet.erase(return_packet.size() - 3);// Strip the #XX checksum
356
357 if (!m_noack_mode)
358 {
359 // Compute the checksum
360 int computed_checksum = 0;
361 for (std::string::iterator it = return_packet.begin ();
362 it != return_packet.end ();
363 ++it)
364 {
365 computed_checksum += *it;
366 }
367
368 if (packet_checksum == (computed_checksum & 0xff))
369 {
370 //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
371 m_comm.Write ("+", 1);
372 }
373 else
374 {
375 DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s' (error: packet checksum mismatch (0x%2.2x != 0x%2.2x))",
376 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
377 __FUNCTION__,
378 return_packet.c_str(),
379 packet_checksum,
380 computed_checksum);
381 m_comm.Write ("-", 1);
382 return rnb_err;
383 }
384 }
385 }
386 break;
387
388 default:
389 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s tossing unexpected packet???? %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
390 if (!m_noack_mode)
391 m_comm.Write ("-", 1);
392 return rnb_err;
393 }
394
395 return rnb_success;
396}
397
398rnb_err_t
399RNBRemote::HandlePacket_UNIMPLEMENTED (const char* p)
400{
401 DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s(\"%s\")", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p ? p : "NULL");
402 return SendPacket ("");
403}
404
405rnb_err_t
406RNBRemote::HandlePacket_ILLFORMED (const char *description)
407{
408 DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s sending ILLFORMED", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
409 return SendPacket ("E03");
410}
411
412rnb_err_t
413RNBRemote::GetPacket (std::string &packet_payload, RNBRemote::Packet& packet_info, bool wait)
414{
415 std::string payload;
416 rnb_err_t err = GetPacketPayload (payload);
417 if (err != rnb_success)
418 {
419 PThreadEvent& events = m_ctx.Events();
420 nub_event_t set_events = events.GetEventBits();
421 // TODO: add timeout version of GetPacket?? We would then need to pass
422 // that timeout value along to DNBProcessTimedWaitForEvent.
423 if (!wait || ((set_events & RNBContext::event_read_thread_running) == 0))
424 return err;
425
426 const nub_event_t events_to_wait_for = RNBContext::event_read_packet_available | RNBContext::event_read_thread_exiting;
427 set_events = 0;
428
429 while ((set_events = events.WaitForSetEvents(events_to_wait_for)) != 0)
430 {
431 if (set_events & RNBContext::event_read_packet_available)
432 {
433 // Try the queue again now that we got an event
434 err = GetPacketPayload (payload);
435 if (err == rnb_success)
436 break;
437 }
438
439 if (set_events & RNBContext::event_read_thread_exiting)
440 err = rnb_not_connected;
441
442 if (err == rnb_not_connected)
443 return err;
444
445 } while (err == rnb_err);
446
447 if (set_events == 0)
448 err = rnb_not_connected;
449 }
450
451 if (err == rnb_success)
452 {
453 Packet::iterator it;
454 for (it = m_packets.begin (); it != m_packets.end (); ++it)
455 {
456 if (payload.compare (0, it->abbrev.size(), it->abbrev) == 0)
457 break;
458 }
459
460 // A packet we don't have an entry for. This can happen when we
461 // get a packet that we don't know about or support. We just reply
462 // accordingly and go on.
463 if (it == m_packets.end ())
464 {
465 DNBLogThreadedIf (LOG_RNB_PACKETS, "unimplemented packet: '%s'", payload.c_str());
466 HandlePacket_UNIMPLEMENTED(payload.c_str());
467 return rnb_err;
468 }
469 else
470 {
471 packet_info = *it;
472 packet_payload = payload;
473 }
474 }
475 return err;
476}
477
478rnb_err_t
479RNBRemote::HandleAsyncPacket(PacketEnum *type)
480{
481 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
482 static DNBTimer g_packetTimer(true);
483 rnb_err_t err = rnb_err;
484 std::string packet_data;
485 RNBRemote::Packet packet_info;
486 err = GetPacket (packet_data, packet_info, false);
487
488 if (err == rnb_success)
489 {
490 if (!packet_data.empty() && isprint(packet_data[0]))
491 DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (\"%s\");", packet_data.c_str());
492 else
493 DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (%s);", packet_info.printable_name.c_str());
494
495 HandlePacketCallback packet_callback = packet_info.async;
496 if (packet_callback != NULL)
497 {
498 if (type != NULL)
499 *type = packet_info.type;
500 return (this->*packet_callback)(packet_data.c_str());
501 }
502 }
503
504 return err;
505}
506
507rnb_err_t
508RNBRemote::HandleReceivedPacket(PacketEnum *type)
509{
510 static DNBTimer g_packetTimer(true);
511
512 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
513 rnb_err_t err = rnb_err;
514 std::string packet_data;
515 RNBRemote::Packet packet_info;
516 err = GetPacket (packet_data, packet_info, false);
517
518 if (err == rnb_success)
519 {
520 DNBLogThreadedIf (LOG_RNB_REMOTE, "HandleReceivedPacket (\"%s\");", packet_data.c_str());
521 HandlePacketCallback packet_callback = packet_info.normal;
522 if (packet_callback != NULL)
523 {
524 if (type != NULL)
525 *type = packet_info.type;
526 return (this->*packet_callback)(packet_data.c_str());
527 }
528 else
529 {
530 // Do not fall through to end of this function, if we have valid
531 // packet_info and it has a NULL callback, then we need to respect
532 // that it may not want any response or anything to be done.
533 return err;
534 }
535 }
536 return rnb_err;
537}
538
539void
540RNBRemote::CommDataReceived(const std::string& new_data)
541{
542 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
543 {
544 // Put the packet data into the buffer in a thread safe fashion
545 PThreadMutex::Locker locker(m_mutex);
546
547 std::string data;
548 // See if we have any left over data from a previous call to this
549 // function?
550 if (!m_rx_partial_data.empty())
551 {
552 // We do, so lets start with that data
553 data.swap(m_rx_partial_data);
554 }
555 // Append the new incoming data
556 data += new_data;
557
558 // Parse up the packets into gdb remote packets
559 uint32_t idx = 0;
560 const size_t data_size = data.size();
561
562 while (idx < data_size)
563 {
564 // end_idx must be one past the last valid packet byte. Start
565 // it off with an invalid value that is the same as the current
566 // index.
567 size_t end_idx = idx;
568
569 switch (data[idx])
570 {
571 case '+': // Look for ack
572 case '-': // Look for cancel
573 case '\x03': // ^C to halt target
574 end_idx = idx + 1; // The command is one byte long...
575 break;
576
577 case '$':
578 // Look for a standard gdb packet?
579 end_idx = data.find('#', idx + 1);
580 if (end_idx == std::string::npos || end_idx + 2 > data_size)
581 {
582 end_idx = std::string::npos;
583 }
584 else
585 {
586 // Add two for the checksum bytes
587 end_idx += 4;
588 }
589 break;
590
591 default:
592 break;
593 }
594
595 if (end_idx == std::string::npos)
596 {
597 // Not all data may be here for the packet yet, save it for
598 // next time through this function.
599 m_rx_partial_data += data.substr(idx);
600 //DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s saving data for later[%u, npos): '%s'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, idx, m_rx_partial_data.c_str());
601 idx = end_idx;
602 }
603 else
604 if (idx < end_idx)
605 {
606 m_packets_recvd++;
607 // Hack to get rid of initial '+' ACK???
608 if (m_packets_recvd == 1 && (end_idx == idx + 1) && data[idx] == '+')
609 {
610 //DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s throwing first ACK away....[%u, npos): '+'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, idx);
611 }
612 else
613 {
614 // We have a valid packet...
615 m_rx_packets.push_back(data.substr(idx, end_idx - idx));
616 DNBLogThreadedIf (LOG_RNB_PACKETS, "getpkt: %s", m_rx_packets.back().c_str());
617 }
618 idx = end_idx;
619 }
620 else
621 {
622 DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s tossing junk byte at %c",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, data[idx]);
623 idx = idx + 1;
624 }
625 }
626 }
627
628 if (!m_rx_packets.empty())
629 {
630 // Let the main thread know we have received a packet
631
632 //DNBLogThreadedIf (LOG_RNB_EVENTS, "%8d RNBRemote::%s called events.SetEvent(RNBContext::event_read_packet_available)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
633 PThreadEvent& events = m_ctx.Events();
634 events.SetEvents (RNBContext::event_read_packet_available);
635 }
636}
637
638rnb_err_t
639RNBRemote::GetCommData ()
640{
641 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
642 std::string comm_data;
643 rnb_err_t err = m_comm.Read (comm_data);
644 if (err == rnb_success)
645 {
646 if (!comm_data.empty())
647 CommDataReceived (comm_data);
648 }
649 return err;
650}
651
652void
653RNBRemote::StartReadRemoteDataThread()
654{
655 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
656 PThreadEvent& events = m_ctx.Events();
657 if ((events.GetEventBits() & RNBContext::event_read_thread_running) == 0)
658 {
659 events.ResetEvents (RNBContext::event_read_thread_exiting);
660 int err = ::pthread_create (&m_rx_pthread, NULL, ThreadFunctionReadRemoteData, this);
661 if (err == 0)
662 {
663 // Our thread was successfully kicked off, wait for it to
664 // set the started event so we can safely continue
665 events.WaitForSetEvents (RNBContext::event_read_thread_running);
666 }
667 else
668 {
669 events.ResetEvents (RNBContext::event_read_thread_running);
670 events.SetEvents (RNBContext::event_read_thread_exiting);
671 }
672 }
673}
674
675void
676RNBRemote::StopReadRemoteDataThread()
677{
678 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
679 PThreadEvent& events = m_ctx.Events();
680 if ((events.GetEventBits() & RNBContext::event_read_thread_running) == RNBContext::event_read_thread_running)
681 {
682 m_comm.Disconnect(true);
683 struct timespec timeout_abstime;
684 DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0);
685
686 // Wait for 2 seconds for the remote data thread to exit
687 if (events.WaitForSetEvents(RNBContext::event_read_thread_exiting, &timeout_abstime) == 0)
688 {
689 // Kill the remote data thread???
690 }
691 }
692}
693
694
695void*
696RNBRemote::ThreadFunctionReadRemoteData(void *arg)
697{
698 // Keep a shared pointer reference so this doesn't go away on us before the thread is killed.
699 DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread starting...", __FUNCTION__, arg);
700 RNBRemoteSP remoteSP(g_remoteSP);
701 if (remoteSP.get() != NULL)
702 {
703 RNBRemote* remote = remoteSP.get();
704 PThreadEvent& events = remote->Context().Events();
705 events.SetEvents (RNBContext::event_read_thread_running);
706 // START: main receive remote command thread loop
707 bool done = false;
708 while (!done)
709 {
710 rnb_err_t err = remote->GetCommData();
711
712 switch (err)
713 {
714 case rnb_success:
715 break;
716
717 default:
718 case rnb_err:
719 DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err);
720 done = true;
721 break;
722
723 case rnb_not_connected:
724 DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned not connected...");
725 done = true;
726 break;
727 }
728 }
729 // START: main receive remote command thread loop
730 events.ResetEvents (RNBContext::event_read_thread_running);
731 events.SetEvents (RNBContext::event_read_thread_exiting);
732 }
733 DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...", __FUNCTION__, arg);
734 return NULL;
735}
736
737
738
739/* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes
740 (8-bit bytes).
741 This encoding uses 0x7d ('}') as an escape character for 0x7d ('}'),
742 0x23 ('#'), and 0x24 ('$').
743 LEN is the number of bytes to be processed. If a character is escaped,
744 it is 2 characters for LEN. A LEN of -1 means encode-until-nul-byte
745 (end of string). */
746
747std::vector<uint8_t>
748decode_binary_data (const char *str, int len)
749{
750 std::vector<uint8_t> bytes;
751 if (len == 0)
752 {
753 return bytes;
754 }
755 if (len == -1)
756 len = strlen (str);
757
758 while (len--)
759 {
760 unsigned char c = *str;
761 if (c == 0x7d && len > 0)
762 {
763 len--;
764 str++;
765 c ^= 0x20;
766 }
767 bytes.push_back (c);
768 }
769 return bytes;
770}
771
772typedef struct register_map_entry
773{
774 uint32_t gdb_regnum; // gdb register number
775 uint32_t gdb_size; // gdb register size in bytes (can be greater than or less than to debugnub size...)
776 const char * gdb_name; // gdb register name
777 DNBRegisterInfo nub_info; // debugnub register info
778 const uint8_t* fail_value; // Value to print if case we fail to reg this register (if this is NULL, we will return an error)
779 int expedite; // expedite delivery of this register in last stop reply packets
780} register_map_entry_t;
781
782
783
784// If the notion of registers differs from what is handed out by the
785// architecture, then flavors can be defined here.
786
787static const uint32_t MAX_REGISTER_BYTE_SIZE = 16;
788static const uint8_t k_zero_bytes[MAX_REGISTER_BYTE_SIZE] = {0};
789static std::vector<register_map_entry_t> g_dynamic_register_map;
790static register_map_entry_t *g_reg_entries = NULL;
791static size_t g_num_reg_entries = 0;
792
793static void
794RegisterEntryNotAvailable (register_map_entry_t *reg_entry)
795{
796 reg_entry->fail_value = k_zero_bytes;
797 reg_entry->nub_info.set = INVALID_NUB_REGNUM;
798 reg_entry->nub_info.reg = INVALID_NUB_REGNUM;
799 reg_entry->nub_info.name = NULL;
800 reg_entry->nub_info.alt = NULL;
801 reg_entry->nub_info.type = InvalidRegType;
802 reg_entry->nub_info.format = InvalidRegFormat;
803 reg_entry->nub_info.size = 0;
804 reg_entry->nub_info.offset = 0;
805 reg_entry->nub_info.reg_gcc = INVALID_NUB_REGNUM;
806 reg_entry->nub_info.reg_dwarf = INVALID_NUB_REGNUM;
807 reg_entry->nub_info.reg_generic = INVALID_NUB_REGNUM;
808 reg_entry->nub_info.reg_gdb = INVALID_NUB_REGNUM;
809}
810
Chris Lattner24943d22010-06-08 16:52:24 +0000811
812//----------------------------------------------------------------------
813// ARM regiseter sets as gdb knows them
814//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +0000815register_map_entry_t
816g_gdb_register_map_arm[] =
817{
818 { 0, 4, "r0", {0}, NULL, 1},
819 { 1, 4, "r1", {0}, NULL, 1},
820 { 2, 4, "r2", {0}, NULL, 1},
821 { 3, 4, "r3", {0}, NULL, 1},
822 { 4, 4, "r4", {0}, NULL, 1},
823 { 5, 4, "r5", {0}, NULL, 1},
824 { 6, 4, "r6", {0}, NULL, 1},
825 { 7, 4, "r7", {0}, NULL, 1},
826 { 8, 4, "r8", {0}, NULL, 1},
827 { 9, 4, "r9", {0}, NULL, 1},
828 { 10, 4, "r10", {0}, NULL, 1},
829 { 11, 4, "r11", {0}, NULL, 1},
830 { 12, 4, "r12", {0}, NULL, 1},
831 { 13, 4, "sp", {0}, NULL, 1},
832 { 14, 4, "lr", {0}, NULL, 1},
833 { 15, 4, "pc", {0}, NULL, 1},
Greg Clayton0a7f75f2010-09-09 06:32:46 +0000834 { 16, 12, "f0", {0}, k_zero_bytes, 0},
835 { 17, 12, "f1", {0}, k_zero_bytes, 0},
836 { 18, 12, "f2", {0}, k_zero_bytes, 0},
837 { 19, 12, "f3", {0}, k_zero_bytes, 0},
838 { 20, 12, "f4", {0}, k_zero_bytes, 0},
839 { 21, 12, "f5", {0}, k_zero_bytes, 0},
840 { 22, 12, "f6", {0}, k_zero_bytes, 0},
841 { 23, 12, "f7", {0}, k_zero_bytes, 0},
Chris Lattner24943d22010-06-08 16:52:24 +0000842 { 24, 4, "fps", {0}, NULL, 0},
843 { 25, 4,"cpsr", {0}, NULL, 1},
844 { 26, 4, "s0", {0}, NULL, 0},
845 { 27, 4, "s1", {0}, NULL, 0},
846 { 28, 4, "s2", {0}, NULL, 0},
847 { 29, 4, "s3", {0}, NULL, 0},
848 { 30, 4, "s4", {0}, NULL, 0},
849 { 31, 4, "s5", {0}, NULL, 0},
850 { 32, 4, "s6", {0}, NULL, 0},
851 { 33, 4, "s7", {0}, NULL, 0},
852 { 34, 4, "s8", {0}, NULL, 0},
853 { 35, 4, "s9", {0}, NULL, 0},
854 { 36, 4, "s10", {0}, NULL, 0},
855 { 37, 4, "s11", {0}, NULL, 0},
856 { 38, 4, "s12", {0}, NULL, 0},
857 { 39, 4, "s13", {0}, NULL, 0},
858 { 40, 4, "s14", {0}, NULL, 0},
859 { 41, 4, "s15", {0}, NULL, 0},
860 { 42, 4, "s16", {0}, NULL, 0},
861 { 43, 4, "s17", {0}, NULL, 0},
862 { 44, 4, "s18", {0}, NULL, 0},
863 { 45, 4, "s19", {0}, NULL, 0},
864 { 46, 4, "s20", {0}, NULL, 0},
865 { 47, 4, "s21", {0}, NULL, 0},
866 { 48, 4, "s22", {0}, NULL, 0},
867 { 49, 4, "s23", {0}, NULL, 0},
868 { 50, 4, "s24", {0}, NULL, 0},
869 { 51, 4, "s25", {0}, NULL, 0},
870 { 52, 4, "s26", {0}, NULL, 0},
871 { 53, 4, "s27", {0}, NULL, 0},
872 { 54, 4, "s28", {0}, NULL, 0},
873 { 55, 4, "s29", {0}, NULL, 0},
874 { 56, 4, "s30", {0}, NULL, 0},
875 { 57, 4, "s31", {0}, NULL, 0},
876 { 58, 4, "fpscr", {0}, NULL, 0}
877};
878
Chris Lattner24943d22010-06-08 16:52:24 +0000879register_map_entry_t
880g_gdb_register_map_i386[] =
881{
882 { 0, 4, "eax" , {0}, NULL, 0 },
883 { 1, 4, "ecx" , {0}, NULL, 0 },
884 { 2, 4, "edx" , {0}, NULL, 0 },
885 { 3, 4, "ebx" , {0}, NULL, 0 },
886 { 4, 4, "esp" , {0}, NULL, 1 },
887 { 5, 4, "ebp" , {0}, NULL, 1 },
888 { 6, 4, "esi" , {0}, NULL, 0 },
889 { 7, 4, "edi" , {0}, NULL, 0 },
890 { 8, 4, "eip" , {0}, NULL, 1 },
891 { 9, 4, "eflags" , {0}, NULL, 0 },
892 { 10, 4, "cs" , {0}, NULL, 0 },
893 { 11, 4, "ss" , {0}, NULL, 0 },
894 { 12, 4, "ds" , {0}, NULL, 0 },
895 { 13, 4, "es" , {0}, NULL, 0 },
896 { 14, 4, "fs" , {0}, NULL, 0 },
897 { 15, 4, "gs" , {0}, NULL, 0 },
898 { 16, 10, "stmm0" , {0}, NULL, 0 },
899 { 17, 10, "stmm1" , {0}, NULL, 0 },
900 { 18, 10, "stmm2" , {0}, NULL, 0 },
901 { 19, 10, "stmm3" , {0}, NULL, 0 },
902 { 20, 10, "stmm4" , {0}, NULL, 0 },
903 { 21, 10, "stmm5" , {0}, NULL, 0 },
904 { 22, 10, "stmm6" , {0}, NULL, 0 },
905 { 23, 10, "stmm7" , {0}, NULL, 0 },
906 { 24, 4, "fctrl" , {0}, NULL, 0 },
907 { 25, 4, "fstat" , {0}, NULL, 0 },
908 { 26, 4, "ftag" , {0}, NULL, 0 },
909 { 27, 4, "fiseg" , {0}, NULL, 0 },
910 { 28, 4, "fioff" , {0}, NULL, 0 },
911 { 29, 4, "foseg" , {0}, NULL, 0 },
912 { 30, 4, "fooff" , {0}, NULL, 0 },
913 { 31, 4, "fop" , {0}, NULL, 0 },
914 { 32, 16, "xmm0" , {0}, NULL, 0 },
915 { 33, 16, "xmm1" , {0}, NULL, 0 },
916 { 34, 16, "xmm2" , {0}, NULL, 0 },
917 { 35, 16, "xmm3" , {0}, NULL, 0 },
918 { 36, 16, "xmm4" , {0}, NULL, 0 },
919 { 37, 16, "xmm5" , {0}, NULL, 0 },
920 { 38, 16, "xmm6" , {0}, NULL, 0 },
921 { 39, 16, "xmm7" , {0}, NULL, 0 },
922 { 40, 4, "mxcsr" , {0}, NULL, 0 },
923};
924
Chris Lattner24943d22010-06-08 16:52:24 +0000925register_map_entry_t
926g_gdb_register_map_x86_64[] =
927{
928 { 0, 8, "rax" , {0}, NULL, 0 },
929 { 1, 8, "rbx" , {0}, NULL, 0 },
930 { 2, 8, "rcx" , {0}, NULL, 0 },
931 { 3, 8, "rdx" , {0}, NULL, 0 },
932 { 4, 8, "rsi" , {0}, NULL, 0 },
933 { 5, 8, "rdi" , {0}, NULL, 0 },
934 { 6, 8, "rbp" , {0}, NULL, 1 },
935 { 7, 8, "rsp" , {0}, NULL, 1 },
936 { 8, 8, "r8" , {0}, NULL, 0 },
937 { 9, 8, "r9" , {0}, NULL, 0 },
938 { 10, 8, "r10" , {0}, NULL, 0 },
939 { 11, 8, "r11" , {0}, NULL, 0 },
940 { 12, 8, "r12" , {0}, NULL, 0 },
941 { 13, 8, "r13" , {0}, NULL, 0 },
942 { 14, 8, "r14" , {0}, NULL, 0 },
943 { 15, 8, "r15" , {0}, NULL, 0 },
944 { 16, 8, "rip" , {0}, NULL, 1 },
945 { 17, 4, "rflags", {0}, NULL, 0 },
946 { 18, 4, "cs" , {0}, NULL, 0 },
947 { 19, 4, "ss" , {0}, NULL, 0 },
948 { 20, 4, "ds" , {0}, NULL, 0 },
949 { 21, 4, "es" , {0}, NULL, 0 },
950 { 22, 4, "fs" , {0}, NULL, 0 },
951 { 23, 4, "gs" , {0}, NULL, 0 },
952 { 24, 10, "stmm0" , {0}, NULL, 0 },
953 { 25, 10, "stmm1" , {0}, NULL, 0 },
954 { 26, 10, "stmm2" , {0}, NULL, 0 },
955 { 27, 10, "stmm3" , {0}, NULL, 0 },
956 { 28, 10, "stmm4" , {0}, NULL, 0 },
957 { 29, 10, "stmm5" , {0}, NULL, 0 },
958 { 30, 10, "stmm6" , {0}, NULL, 0 },
959 { 31, 10, "stmm7" , {0}, NULL, 0 },
960 { 32, 4, "fctrl" , {0}, NULL, 0 },
961 { 33, 4, "fstat" , {0}, NULL, 0 },
962 { 34, 4, "ftag" , {0}, NULL, 0 },
963 { 35, 4, "fiseg" , {0}, NULL, 0 },
964 { 36, 4, "fioff" , {0}, NULL, 0 },
965 { 37, 4, "foseg" , {0}, NULL, 0 },
966 { 38, 4, "fooff" , {0}, NULL, 0 },
967 { 39, 4, "fop" , {0}, NULL, 0 },
968 { 40, 16, "xmm0" , {0}, NULL, 0 },
969 { 41, 16, "xmm1" , {0}, NULL, 0 },
970 { 42, 16, "xmm2" , {0}, NULL, 0 },
971 { 43, 16, "xmm3" , {0}, NULL, 0 },
972 { 44, 16, "xmm4" , {0}, NULL, 0 },
973 { 45, 16, "xmm5" , {0}, NULL, 0 },
974 { 46, 16, "xmm6" , {0}, NULL, 0 },
975 { 47, 16, "xmm7" , {0}, NULL, 0 },
976 { 48, 16, "xmm8" , {0}, NULL, 0 },
977 { 49, 16, "xmm9" , {0}, NULL, 0 },
978 { 50, 16, "xmm10" , {0}, NULL, 0 },
979 { 51, 16, "xmm11" , {0}, NULL, 0 },
980 { 52, 16, "xmm12" , {0}, NULL, 0 },
981 { 53, 16, "xmm13" , {0}, NULL, 0 },
982 { 54, 16, "xmm14" , {0}, NULL, 0 },
983 { 55, 16, "xmm15" , {0}, NULL, 0 },
984 { 56, 4, "mxcsr" , {0}, NULL, 0 }
985};
986
Greg Clayton20d338f2010-11-18 05:57:03 +0000987
Chris Lattner24943d22010-06-08 16:52:24 +0000988void
Greg Clayton20d338f2010-11-18 05:57:03 +0000989RNBRemote::Initialize()
Chris Lattner24943d22010-06-08 16:52:24 +0000990{
Greg Clayton20d338f2010-11-18 05:57:03 +0000991 DNBInitialize();
992}
993
994
995bool
996RNBRemote::InitializeRegisters ()
997{
998 pid_t pid = m_ctx.ProcessID();
999 if (pid == INVALID_NUB_PROCESS)
1000 return false;
1001
1002 if (m_use_native_regs)
Chris Lattner24943d22010-06-08 16:52:24 +00001003 {
Greg Clayton20d338f2010-11-18 05:57:03 +00001004 DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface (%s)", __FUNCTION__, m_arch.c_str());
1005 // Discover the registers by querying the DNB interface and letting it
1006 // state the registers that it would like to export. This allows the
1007 // registers to be discovered using multiple qRegisterInfo calls to get
1008 // all register information after the architecture for the process is
1009 // determined.
1010 if (g_dynamic_register_map.empty())
1011 {
1012 nub_size_t num_reg_sets = 0;
1013 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
1014
1015 assert (num_reg_sets > 0 && reg_sets != NULL);
1016
1017 uint32_t regnum = 0;
1018 for (nub_size_t set = 0; set < num_reg_sets; ++set)
1019 {
1020 if (reg_sets[set].registers == NULL)
1021 continue;
1022
1023 for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
1024 {
1025 register_map_entry_t reg_entry = {
1026 regnum++, // register number starts at zero and goes up with no gaps
1027 reg_sets[set].registers[reg].size, // register size in bytes
1028 reg_sets[set].registers[reg].name, // register name
1029 reg_sets[set].registers[reg], // DNBRegisterInfo
1030 NULL, // Value to print if case we fail to reg this register (if this is NULL, we will return an error)
1031 reg_sets[set].registers[reg].reg_generic != INVALID_NUB_REGNUM};
1032
1033 g_dynamic_register_map.push_back (reg_entry);
1034 }
1035 }
1036 g_reg_entries = g_dynamic_register_map.data();
1037 g_num_reg_entries = g_dynamic_register_map.size();
1038 }
1039 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00001040 }
1041 else
1042 {
Greg Clayton20d338f2010-11-18 05:57:03 +00001043 DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting gdb registers (%s)", __FUNCTION__, m_arch.c_str());
1044#if defined (__i386__) || defined (__x86_64__)
1045 if (m_arch.compare("x86_64") == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001046 {
Greg Clayton20d338f2010-11-18 05:57:03 +00001047 const size_t num_regs = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
1048 for (uint32_t i=0; i<num_regs; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001049 {
Greg Clayton20d338f2010-11-18 05:57:03 +00001050 if (!DNBGetRegisterInfoByName (g_gdb_register_map_x86_64[i].gdb_name, &g_gdb_register_map_x86_64[i].nub_info))
1051 {
1052 RegisterEntryNotAvailable (&g_gdb_register_map_x86_64[i]);
1053 assert (g_gdb_register_map_x86_64[i].gdb_size < MAX_REGISTER_BYTE_SIZE);
1054 }
Chris Lattner24943d22010-06-08 16:52:24 +00001055 }
Greg Clayton20d338f2010-11-18 05:57:03 +00001056 g_reg_entries = g_gdb_register_map_x86_64;
1057 g_num_reg_entries = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
1058 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00001059 }
Greg Clayton20d338f2010-11-18 05:57:03 +00001060 else if (m_arch.compare("i386") == 0)
1061 {
1062 const size_t num_regs = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
1063 for (uint32_t i=0; i<num_regs; ++i)
1064 {
1065 if (!DNBGetRegisterInfoByName (g_gdb_register_map_i386[i].gdb_name, &g_gdb_register_map_i386[i].nub_info))
1066 {
1067 RegisterEntryNotAvailable (&g_gdb_register_map_i386[i]);
1068 assert (g_gdb_register_map_i386[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
1069 }
1070 }
1071 g_reg_entries = g_gdb_register_map_i386;
1072 g_num_reg_entries = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
1073 return true;
1074 }
1075#elif defined (__arm__)
1076 if (m_arch.find ("arm") == 0)
1077 {
1078 const size_t num_regs = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
1079 for (uint32_t i=0; i<num_regs; ++i)
1080 {
1081 if (!DNBGetRegisterInfoByName (g_gdb_register_map_arm[i].gdb_name, &g_gdb_register_map_arm[i].nub_info))
1082 {
1083 RegisterEntryNotAvailable (&g_gdb_register_map_arm[i]);
1084 assert (g_gdb_register_map_arm[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
1085 }
1086 }
1087 g_reg_entries = g_gdb_register_map_arm;
1088 g_num_reg_entries = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
1089 return true;
1090 }
Chris Lattner24943d22010-06-08 16:52:24 +00001091#endif
Chris Lattner24943d22010-06-08 16:52:24 +00001092 }
Greg Clayton20d338f2010-11-18 05:57:03 +00001093 return false;
Chris Lattner24943d22010-06-08 16:52:24 +00001094}
1095
1096/* The inferior has stopped executing; send a packet
1097 to gdb to let it know. */
1098
1099void
1100RNBRemote::NotifyThatProcessStopped (void)
1101{
Greg Clayton20d338f2010-11-18 05:57:03 +00001102 RNBRemote::HandlePacket_last_signal (NULL);
Chris Lattner24943d22010-06-08 16:52:24 +00001103 return;
1104}
1105
1106
1107/* `A arglen,argnum,arg,...'
1108 Update the inferior context CTX with the program name and arg
1109 list.
1110 The documentation for this packet is underwhelming but my best reading
1111 of this is that it is a series of (len, position #, arg)'s, one for
1112 each argument with "arg" ``hex encoded'' (two 0-9a-f chars?).
1113 Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either
1114 is sufficient to get around the "," position separator escape issue.
1115
1116 e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is
1117
1118 6,0,676462,4,1,2d71,10,2,612e6f7574
1119
1120 Note that "argnum" and "arglen" are numbers in base 10. Again, that's
1121 not documented either way but I'm assuming it's so. */
1122
1123rnb_err_t
1124RNBRemote::HandlePacket_A (const char *p)
1125{
1126 if (p == NULL || *p == '\0')
1127 {
1128 return HandlePacket_ILLFORMED ("Null packet for 'A' pkt");
1129 }
1130 p++;
1131 if (p == '\0' || !isdigit (*p))
1132 {
1133 return HandlePacket_ILLFORMED ("arglen not specified on 'A' pkt");
1134 }
1135
1136 /* I promise I don't modify it anywhere in this function. strtoul()'s
1137 2nd arg has to be non-const which makes it problematic to step
1138 through the string easily. */
1139 char *buf = const_cast<char *>(p);
1140
1141 RNBContext& ctx = Context();
1142
1143 while (*buf != '\0')
1144 {
1145 int arglen, argnum;
1146 std::string arg;
1147 char *c;
1148
1149 errno = 0;
1150 arglen = strtoul (buf, &c, 10);
1151 if (errno != 0 && arglen == 0)
1152 {
1153 return HandlePacket_ILLFORMED ("arglen not a number on 'A' pkt");
1154 }
1155 if (*c != ',')
1156 {
1157 return HandlePacket_ILLFORMED ("arglen not followed by comma on 'A' pkt");
1158 }
1159 buf = c + 1;
1160
1161 errno = 0;
1162 argnum = strtoul (buf, &c, 10);
1163 if (errno != 0 && argnum == 0)
1164 {
1165 return HandlePacket_ILLFORMED ("argnum not a number on 'A' pkt");
1166 }
1167 if (*c != ',')
1168 {
1169 return HandlePacket_ILLFORMED ("arglen not followed by comma on 'A' pkt");
1170 }
1171 buf = c + 1;
1172
1173 c = buf;
1174 buf = buf + arglen;
1175 while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0')
1176 {
1177 char smallbuf[3];
1178 smallbuf[0] = *c;
1179 smallbuf[1] = *(c + 1);
1180 smallbuf[2] = '\0';
1181
1182 errno = 0;
1183 int ch = strtoul (smallbuf, NULL, 16);
1184 if (errno != 0 && ch == 0)
1185 {
1186 return HandlePacket_ILLFORMED ("non-hex char in arg on 'A' pkt");
1187 }
1188
1189 arg.push_back(ch);
1190 c += 2;
1191 }
1192
1193 ctx.PushArgument (arg.c_str());
1194 if (*buf == ',')
1195 buf++;
1196 }
1197 SendPacket ("OK");
1198
1199 return rnb_success;
1200}
1201
1202/* `H c t'
1203 Set the thread for subsequent actions; 'c' for step/continue ops,
1204 'g' for other ops. -1 means all threads, 0 means any thread. */
1205
1206rnb_err_t
1207RNBRemote::HandlePacket_H (const char *p)
1208{
1209 p++; // skip 'H'
1210 if (*p != 'c' && *p != 'g')
1211 {
1212 return HandlePacket_ILLFORMED ("Missing 'c' or 'g' type in H packet");
1213 }
1214
1215 if (!m_ctx.HasValidProcessID())
1216 {
1217 // We allow gdb to connect to a server that hasn't started running
1218 // the target yet. gdb still wants to ask questions about it and
1219 // freaks out if it gets an error. So just return OK here.
1220 }
1221
1222 errno = 0;
1223 nub_thread_t tid = strtoul (p + 1, NULL, 16);
1224 if (errno != 0 && tid == 0)
1225 {
1226 return HandlePacket_ILLFORMED ("Invalid thread number in H packet");
1227 }
1228 if (*p == 'c')
1229 SetContinueThread (tid);
1230 if (*p == 'g')
1231 SetCurrentThread (tid);
1232
1233 return SendPacket ("OK");
1234}
1235
1236
1237rnb_err_t
1238RNBRemote::HandlePacket_qLaunchSuccess (const char *p)
1239{
1240 if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Error() == 0)
1241 return SendPacket("OK");
1242 std::ostringstream ret_str;
1243 std::string status_str;
1244 ret_str << "E" << m_ctx.LaunchStatusAsString(status_str);
1245
1246 return SendPacket (ret_str.str());
1247}
1248
1249rnb_err_t
1250RNBRemote::HandlePacket_qShlibInfoAddr (const char *p)
1251{
1252 if (m_ctx.HasValidProcessID())
1253 {
1254 nub_addr_t shlib_info_addr = DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID());
1255 if (shlib_info_addr != INVALID_NUB_ADDRESS)
1256 {
1257 std::ostringstream ostrm;
1258 ostrm << RAW_HEXBASE << shlib_info_addr;
1259 return SendPacket (ostrm.str ());
1260 }
1261 }
1262 return SendPacket ("E44");
1263}
1264
1265rnb_err_t
1266RNBRemote::HandlePacket_qStepPacketSupported (const char *p)
1267{
1268 // Normally the "s" packet is mandatory, yet in gdb when using ARM, they
1269 // get around the need for this packet by implementing software single
1270 // stepping from gdb. Current versions of debugserver do support the "s"
1271 // packet, yet some older versions do not. We need a way to tell if this
1272 // packet is supported so we can disable software single stepping in gdb
1273 // for remote targets (so the "s" packet will get used).
1274 return SendPacket("OK");
1275}
1276
1277rnb_err_t
1278RNBRemote::HandlePacket_qThreadStopInfo (const char *p)
1279{
1280 p += strlen ("qThreadStopInfo");
1281 nub_thread_t tid = strtoul(p, 0, 16);
1282 return SendStopReplyPacketForThread (tid);
1283}
1284
1285rnb_err_t
1286RNBRemote::HandlePacket_qThreadInfo (const char *p)
1287{
1288 // We allow gdb to connect to a server that hasn't started running
1289 // the target yet. gdb still wants to ask questions about it and
1290 // freaks out if it gets an error. So just return OK here.
1291 nub_process_t pid = m_ctx.ProcessID();
1292 if (pid == INVALID_NUB_PROCESS)
1293 return SendPacket ("OK");
1294
1295 // Only "qfThreadInfo" and "qsThreadInfo" get into this function so
1296 // we only need to check the second byte to tell which is which
1297 if (p[1] == 'f')
1298 {
1299 nub_size_t numthreads = DNBProcessGetNumThreads (pid);
1300 std::ostringstream ostrm;
1301 ostrm << "m";
1302 bool first = true;
1303 for (nub_size_t i = 0; i < numthreads; ++i)
1304 {
1305 if (first)
1306 first = false;
1307 else
1308 ostrm << ",";
1309 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
1310 ostrm << std::hex << th;
1311 }
1312 return SendPacket (ostrm.str ());
1313 }
1314 else
1315 {
1316 return SendPacket ("l");
1317 }
1318}
1319
1320rnb_err_t
1321RNBRemote::HandlePacket_qThreadExtraInfo (const char *p)
1322{
1323 // We allow gdb to connect to a server that hasn't started running
1324 // the target yet. gdb still wants to ask questions about it and
1325 // freaks out if it gets an error. So just return OK here.
1326 nub_process_t pid = m_ctx.ProcessID();
1327 if (pid == INVALID_NUB_PROCESS)
1328 return SendPacket ("OK");
1329
1330 /* This is supposed to return a string like 'Runnable' or
1331 'Blocked on Mutex'.
1332 The returned string is formatted like the "A" packet - a
1333 sequence of letters encoded in as 2-hex-chars-per-letter. */
1334 p += strlen ("qThreadExtraInfo");
1335 if (*p++ != ',')
1336 return HandlePacket_ILLFORMED ("Ill formed qThreadExtraInfo packet");
1337 errno = 0;
1338 nub_thread_t tid = strtoul (p, NULL, 16);
1339 if (errno != 0 && tid == 0)
1340 {
1341 return HandlePacket_ILLFORMED ("Invalid thread number in qThreadExtraInfo packet");
1342 }
1343
1344 const char * threadInfo = DNBThreadGetInfo(pid, tid);
1345 if (threadInfo != NULL && threadInfo[0])
1346 {
1347 return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL);
1348 }
1349 else
1350 {
1351 // "OK" == 4f6b
1352 // Return "OK" as a ASCII hex byte stream if things go wrong
1353 return SendPacket ("4f6b");
1354 }
1355
1356 return SendPacket ("");
1357}
1358
1359rnb_err_t
1360RNBRemote::HandlePacket_qC (const char *p)
1361{
1362 nub_process_t pid;
1363 std::ostringstream rep;
1364 // If we haven't run the process yet, we tell the debugger the
1365 // pid is 0. That way it can know to tell use to run later on.
1366 if (m_ctx.HasValidProcessID())
1367 pid = m_ctx.ProcessID();
1368 else
1369 pid = 0;
1370 rep << "QC" << std::hex << pid;
1371 return SendPacket (rep.str());
1372}
1373
1374rnb_err_t
1375RNBRemote::HandlePacket_qRegisterInfo (const char *p)
1376{
Greg Clayton20d338f2010-11-18 05:57:03 +00001377 if (g_num_reg_entries == 0)
1378 InitializeRegisters ();
1379
Chris Lattner24943d22010-06-08 16:52:24 +00001380 p += strlen ("qRegisterInfo");
1381
1382 nub_size_t num_reg_sets = 0;
1383 const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets);
1384 uint32_t reg_num = strtoul(p, 0, 16);
1385
1386 if (reg_num < g_num_reg_entries)
1387 {
1388 const register_map_entry_t *reg_entry = &g_reg_entries[reg_num];
1389 std::ostringstream ostrm;
1390 ostrm << "name:" << reg_entry->gdb_name << ';';
1391
1392 if (reg_entry->nub_info.name && ::strcmp (reg_entry->gdb_name, reg_entry->nub_info.name))
1393 ostrm << "alt-name:" << reg_entry->nub_info.name << ';';
1394 else if (reg_entry->nub_info.alt && ::strcmp (reg_entry->gdb_name, reg_entry->nub_info.alt))
1395 ostrm << "alt-name:" << reg_entry->nub_info.alt << ';';
1396
1397 ostrm << "bitsize:" << std::dec << reg_entry->gdb_size * 8 << ';';
1398 ostrm << "offset:" << std::dec << reg_entry->nub_info.offset << ';';
1399
1400 switch (reg_entry->nub_info.type)
1401 {
1402 case Uint: ostrm << "encoding:uint;"; break;
1403 case Sint: ostrm << "encoding:sint;"; break;
1404 case IEEE754: ostrm << "encoding:ieee754;"; break;
1405 case Vector: ostrm << "encoding:vector;"; break;
1406 }
1407
1408 switch (reg_entry->nub_info.format)
1409 {
1410 case Binary: ostrm << "format:binary;"; break;
1411 case Decimal: ostrm << "format:decimal;"; break;
1412 case Hex: ostrm << "format:hex;"; break;
1413 case Float: ostrm << "format:float;"; break;
1414 case VectorOfSInt8: ostrm << "format:vector-sint8;"; break;
1415 case VectorOfUInt8: ostrm << "format:vector-uint8;"; break;
1416 case VectorOfSInt16: ostrm << "format:vector-sint16;"; break;
1417 case VectorOfUInt16: ostrm << "format:vector-uint16;"; break;
1418 case VectorOfSInt32: ostrm << "format:vector-sint32;"; break;
1419 case VectorOfUInt32: ostrm << "format:vector-uint32;"; break;
1420 case VectorOfFloat32: ostrm << "format:vector-float32;"; break;
1421 case VectorOfUInt128: ostrm << "format:vector-uint128;"; break;
1422 };
1423
1424 if (reg_set_info && reg_entry->nub_info.set < num_reg_sets)
1425 ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';';
1426
1427
1428 if (g_reg_entries != g_dynamic_register_map.data())
1429 {
1430 if (reg_entry->nub_info.reg_gdb != INVALID_NUB_REGNUM && reg_entry->nub_info.reg_gdb != reg_num)
1431 {
1432 printf("register %s is getting gdb reg_num of %u when the register info says %u\n",
1433 reg_entry->gdb_name, reg_num, reg_entry->nub_info.reg_gdb);
1434 }
1435 }
1436
1437 if (reg_entry->nub_info.reg_gcc != INVALID_NUB_REGNUM)
1438 ostrm << "gcc:" << std::dec << reg_entry->nub_info.reg_gcc << ';';
1439
1440 if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM)
1441 ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';';
1442
1443
1444 switch (reg_entry->nub_info.reg_generic)
1445 {
1446 case GENERIC_REGNUM_FP: ostrm << "generic:fp;"; break;
1447 case GENERIC_REGNUM_PC: ostrm << "generic:pc;"; break;
1448 case GENERIC_REGNUM_SP: ostrm << "generic:sp;"; break;
1449 case GENERIC_REGNUM_RA: ostrm << "generic:ra;"; break;
1450 case GENERIC_REGNUM_FLAGS: ostrm << "generic:flags;"; break;
1451 default: break;
1452 }
1453
1454 return SendPacket (ostrm.str ());
1455 }
1456 return SendPacket ("E45");
1457}
1458
1459
1460/* This expects a packet formatted like
1461
1462 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE;
1463
1464 with the "QSetLogging:" already removed from the start. Maybe in the
1465 future this packet will include other keyvalue pairs like
1466
1467 QSetLogging:bitmask=LOG_ALL;mode=asl;
1468 */
1469
1470rnb_err_t
1471set_logging (const char *p)
1472{
1473 int bitmask = 0;
1474 while (p && *p != '\0')
1475 {
1476 if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0)
1477 {
1478 p += sizeof ("bitmask=") - 1;
1479 while (p && *p != '\0' && *p != ';')
1480 {
1481 if (*p == '|')
1482 p++;
1483 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
1484 {
1485 p += sizeof ("LOG_VERBOSE") - 1;
1486 bitmask |= LOG_VERBOSE;
1487 }
1488 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0)
1489 {
1490 p += sizeof ("LOG_PROCESS") - 1;
1491 bitmask |= LOG_PROCESS;
1492 }
1493 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0)
1494 {
1495 p += sizeof ("LOG_THREAD") - 1;
1496 bitmask |= LOG_THREAD;
1497 }
1498 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0)
1499 {
1500 p += sizeof ("LOG_EXCEPTIONS") - 1;
1501 bitmask |= LOG_EXCEPTIONS;
1502 }
1503 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0)
1504 {
1505 p += sizeof ("LOG_SHLIB") - 1;
1506 bitmask |= LOG_SHLIB;
1507 }
1508 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0)
1509 {
1510 p += sizeof ("LOG_MEMORY") - 1;
1511 bitmask |= LOG_MEMORY;
1512 }
1513 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0)
1514 {
1515 p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1;
1516 bitmask |= LOG_MEMORY_DATA_SHORT;
1517 }
1518 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0)
1519 {
1520 p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
1521 bitmask |= LOG_MEMORY_DATA_LONG;
1522 }
1523 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
1524 {
1525 p += sizeof ("LOG_BREAKPOINTS") - 1;
1526 bitmask |= LOG_BREAKPOINTS;
1527 }
1528 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
1529 {
1530 p += sizeof ("LOG_ALL") - 1;
1531 bitmask |= LOG_ALL;
1532 }
1533 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
1534 {
1535 p += sizeof ("LOG_EVENTS") - 1;
1536 bitmask |= LOG_EVENTS;
1537 }
1538 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
1539 {
1540 p += sizeof ("LOG_DEFAULT") - 1;
1541 bitmask |= LOG_DEFAULT;
1542 }
1543 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
1544 {
1545 p += sizeof ("LOG_NONE") - 1;
1546 bitmask = 0;
1547 }
1548 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0)
1549 {
1550 p += sizeof ("LOG_RNB_MINIMAL") - 1;
1551 bitmask |= LOG_RNB_MINIMAL;
1552 }
1553 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0)
1554 {
1555 p += sizeof ("LOG_RNB_MEDIUM") - 1;
1556 bitmask |= LOG_RNB_MEDIUM;
1557 }
1558 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0)
1559 {
1560 p += sizeof ("LOG_RNB_MAX") - 1;
1561 bitmask |= LOG_RNB_MAX;
1562 }
1563 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0)
1564 {
1565 p += sizeof ("LOG_RNB_COMM") - 1;
1566 bitmask |= LOG_RNB_COMM;
1567 }
1568 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0)
1569 {
1570 p += sizeof ("LOG_RNB_REMOTE") - 1;
1571 bitmask |= LOG_RNB_REMOTE;
1572 }
1573 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0)
1574 {
1575 p += sizeof ("LOG_RNB_EVENTS") - 1;
1576 bitmask |= LOG_RNB_EVENTS;
1577 }
1578 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0)
1579 {
1580 p += sizeof ("LOG_RNB_PROC") - 1;
1581 bitmask |= LOG_RNB_PROC;
1582 }
1583 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0)
1584 {
1585 p += sizeof ("LOG_RNB_PACKETS") - 1;
1586 bitmask |= LOG_RNB_PACKETS;
1587 }
1588 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0)
1589 {
1590 p += sizeof ("LOG_RNB_ALL") - 1;
1591 bitmask |= LOG_RNB_ALL;
1592 }
1593 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0)
1594 {
1595 p += sizeof ("LOG_RNB_DEFAULT") - 1;
1596 bitmask |= LOG_RNB_DEFAULT;
1597 }
1598 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0)
1599 {
1600 p += sizeof ("LOG_RNB_NONE") - 1;
1601 bitmask = 0;
1602 }
1603 else
1604 {
1605 /* Unrecognized logging bit; ignore it. */
1606 const char *c = strchr (p, '|');
1607 if (c)
1608 {
1609 p = c;
1610 }
1611 else
1612 {
1613 c = strchr (p, ';');
1614 if (c)
1615 {
1616 p = c;
1617 }
1618 else
1619 {
1620 // Improperly terminated word; just go to end of str
1621 p = strchr (p, '\0');
1622 }
1623 }
1624 }
1625 }
1626 // Did we get a properly formatted logging bitmask?
1627 if (*p == ';')
1628 {
1629 // Enable DNB logging
1630 DNBLogSetLogCallback(ASLLogCallback, NULL);
1631 DNBLogSetLogMask (bitmask);
1632 p++;
1633 }
1634 }
1635 // We're not going to support logging to a file for now. All logging
1636 // goes through ASL.
1637#if 0
1638 else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0)
1639 {
1640 p += sizeof ("mode=") - 1;
1641 if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0)
1642 {
1643 DNBLogToASL ();
1644 p += sizeof ("asl;") - 1;
1645 }
1646 else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0)
1647 {
1648 DNBLogToFile ();
1649 p += sizeof ("file;") - 1;
1650 }
1651 else
1652 {
1653 // Ignore unknown argument
1654 const char *c = strchr (p, ';');
1655 if (c)
1656 p = c + 1;
1657 else
1658 p = strchr (p, '\0');
1659 }
1660 }
1661 else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0)
1662 {
1663 p += sizeof ("filename=") - 1;
1664 const char *c = strchr (p, ';');
1665 if (c == NULL)
1666 {
1667 c = strchr (p, '\0');
1668 continue;
1669 }
1670 char *fn = (char *) alloca (c - p + 1);
1671 strncpy (fn, p, c - p);
1672 fn[c - p] = '\0';
1673
1674 // A file name of "asl" is special and is another way to indicate
1675 // that logging should be done via ASL, not by file.
1676 if (strcmp (fn, "asl") == 0)
1677 {
1678 DNBLogToASL ();
1679 }
1680 else
1681 {
1682 FILE *f = fopen (fn, "w");
1683 if (f)
1684 {
1685 DNBLogSetLogFile (f);
1686 DNBEnableLogging (f, DNBLogGetLogMask ());
1687 DNBLogToFile ();
1688 }
1689 }
1690 p = c + 1;
1691 }
1692#endif /* #if 0 to enforce ASL logging only. */
1693 else
1694 {
1695 // Ignore unknown argument
1696 const char *c = strchr (p, ';');
1697 if (c)
1698 p = c + 1;
1699 else
1700 p = strchr (p, '\0');
1701 }
1702 }
1703
1704 return rnb_success;
1705}
1706
Greg Claytonc71899e2011-01-18 19:36:39 +00001707rnb_err_t
1708RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
1709{
1710 m_thread_suffix_supported = true;
1711 return SendPacket ("OK");
1712}
1713
1714rnb_err_t
1715RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
1716{
1717 // Send the OK packet first so the correct checksum is appended...
1718 rnb_err_t result = SendPacket ("OK");
1719 m_noack_mode = true;
1720 return result;
1721}
Chris Lattner24943d22010-06-08 16:52:24 +00001722
1723
1724rnb_err_t
Greg Claytonc71899e2011-01-18 19:36:39 +00001725RNBRemote::HandlePacket_QSetLogging (const char *p)
Chris Lattner24943d22010-06-08 16:52:24 +00001726{
Greg Claytonc71899e2011-01-18 19:36:39 +00001727 p += sizeof ("QSetLogging:") - 1;
1728 rnb_err_t result = set_logging (p);
1729 if (result == rnb_success)
Greg Clayton0a7f75f2010-09-09 06:32:46 +00001730 return SendPacket ("OK");
Greg Claytonc71899e2011-01-18 19:36:39 +00001731 else
1732 return SendPacket ("E35");
1733}
Greg Clayton0a7f75f2010-09-09 06:32:46 +00001734
Greg Claytonc71899e2011-01-18 19:36:39 +00001735rnb_err_t
1736RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
1737{
1738 extern int g_disable_aslr;
1739 p += sizeof ("QSetDisableASLR:") - 1;
1740 switch (*p)
1741 {
1742 case '0': g_disable_aslr = 0; break;
1743 case '1': g_disable_aslr = 1; break;
1744 default:
1745 return SendPacket ("E56");
1746 }
1747 return SendPacket ("OK");
1748}
1749
1750
1751rnb_err_t
1752RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
1753{
Chris Lattner24943d22010-06-08 16:52:24 +00001754 /* The number of characters in a packet payload that gdb is
1755 prepared to accept. The packet-start char, packet-end char,
1756 2 checksum chars and terminating null character are not included
1757 in this size. */
Greg Claytonc71899e2011-01-18 19:36:39 +00001758 p += sizeof ("QSetMaxPayloadSize:") - 1;
1759 errno = 0;
1760 uint32_t size = strtoul (p, NULL, 16);
1761 if (errno != 0 && size == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001762 {
Greg Claytonc71899e2011-01-18 19:36:39 +00001763 return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPayloadSize packet");
Chris Lattner24943d22010-06-08 16:52:24 +00001764 }
Greg Claytonc71899e2011-01-18 19:36:39 +00001765 m_max_payload_size = size;
1766 return SendPacket ("OK");
1767}
Chris Lattner24943d22010-06-08 16:52:24 +00001768
Greg Claytonc71899e2011-01-18 19:36:39 +00001769rnb_err_t
1770RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
1771{
Chris Lattner24943d22010-06-08 16:52:24 +00001772 /* This tells us the largest packet that gdb can handle.
1773 i.e. the size of gdb's packet-reading buffer.
1774 QSetMaxPayloadSize is preferred because it is less ambiguous. */
Greg Claytonc71899e2011-01-18 19:36:39 +00001775 p += sizeof ("QSetMaxPacketSize:") - 1;
1776 errno = 0;
1777 uint32_t size = strtoul (p, NULL, 16);
1778 if (errno != 0 && size == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001779 {
Greg Claytonc71899e2011-01-18 19:36:39 +00001780 return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPacketSize packet");
Chris Lattner24943d22010-06-08 16:52:24 +00001781 }
Greg Claytonc71899e2011-01-18 19:36:39 +00001782 m_max_payload_size = size - 5;
1783 return SendPacket ("OK");
1784}
Chris Lattner24943d22010-06-08 16:52:24 +00001785
Greg Claytonc71899e2011-01-18 19:36:39 +00001786
1787
1788
1789rnb_err_t
1790RNBRemote::HandlePacket_QEnvironment (const char *p)
1791{
Chris Lattner24943d22010-06-08 16:52:24 +00001792 /* This sets the environment for the target program. The packet is of the form:
1793
1794 QEnvironment:VARIABLE=VALUE
1795
1796 */
1797
Greg Claytonc71899e2011-01-18 19:36:39 +00001798 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
1799 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
Chris Lattner24943d22010-06-08 16:52:24 +00001800
Greg Claytonc71899e2011-01-18 19:36:39 +00001801 p += sizeof ("QEnvironment:") - 1;
1802 RNBContext& ctx = Context();
Chris Lattner24943d22010-06-08 16:52:24 +00001803
Greg Claytonc71899e2011-01-18 19:36:39 +00001804 ctx.PushEnvironment (p);
1805 return SendPacket ("OK");
Chris Lattner24943d22010-06-08 16:52:24 +00001806}
1807
1808void
1809append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap)
1810{
1811 int i;
1812 if (swap)
1813 {
1814 for (i = buf_size-1; i >= 0; i--)
1815 ostrm << RAWHEX8(buf[i]);
1816 }
1817 else
1818 {
1819 for (i = 0; i < buf_size; i++)
1820 ostrm << RAWHEX8(buf[i]);
1821 }
1822}
1823
1824
1825void
1826register_value_in_hex_fixed_width
1827(
1828 std::ostream& ostrm,
1829 nub_process_t pid,
1830 nub_thread_t tid,
1831 const register_map_entry_t* reg
1832 )
1833{
1834 if (reg != NULL)
1835 {
1836 DNBRegisterValue val;
1837 if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &val))
1838 {
1839 append_hex_value (ostrm, val.value.v_uint8, reg->gdb_size, false);
1840 }
1841 else
1842 {
1843 // If we fail to read a regiser value, check if it has a default
1844 // fail value. If it does, return this instead in case some of
1845 // the registers are not available on the current system.
1846 if (reg->gdb_size > 0)
1847 {
1848 if (reg->fail_value != NULL)
1849 {
1850 append_hex_value (ostrm, reg->fail_value, reg->gdb_size, false);
1851 }
1852 else
1853 {
1854 std::basic_string<uint8_t> zeros(reg->gdb_size, '\0');
1855 append_hex_value (ostrm, zeros.data(), zeros.size(), false);
1856 }
1857 }
1858 }
1859 }
1860}
1861
1862
1863void
1864gdb_regnum_with_fixed_width_hex_register_value
1865(
1866 std::ostream& ostrm,
1867 nub_process_t pid,
1868 nub_thread_t tid,
1869 const register_map_entry_t* reg
1870 )
1871{
1872 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
1873 // gdb register number, and VVVVVVVV is the correct number of hex bytes
1874 // as ASCII for the register value.
1875 if (reg != NULL)
1876 {
1877 ostrm << RAWHEX8(reg->gdb_regnum) << ':';
1878 register_value_in_hex_fixed_width (ostrm, pid, tid, reg);
1879 ostrm << ';';
1880 }
1881}
1882
1883rnb_err_t
1884RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
1885{
1886 const nub_process_t pid = m_ctx.ProcessID();
1887 if (pid == INVALID_NUB_PROCESS)
1888 return SendPacket("E50");
1889
1890 struct DNBThreadStopInfo tid_stop_info;
1891
1892 /* Fill the remaining space in this packet with as many registers
1893 as we can stuff in there. */
1894
1895 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
1896 {
1897 std::ostringstream ostrm;
1898 // Output the T packet with the thread
1899 ostrm << 'T';
1900 int signum = tid_stop_info.details.signal.signo;
1901 DNBLogThreadedIf (LOG_RNB_PROC, "%8d %s got signal signo = %u, exc_type = %u", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, tid_stop_info.details.signal.signo, tid_stop_info.details.exception.type);
1902
1903 // Translate any mach exceptions to gdb versions, unless they are
1904 // common exceptions like a breakpoint or a soft signal.
1905 switch (tid_stop_info.details.exception.type)
1906 {
1907 default: signum = 0; break;
1908 case EXC_BREAKPOINT: signum = SIGTRAP; break;
1909 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break;
1910 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break;
1911 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break;
1912 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break;
1913 case EXC_SOFTWARE:
1914 if (tid_stop_info.details.exception.data_count == 2 &&
1915 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
1916 signum = tid_stop_info.details.exception.data[1];
1917 else
1918 signum = TARGET_EXC_SOFTWARE;
1919 break;
1920 }
1921
1922 ostrm << RAWHEX8(signum & 0xff);
1923
1924 ostrm << std::hex << "thread:" << tid << ';';
1925
1926 const char *thread_name = DNBThreadGetName (pid, tid);
1927 if (thread_name && thread_name[0])
Greg Clayton4862fa22011-01-08 03:17:57 +00001928 {
1929 size_t thread_name_len = strlen(thread_name);
1930
1931 if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
1932 ostrm << std::hex << "name:" << thread_name << ';';
1933 else
1934 {
1935 // the thread name contains special chars, send as hex bytes
1936 ostrm << std::hex << "hexname:";
1937 uint8_t *u_thread_name = (uint8_t *)thread_name;
1938 for (int i = 0; i < thread_name_len; i++)
1939 ostrm << RAWHEX8(u_thread_name[i]);
1940 ostrm << ';';
1941 }
1942 }
Chris Lattner24943d22010-06-08 16:52:24 +00001943
1944 thread_identifier_info_data_t thread_ident_info;
1945 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
1946 {
1947 if (thread_ident_info.dispatch_qaddr != 0)
Greg Clayton0a7f75f2010-09-09 06:32:46 +00001948 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
Chris Lattner24943d22010-06-08 16:52:24 +00001949 }
Greg Clayton20d338f2010-11-18 05:57:03 +00001950 if (g_num_reg_entries == 0)
1951 InitializeRegisters ();
1952
Chris Lattner24943d22010-06-08 16:52:24 +00001953 DNBRegisterValue reg_value;
1954 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
1955 {
1956 if (g_reg_entries[reg].expedite)
1957 {
1958 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
1959 continue;
1960
1961 gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg]);
1962 }
1963 }
1964
1965 if (tid_stop_info.details.exception.type)
1966 {
1967 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";";
1968 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";";
1969 for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i)
1970 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";";
1971 }
1972 return SendPacket (ostrm.str ());
1973 }
1974 return SendPacket("E51");
1975}
1976
1977/* `?'
1978 The stop reply packet - tell gdb what the status of the inferior is.
1979 Often called the questionmark_packet. */
1980
1981rnb_err_t
1982RNBRemote::HandlePacket_last_signal (const char *unused)
1983{
1984 if (!m_ctx.HasValidProcessID())
1985 {
1986 // Inferior is not yet specified/running
1987 return SendPacket ("E02");
1988 }
1989
1990 nub_process_t pid = m_ctx.ProcessID();
1991 nub_state_t pid_state = DNBProcessGetState (pid);
1992
1993 switch (pid_state)
1994 {
1995 case eStateAttaching:
1996 case eStateLaunching:
1997 case eStateRunning:
1998 case eStateStepping:
1999 return rnb_success; // Ignore
2000
2001 case eStateSuspended:
2002 case eStateStopped:
2003 case eStateCrashed:
Greg Clayton20d338f2010-11-18 05:57:03 +00002004 {
2005 nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2006 // Make sure we set the current thread so g and p packets return
2007 // the data the gdb will expect.
2008 SetCurrentThread (tid);
Chris Lattner24943d22010-06-08 16:52:24 +00002009
Greg Clayton20d338f2010-11-18 05:57:03 +00002010 SendStopReplyPacketForThread (tid);
2011 }
Chris Lattner24943d22010-06-08 16:52:24 +00002012 break;
2013
2014 case eStateInvalid:
2015 case eStateUnloaded:
2016 case eStateExited:
Chris Lattner24943d22010-06-08 16:52:24 +00002017 {
Greg Clayton20d338f2010-11-18 05:57:03 +00002018 char pid_exited_packet[16] = "";
2019 int pid_status = 0;
2020 // Process exited with exit status
2021 if (!DNBProcessGetExitStatus(pid, &pid_status))
2022 pid_status = 0;
Chris Lattner24943d22010-06-08 16:52:24 +00002023
Greg Clayton20d338f2010-11-18 05:57:03 +00002024 if (pid_status)
2025 {
2026 if (WIFEXITED (pid_status))
2027 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2028 else if (WIFSIGNALED (pid_status))
2029 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2030 else if (WIFSTOPPED (pid_status))
2031 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2032 }
Chris Lattner24943d22010-06-08 16:52:24 +00002033
Greg Clayton20d338f2010-11-18 05:57:03 +00002034 // If we have an empty exit packet, lets fill one in to be safe.
2035 if (!pid_exited_packet[0])
2036 {
2037 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2038 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2039 }
2040
2041 return SendPacket (pid_exited_packet);
2042 }
Chris Lattner24943d22010-06-08 16:52:24 +00002043 break;
2044 }
2045 return rnb_success;
2046}
2047
2048rnb_err_t
2049RNBRemote::HandlePacket_M (const char *p)
2050{
2051 if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2052 {
2053 return HandlePacket_ILLFORMED ("Too short M packet");
2054 }
2055
2056 char *c;
2057 p++;
2058 errno = 0;
2059 nub_addr_t addr = strtoull (p, &c, 16);
2060 if (errno != 0 && addr == 0)
2061 {
2062 return HandlePacket_ILLFORMED ("Invalid address in M packet");
2063 }
2064 if (*c != ',')
2065 {
2066 return HandlePacket_ILLFORMED ("Comma sep missing in M packet");
2067 }
2068
2069 /* Advance 'p' to the length part of the packet. */
2070 p += (c - p) + 1;
2071
2072 errno = 0;
2073 uint32_t length = strtoul (p, &c, 16);
2074 if (errno != 0 && length == 0)
2075 {
2076 return HandlePacket_ILLFORMED ("Invalid length in M packet");
2077 }
2078 if (length == 0)
2079 {
2080 return SendPacket ("OK");
2081 }
2082
2083 if (*c != ':')
2084 {
2085 return HandlePacket_ILLFORMED ("Missing colon in M packet");
2086 }
2087 /* Advance 'p' to the data part of the packet. */
2088 p += (c - p) + 1;
2089
2090 int datalen = strlen (p);
2091 if (datalen & 0x1)
2092 {
2093 return HandlePacket_ILLFORMED ("Uneven # of hex chars for data in M packet");
2094 }
2095 if (datalen == 0)
2096 {
2097 return SendPacket ("OK");
2098 }
2099
2100 uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2101 uint8_t *i = buf;
2102
2103 while (*p != '\0' && *(p + 1) != '\0')
2104 {
2105 char hexbuf[3];
2106 hexbuf[0] = *p;
2107 hexbuf[1] = *(p + 1);
2108 hexbuf[2] = '\0';
2109 errno = 0;
2110 uint8_t byte = strtoul (hexbuf, NULL, 16);
2111 if (errno != 0 && byte == 0)
2112 {
2113 return HandlePacket_ILLFORMED ("Invalid hex byte in M packet");
2114 }
2115 *i++ = byte;
2116 p += 2;
2117 }
2118
2119 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2120 if (wrote != length)
2121 return SendPacket ("E09");
2122 else
2123 return SendPacket ("OK");
2124}
2125
2126
2127rnb_err_t
2128RNBRemote::HandlePacket_m (const char *p)
2129{
2130 if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2131 {
2132 return HandlePacket_ILLFORMED ("Too short m packet");
2133 }
2134
2135 char *c;
2136 p++;
2137 errno = 0;
2138 nub_addr_t addr = strtoull (p, &c, 16);
2139 if (errno != 0 && addr == 0)
2140 {
2141 return HandlePacket_ILLFORMED ("Invalid address in m packet");
2142 }
2143 if (*c != ',')
2144 {
2145 return HandlePacket_ILLFORMED ("Comma sep missing in m packet");
2146 }
2147
2148 /* Advance 'p' to the length part of the packet. */
2149 p += (c - p) + 1;
2150
2151 errno = 0;
2152 uint32_t length = strtoul (p, NULL, 16);
2153 if (errno != 0 && length == 0)
2154 {
2155 return HandlePacket_ILLFORMED ("Invalid length in m packet");
2156 }
2157 if (length == 0)
2158 {
2159 return SendPacket ("");
2160 }
2161
2162 uint8_t buf[length];
2163 int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf);
2164 if (bytes_read == 0)
2165 {
2166 return SendPacket ("E08");
2167 }
2168
2169 // "The reply may contain fewer bytes than requested if the server was able
2170 // to read only part of the region of memory."
2171 length = bytes_read;
2172
2173 std::ostringstream ostrm;
2174 for (int i = 0; i < length; i++)
2175 ostrm << RAWHEX8(buf[i]);
2176 return SendPacket (ostrm.str ());
2177}
2178
2179rnb_err_t
2180RNBRemote::HandlePacket_X (const char *p)
2181{
2182 if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2183 {
2184 return HandlePacket_ILLFORMED ("Too short X packet");
2185 }
2186
2187 char *c;
2188 p++;
2189 errno = 0;
2190 nub_addr_t addr = strtoull (p, &c, 16);
2191 if (errno != 0 && addr == 0)
2192 {
2193 return HandlePacket_ILLFORMED ("Invalid address in X packet");
2194 }
2195 if (*c != ',')
2196 {
2197 return HandlePacket_ILLFORMED ("Comma sep missing in X packet");
2198 }
2199
2200 /* Advance 'p' to the length part of the packet. */
2201 p += (c - p) + 1;
2202
2203 errno = 0;
2204 int length = strtoul (p, NULL, 16);
2205 if (errno != 0 && length == 0)
2206 {
2207 return HandlePacket_ILLFORMED ("Invalid length in m packet");
2208 }
2209
2210 // I think gdb sends a zero length write request to test whether this
2211 // packet is accepted.
2212 if (length == 0)
2213 {
2214 return SendPacket ("OK");
2215 }
2216
2217 std::vector<uint8_t> data = decode_binary_data (c, -1);
2218 std::vector<uint8_t>::const_iterator it;
2219 uint8_t *buf = (uint8_t *) alloca (data.size ());
2220 uint8_t *i = buf;
2221 for (it = data.begin (); it != data.end (); ++it)
2222 {
2223 *i++ = *it;
2224 }
2225
2226 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
2227 if (wrote != data.size ())
2228 return SendPacket ("E08");
2229 return SendPacket ("OK");
2230}
2231
2232/* `g' -- read registers
2233 Get the contents of the registers for the current thread,
2234 send them to gdb.
2235 Should the setting of the Hg packet determine which thread's registers
2236 are returned? */
2237
2238rnb_err_t
2239RNBRemote::HandlePacket_g (const char *p)
2240{
2241 std::ostringstream ostrm;
2242 if (!m_ctx.HasValidProcessID())
2243 {
2244 return SendPacket ("E11");
2245 }
Greg Clayton20d338f2010-11-18 05:57:03 +00002246
2247 if (g_num_reg_entries == 0)
2248 InitializeRegisters ();
2249
Chris Lattner24943d22010-06-08 16:52:24 +00002250 nub_process_t pid = m_ctx.ProcessID ();
Greg Claytonc71899e2011-01-18 19:36:39 +00002251 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
2252 if (tid == INVALID_NUB_THREAD)
2253 return HandlePacket_ILLFORMED ("No thread specified in p packet");
Chris Lattner24943d22010-06-08 16:52:24 +00002254
2255 if (m_use_native_regs)
2256 {
2257 // Get the register context size first by calling with NULL buffer
2258 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2259 if (reg_ctx_size)
2260 {
2261 // Now allocate enough space for the entire register context
2262 std::vector<uint8_t> reg_ctx;
2263 reg_ctx.resize(reg_ctx_size);
2264 // Now read the register context
2265 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
2266 if (reg_ctx_size)
2267 {
2268 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
2269 return SendPacket (ostrm.str ());
2270 }
2271 }
2272 }
2273
2274 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2275 register_value_in_hex_fixed_width (ostrm, pid, tid, &g_reg_entries[reg]);
2276
2277 return SendPacket (ostrm.str ());
2278}
2279
2280/* `G XXX...' -- write registers
2281 How is the thread for these specified, beyond "the current thread"?
2282 Does gdb actually use the Hg packet to set this? */
2283
2284rnb_err_t
2285RNBRemote::HandlePacket_G (const char *p)
2286{
2287 if (!m_ctx.HasValidProcessID())
2288 {
2289 return SendPacket ("E11");
2290 }
Greg Clayton20d338f2010-11-18 05:57:03 +00002291
2292 if (g_num_reg_entries == 0)
2293 InitializeRegisters ();
2294
Chris Lattner24943d22010-06-08 16:52:24 +00002295 StringExtractor packet(p);
2296 packet.SetFilePos(1); // Skip the 'G'
2297
2298 nub_process_t pid = m_ctx.ProcessID();
Greg Claytonc71899e2011-01-18 19:36:39 +00002299 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2300 if (tid == INVALID_NUB_THREAD)
2301 return HandlePacket_ILLFORMED ("No thread specified in p packet");
Chris Lattner24943d22010-06-08 16:52:24 +00002302
2303 if (m_use_native_regs)
2304 {
2305 // Get the register context size first by calling with NULL buffer
2306 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2307 if (reg_ctx_size)
2308 {
2309 // Now allocate enough space for the entire register context
2310 std::vector<uint8_t> reg_ctx;
2311 reg_ctx.resize(reg_ctx_size);
2312
2313 if (packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc) == reg_ctx.size())
2314 {
2315 // Now write the register context
2316 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
2317 if (reg_ctx_size == reg_ctx.size())
2318 return SendPacket ("OK");
2319 else
2320 return SendPacket ("E55");
2321 }
2322 }
2323 }
2324
2325
2326 DNBRegisterValue reg_value;
2327 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2328 {
2329 const register_map_entry_t *reg_entry = &g_reg_entries[reg];
2330
2331 reg_value.info = reg_entry->nub_info;
2332 if (packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc) != reg_entry->gdb_size)
2333 break;
2334
2335 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
2336 return SendPacket ("E15");
2337 }
2338 return SendPacket ("OK");
2339}
2340
2341static bool
2342RNBRemoteShouldCancelCallback (void *not_used)
2343{
2344 RNBRemoteSP remoteSP(g_remoteSP);
2345 if (remoteSP.get() != NULL)
2346 {
2347 RNBRemote* remote = remoteSP.get();
2348 if (remote->Comm().IsConnected())
2349 return false;
2350 else
2351 return true;
2352 }
2353 return true;
2354}
2355
2356
2357// FORMAT: _MXXXXXX,PPP
2358// XXXXXX: big endian hex chars
2359// PPP: permissions can be any combo of r w x chars
2360//
2361// RESPONSE: XXXXXX
2362// XXXXXX: hex address of the newly allocated memory
2363// EXX: error code
2364//
2365// EXAMPLES:
2366// _M123000,rw
2367// _M123000,rwx
2368// _M123000,xw
2369
2370rnb_err_t
2371RNBRemote::HandlePacket_AllocateMemory (const char *p)
2372{
2373 StringExtractor packet (p);
2374 packet.SetFilePos(2); // Skip the "_M"
2375
2376 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
2377 if (size != 0)
2378 {
2379 if (packet.GetChar() == ',')
2380 {
2381 uint32_t permissions = 0;
2382 char ch;
2383 bool success = true;
2384 while (success && (ch = packet.GetChar()) != '\0')
2385 {
2386 switch (ch)
2387 {
2388 case 'r': permissions |= eMemoryPermissionsReadable; break;
2389 case 'w': permissions |= eMemoryPermissionsWritable; break;
2390 case 'x': permissions |= eMemoryPermissionsExecutable; break;
2391 default: success = false; break;
2392 }
2393 }
2394
2395 if (success)
2396 {
2397 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
2398 if (addr != INVALID_NUB_ADDRESS)
2399 {
2400 std::ostringstream ostrm;
2401 ostrm << RAW_HEXBASE << addr;
2402 return SendPacket (ostrm.str ());
2403 }
2404 }
2405 }
2406 }
2407 return SendPacket ("E53");
2408}
2409
2410// FORMAT: _mXXXXXX
2411// XXXXXX: address that was previosly allocated
2412//
2413// RESPONSE: XXXXXX
2414// OK: address was deallocated
2415// EXX: error code
2416//
2417// EXAMPLES:
2418// _m123000
2419
2420rnb_err_t
2421RNBRemote::HandlePacket_DeallocateMemory (const char *p)
2422{
2423 StringExtractor packet (p);
2424 packet.SetFilePos(2); // Skip the "_m"
2425 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
2426
2427 if (addr != INVALID_NUB_ADDRESS)
2428 {
2429 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
2430 return SendPacket ("OK");
2431 }
2432 return SendPacket ("E54");
2433}
2434
2435/*
2436 vAttach;pid
2437
2438 Attach to a new process with the specified process ID. pid is a hexadecimal integer
2439 identifying the process. If the stub is currently controlling a process, it is
2440 killed. The attached process is stopped.This packet is only available in extended
2441 mode (see extended mode).
2442
2443 Reply:
2444 "ENN" for an error
2445 "Any Stop Reply Packet" for success
2446 */
2447
2448rnb_err_t
2449RNBRemote::HandlePacket_v (const char *p)
2450{
2451 if (strcmp (p, "vCont;c") == 0)
2452 {
2453 // Simple continue
2454 return RNBRemote::HandlePacket_c("c");
2455 }
2456 else if (strcmp (p, "vCont;s") == 0)
2457 {
2458 // Simple step
2459 return RNBRemote::HandlePacket_s("s");
2460 }
2461 else if (strstr (p, "vCont") == p)
2462 {
2463 rnb_err_t rnb_err = rnb_success;
2464 typedef struct
2465 {
2466 nub_thread_t tid;
2467 char action;
2468 int signal;
2469 } vcont_action_t;
2470
2471 DNBThreadResumeActions thread_actions;
2472 char *c = (char *)(p += strlen("vCont"));
2473 char *c_end = c + strlen(c);
2474 if (*c == '?')
2475 return SendPacket ("vCont;c;C;s;S");
2476
2477 while (c < c_end && *c == ';')
2478 {
2479 ++c; // Skip the semi-colon
2480 DNBThreadResumeAction thread_action;
2481 thread_action.tid = INVALID_NUB_THREAD;
2482 thread_action.state = eStateInvalid;
2483 thread_action.signal = 0;
2484 thread_action.addr = INVALID_NUB_ADDRESS;
2485
2486 char action = *c++;
2487
2488 switch (action)
2489 {
2490 case 'C':
2491 errno = 0;
2492 thread_action.signal = strtoul (c, &c, 16);
2493 if (errno != 0)
2494 return HandlePacket_ILLFORMED ("Could not parse signal in vCont packet");
2495 // Fall through to next case...
2496
2497 case 'c':
2498 // Continue
2499 thread_action.state = eStateRunning;
2500 break;
2501
2502 case 'S':
2503 errno = 0;
2504 thread_action.signal = strtoul (c, &c, 16);
2505 if (errno != 0)
2506 return HandlePacket_ILLFORMED ("Could not parse signal in vCont packet");
2507 // Fall through to next case...
2508
2509 case 's':
2510 // Step
2511 thread_action.state = eStateStepping;
2512 break;
2513
2514 break;
2515
2516 default:
2517 rnb_err = HandlePacket_ILLFORMED ("Unsupported action in vCont packet");
2518 break;
2519 }
2520 if (*c == ':')
2521 {
2522 errno = 0;
2523 thread_action.tid = strtoul (++c, &c, 16);
2524 if (errno != 0)
2525 return HandlePacket_ILLFORMED ("Could not parse thread number in vCont packet");
2526 }
2527
2528 thread_actions.Append (thread_action);
2529 }
2530
2531 // If a default action for all other threads wasn't mentioned
2532 // then we should stop the threads
2533 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
2534 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
2535 return rnb_success;
2536 }
2537 else if (strstr (p, "vAttach") == p)
2538 {
2539 nub_process_t attach_pid = INVALID_NUB_PROCESS;
2540 char err_str[1024]={'\0'};
2541 if (strstr (p, "vAttachWait;") == p)
2542 {
2543 p += strlen("vAttachWait;");
2544 std::string attach_name;
2545 while (*p != '\0')
2546 {
2547 char smallbuf[3];
2548 smallbuf[0] = *p;
2549 smallbuf[1] = *(p + 1);
2550 smallbuf[2] = '\0';
2551
2552 errno = 0;
2553 int ch = strtoul (smallbuf, NULL, 16);
2554 if (errno != 0 && ch == 0)
2555 {
2556 return HandlePacket_ILLFORMED ("non-hex char in arg on 'vAttachWait' pkt");
2557 }
2558
2559 attach_name.push_back(ch);
2560 p += 2;
2561 }
2562
2563 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2564
2565 }
Greg Clayton0561f3d2010-10-26 21:04:55 +00002566 else if (strstr (p, "vAttachName;") == p)
Greg Claytonc1d37752010-10-18 01:45:30 +00002567 {
2568 p += strlen("vAttachName;");
2569 std::string attach_name;
2570 while (*p != '\0')
2571 {
2572 char smallbuf[3];
2573 smallbuf[0] = *p;
2574 smallbuf[1] = *(p + 1);
2575 smallbuf[2] = '\0';
2576
2577 errno = 0;
2578 int ch = strtoul (smallbuf, NULL, 16);
2579 if (errno != 0 && ch == 0)
2580 {
2581 return HandlePacket_ILLFORMED ("non-hex char in arg on 'vAttachWait' pkt");
2582 }
2583
2584 attach_name.push_back(ch);
2585 p += 2;
2586 }
2587
2588 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
2589
2590 }
Chris Lattner24943d22010-06-08 16:52:24 +00002591 else if (strstr (p, "vAttach;") == p)
2592 {
2593 p += strlen("vAttach;");
2594 char *end = NULL;
2595 attach_pid = strtoul (p, &end, 16); // PID will be in hex, so use base 16 to decode
2596 if (p != end && *end == '\0')
2597 {
2598 // Wait at most 30 second for attach
2599 struct timespec attach_timeout_abstime;
2600 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
2601 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str));
2602 }
2603 }
2604 else
2605 return HandlePacket_UNIMPLEMENTED(p);
2606
2607
2608 if (attach_pid != INVALID_NUB_PROCESS)
2609 {
2610 if (m_ctx.ProcessID() != attach_pid)
2611 m_ctx.SetProcessID(attach_pid);
2612 // Send a stop reply packet to indicate we successfully attached!
2613 NotifyThatProcessStopped ();
2614 return rnb_success;
2615 }
2616 else
2617 {
2618 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
2619 if (err_str[0])
2620 m_ctx.LaunchStatus().SetErrorString(err_str);
2621 else
2622 m_ctx.LaunchStatus().SetErrorString("attach failed");
2623 return SendPacket ("E01"); // E01 is our magic error value for attach failed.
2624 }
2625 }
2626
2627 // All other failures come through here
2628 return HandlePacket_UNIMPLEMENTED(p);
2629}
2630
2631/* `T XX' -- status of thread
2632 Check if the specified thread is alive.
2633 The thread number is in hex? */
2634
2635rnb_err_t
2636RNBRemote::HandlePacket_T (const char *p)
2637{
2638 p++;
2639 if (p == NULL || *p == '\0')
2640 {
2641 return HandlePacket_ILLFORMED ("No thread specified in T packet");
2642 }
2643 if (!m_ctx.HasValidProcessID())
2644 {
2645 return SendPacket ("E15");
2646 }
2647 errno = 0;
2648 nub_thread_t tid = strtoul (p, NULL, 16);
2649 if (errno != 0 && tid == 0)
2650 {
2651 return HandlePacket_ILLFORMED ("Could not parse thread number in T packet");
2652 }
2653
2654 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
2655 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
2656 {
2657 return SendPacket ("E16");
2658 }
2659
2660 return SendPacket ("OK");
2661}
2662
2663
2664rnb_err_t
2665RNBRemote::HandlePacket_z (const char *p)
2666{
2667 if (p == NULL || *p == '\0')
2668 return HandlePacket_ILLFORMED ("No thread specified in z packet");
2669
2670 if (!m_ctx.HasValidProcessID())
2671 return SendPacket ("E15");
2672
2673 char packet_cmd = *p++;
2674 char break_type = *p++;
2675
2676 if (*p++ != ',')
2677 return HandlePacket_ILLFORMED ("Comma separator missing in z packet");
2678
2679 char *c = NULL;
2680 nub_process_t pid = m_ctx.ProcessID();
2681 errno = 0;
2682 nub_addr_t addr = strtoull (p, &c, 16);
2683 if (errno != 0 && addr == 0)
2684 return HandlePacket_ILLFORMED ("Invalid address in z packet");
2685 p = c;
2686 if (*p++ != ',')
2687 return HandlePacket_ILLFORMED ("Comma separator missing in z packet");
2688
2689 errno = 0;
2690 uint32_t byte_size = strtoul (p, &c, 16);
2691 if (errno != 0 && byte_size == 0)
2692 return HandlePacket_ILLFORMED ("Invalid length in z packet");
2693
2694 if (packet_cmd == 'Z')
2695 {
2696 // set
2697 switch (break_type)
2698 {
2699 case '0': // set software breakpoint
2700 case '1': // set hardware breakpoint
2701 {
2702 // gdb can send multiple Z packets for the same address and
2703 // these calls must be ref counted.
2704 bool hardware = (break_type == '1');
2705
2706 // Check if we currently have a breakpoint already set at this address
2707 BreakpointMapIter pos = m_breakpoints.find(addr);
2708 if (pos != m_breakpoints.end())
2709 {
2710 // We do already have a breakpoint at this address, increment
2711 // its reference count and return OK
2712 pos->second.Retain();
2713 return SendPacket ("OK");
2714 }
2715 else
2716 {
2717 // We do NOT already have a breakpoint at this address, So lets
2718 // create one.
2719 nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware);
2720 if (break_id != INVALID_NUB_BREAK_ID)
2721 {
2722 // We successfully created a breakpoint, now lets full out
2723 // a ref count structure with the breakID and add it to our
2724 // map.
2725 Breakpoint rnbBreakpoint(break_id);
2726 m_breakpoints[addr] = rnbBreakpoint;
2727 return SendPacket ("OK");
2728 }
2729 else
2730 {
2731 // We failed to set the software breakpoint
2732 return SendPacket ("E09");
2733 }
2734 }
2735 }
2736 break;
2737
2738 case '2': // set write watchpoint
2739 case '3': // set read watchpoint
2740 case '4': // set access watchpoint
2741 {
2742 bool hardware = true;
2743 uint32_t watch_flags = 0;
2744 if (break_type == '2')
2745 watch_flags = WATCH_TYPE_WRITE;
2746 else if (break_type == '3')
2747 watch_flags = WATCH_TYPE_READ;
2748 else
2749 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
2750
2751 // Check if we currently have a watchpoint already set at this address
2752 BreakpointMapIter pos = m_watchpoints.find(addr);
2753 if (pos != m_watchpoints.end())
2754 {
2755 // We do already have a watchpoint at this address, increment
2756 // its reference count and return OK
2757 pos->second.Retain();
2758 return SendPacket ("OK");
2759 }
2760 else
2761 {
2762 // We do NOT already have a breakpoint at this address, So lets
2763 // create one.
2764 nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware);
2765 if (watch_id != INVALID_NUB_BREAK_ID)
2766 {
2767 // We successfully created a watchpoint, now lets full out
2768 // a ref count structure with the watch_id and add it to our
2769 // map.
2770 Breakpoint rnbWatchpoint(watch_id);
2771 m_watchpoints[addr] = rnbWatchpoint;
2772 return SendPacket ("OK");
2773 }
2774 else
2775 {
2776 // We failed to set the watchpoint
2777 return SendPacket ("E09");
2778 }
2779 }
2780 }
2781 break;
2782
2783 default:
2784 break;
2785 }
2786 }
2787 else if (packet_cmd == 'z')
2788 {
2789 // remove
2790 switch (break_type)
2791 {
2792 case '0': // remove software breakpoint
2793 case '1': // remove hardware breakpoint
2794 {
2795 // gdb can send multiple z packets for the same address and
2796 // these calls must be ref counted.
2797 BreakpointMapIter pos = m_breakpoints.find(addr);
2798 if (pos != m_breakpoints.end())
2799 {
2800 // We currently have a breakpoint at address ADDR. Decrement
2801 // its reference count, and it that count is now zero we
2802 // can clear the breakpoint.
2803 pos->second.Release();
2804 if (pos->second.RefCount() == 0)
2805 {
2806 if (DNBBreakpointClear (pid, pos->second.BreakID()))
2807 {
2808 m_breakpoints.erase(pos);
2809 return SendPacket ("OK");
2810 }
2811 else
2812 {
2813 return SendPacket ("E08");
2814 }
2815 }
2816 else
2817 {
2818 // We still have references to this breakpoint don't
2819 // delete it, just decrementing the reference count
2820 // is enough.
2821 return SendPacket ("OK");
2822 }
2823 }
2824 else
2825 {
2826 // We don't know about any breakpoints at this address
2827 return SendPacket ("E08");
2828 }
2829 }
2830 break;
2831
2832 case '2': // remove write watchpoint
2833 case '3': // remove read watchpoint
2834 case '4': // remove access watchpoint
2835 {
2836 // gdb can send multiple z packets for the same address and
2837 // these calls must be ref counted.
2838 BreakpointMapIter pos = m_watchpoints.find(addr);
2839 if (pos != m_watchpoints.end())
2840 {
2841 // We currently have a watchpoint at address ADDR. Decrement
2842 // its reference count, and it that count is now zero we
2843 // can clear the watchpoint.
2844 pos->second.Release();
2845 if (pos->second.RefCount() == 0)
2846 {
2847 if (DNBWatchpointClear (pid, pos->second.BreakID()))
2848 {
2849 m_watchpoints.erase(pos);
2850 return SendPacket ("OK");
2851 }
2852 else
2853 {
2854 return SendPacket ("E08");
2855 }
2856 }
2857 else
2858 {
2859 // We still have references to this watchpoint don't
2860 // delete it, just decrementing the reference count
2861 // is enough.
2862 return SendPacket ("OK");
2863 }
2864 }
2865 else
2866 {
2867 // We don't know about any watchpoints at this address
2868 return SendPacket ("E08");
2869 }
2870 }
2871 break;
2872
2873 default:
2874 break;
2875 }
2876 }
2877 return HandlePacket_UNIMPLEMENTED(p);
2878}
2879
Greg Claytonc71899e2011-01-18 19:36:39 +00002880// Extract the thread number from the thread suffix that might be appended to
2881// thread specific packets. This will only be enabled if m_thread_suffix_supported
2882// is true.
2883nub_thread_t
2884RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
2885{
2886 if (m_thread_suffix_supported)
2887 {
2888 nub_thread_t tid = INVALID_NUB_THREAD;
2889 if (p)
2890 {
2891 const char *tid_cstr = strstr (p, "thread:");
2892 if (tid_cstr)
2893 {
2894 tid_cstr += strlen ("thread:");
2895 tid = strtoul(tid_cstr, NULL, 16);
2896 }
Greg Claytonc71899e2011-01-18 19:36:39 +00002897 }
Greg Clayton61468e82011-01-19 07:54:15 +00002898 return tid;
Greg Claytonc71899e2011-01-18 19:36:39 +00002899 }
2900 return GetCurrentThread();
2901
2902}
2903
Chris Lattner24943d22010-06-08 16:52:24 +00002904/* `p XX'
2905 print the contents of register X */
2906
2907rnb_err_t
2908RNBRemote::HandlePacket_p (const char *p)
2909{
Greg Clayton20d338f2010-11-18 05:57:03 +00002910 if (g_num_reg_entries == 0)
2911 InitializeRegisters ();
2912
Chris Lattner24943d22010-06-08 16:52:24 +00002913 if (p == NULL || *p == '\0')
2914 {
2915 return HandlePacket_ILLFORMED ("No thread specified in p packet");
2916 }
2917 if (!m_ctx.HasValidProcessID())
2918 {
2919 return SendPacket ("E15");
2920 }
2921 nub_process_t pid = m_ctx.ProcessID();
2922 errno = 0;
Greg Claytonc71899e2011-01-18 19:36:39 +00002923 char *tid_cstr = NULL;
2924 uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
Chris Lattner24943d22010-06-08 16:52:24 +00002925 if (errno != 0 && reg == 0)
2926 {
Greg Claytonc71899e2011-01-18 19:36:39 +00002927 return HandlePacket_ILLFORMED ("Could not parse register number in p packet");
Chris Lattner24943d22010-06-08 16:52:24 +00002928 }
2929
Greg Claytonc71899e2011-01-18 19:36:39 +00002930 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
2931 if (tid == INVALID_NUB_THREAD)
2932 return HandlePacket_ILLFORMED ("No thread specified in p packet");
2933
Chris Lattner24943d22010-06-08 16:52:24 +00002934 const register_map_entry_t *reg_entry;
2935
2936 if (reg < g_num_reg_entries)
2937 reg_entry = &g_reg_entries[reg];
2938 else
2939 reg_entry = NULL;
2940
2941 std::ostringstream ostrm;
2942 if (reg_entry == NULL)
2943 {
2944 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
2945 ostrm << "00000000";
2946 }
2947 else if (reg_entry->nub_info.reg == -1)
2948 {
2949 if (reg_entry->gdb_size > 0)
2950 {
2951 if (reg_entry->fail_value != NULL)
2952 {
2953 append_hex_value(ostrm, reg_entry->fail_value, reg_entry->gdb_size, false);
2954 }
2955 else
2956 {
2957 std::basic_string<uint8_t> zeros(reg_entry->gdb_size, '\0');
2958 append_hex_value(ostrm, zeros.data(), zeros.size(), false);
2959 }
2960 }
2961 }
2962 else
2963 {
Chris Lattner24943d22010-06-08 16:52:24 +00002964 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry);
2965 }
2966 return SendPacket (ostrm.str());
2967}
2968
2969/* `Pnn=rrrrr'
2970 Set register number n to value r.
2971 n and r are hex strings. */
2972
2973rnb_err_t
2974RNBRemote::HandlePacket_P (const char *p)
2975{
Greg Clayton20d338f2010-11-18 05:57:03 +00002976 if (g_num_reg_entries == 0)
2977 InitializeRegisters ();
2978
Chris Lattner24943d22010-06-08 16:52:24 +00002979 if (p == NULL || *p == '\0')
2980 {
2981 return HandlePacket_ILLFORMED ("Empty P packet");
2982 }
2983 if (!m_ctx.HasValidProcessID())
2984 {
2985 return SendPacket ("E28");
2986 }
2987
2988 nub_process_t pid = m_ctx.ProcessID();
2989
2990 StringExtractor packet (p);
2991
2992 const char cmd_char = packet.GetChar();
2993 // Register ID is always in big endian
2994 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
2995 const char equal_char = packet.GetChar();
2996
2997 if (cmd_char != 'P')
2998 return HandlePacket_ILLFORMED ("Improperly formed P packet");
2999
3000 if (reg == UINT32_MAX)
3001 return SendPacket ("E29");
3002
3003 if (equal_char != '=')
3004 return SendPacket ("E30");
3005
3006 const register_map_entry_t *reg_entry;
3007
3008 if (reg >= g_num_reg_entries)
3009 return SendPacket("E47");
3010
3011 reg_entry = &g_reg_entries[reg];
3012
3013 if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1)
3014 {
3015 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
3016 return SendPacket("E48");
3017 }
3018
3019 DNBRegisterValue reg_value;
3020 reg_value.info = reg_entry->nub_info;
3021 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc);
3022
Greg Claytonc71899e2011-01-18 19:36:39 +00003023 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3024 if (tid == INVALID_NUB_THREAD)
3025 return HandlePacket_ILLFORMED ("No thread specified in p packet");
Chris Lattner24943d22010-06-08 16:52:24 +00003026
3027 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
3028 {
3029 return SendPacket ("E32");
3030 }
3031 return SendPacket ("OK");
3032}
3033
3034/* `c [addr]'
3035 Continue, optionally from a specified address. */
3036
3037rnb_err_t
3038RNBRemote::HandlePacket_c (const char *p)
3039{
3040 const nub_process_t pid = m_ctx.ProcessID();
3041
3042 if (pid == INVALID_NUB_PROCESS)
3043 return SendPacket ("E23");
3044
3045 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3046
3047 if (*(p + 1) != '\0')
3048 {
3049 action.tid = GetContinueThread();
3050 errno = 0;
3051 action.addr = strtoull (p + 1, NULL, 16);
3052 if (errno != 0 && action.addr == 0)
3053 return HandlePacket_ILLFORMED ("Could not parse address in c packet");
3054 }
3055
3056 DNBThreadResumeActions thread_actions;
3057 thread_actions.Append(action);
3058 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
3059 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3060 return SendPacket ("E25");
3061 // Don't send an "OK" packet; response is the stopped/exited message.
3062 return rnb_success;
3063}
3064
3065/* `C sig [;addr]'
3066 Resume with signal sig, optionally at address addr. */
3067
3068rnb_err_t
3069RNBRemote::HandlePacket_C (const char *p)
3070{
3071 const nub_process_t pid = m_ctx.ProcessID();
3072
3073 if (pid == INVALID_NUB_PROCESS)
3074 return SendPacket ("E36");
3075
3076 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3077 int process_signo = -1;
3078 if (*(p + 1) != '\0')
3079 {
3080 action.tid = GetContinueThread();
3081 char *end = NULL;
3082 errno = 0;
3083 process_signo = strtoul (p + 1, &end, 16);
3084 if (errno != 0)
3085 return HandlePacket_ILLFORMED ("Could not parse signal in C packet");
3086 else if (*end == ';')
3087 {
3088 errno = 0;
3089 action.addr = strtoull (end + 1, NULL, 16);
3090 if (errno != 0 && action.addr == 0)
3091 return HandlePacket_ILLFORMED ("Could not parse address in C packet");
3092 }
3093 }
3094
3095 DNBThreadResumeActions thread_actions;
3096 thread_actions.Append (action);
3097 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
3098 if (!DNBProcessSignal(pid, process_signo))
3099 return SendPacket ("E52");
3100 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3101 return SendPacket ("E38");
3102 /* Don't send an "OK" packet; response is the stopped/exited message. */
3103 return rnb_success;
3104}
3105
3106//----------------------------------------------------------------------
3107// 'D' packet
3108// Detach from gdb.
3109//----------------------------------------------------------------------
3110rnb_err_t
3111RNBRemote::HandlePacket_D (const char *p)
3112{
Greg Clayton3b2c41c2010-10-18 04:14:23 +00003113 // We are not supposed to send a response for deatch.
3114 //SendPacket ("OK");
Chris Lattner24943d22010-06-08 16:52:24 +00003115 if (m_ctx.HasValidProcessID())
3116 DNBProcessDetach(m_ctx.ProcessID());
3117 return rnb_success;
3118}
3119
3120/* `k'
3121 Kill the inferior process. */
3122
3123rnb_err_t
3124RNBRemote::HandlePacket_k (const char *p)
3125{
Greg Claytona4881d02011-01-22 07:12:45 +00003126 // No response to should be sent to the kill packet
3127 if (m_ctx.HasValidProcessID())
3128 DNBProcessKill (m_ctx.ProcessID());
Greg Clayton72e1c782011-01-22 23:43:18 +00003129 SendPacket ("W09");
Greg Claytona4881d02011-01-22 07:12:45 +00003130 return rnb_success;
Chris Lattner24943d22010-06-08 16:52:24 +00003131}
3132
3133rnb_err_t
3134RNBRemote::HandlePacket_stop_process (const char *p)
3135{
3136 DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP);
3137 //DNBProcessSignal (m_ctx.ProcessID(), SIGINT);
3138 // Do not send any response packet! Wait for the stop reply packet to naturally happen
3139 return rnb_success;
3140}
3141
3142/* `s'
3143 Step the inferior process. */
3144
3145rnb_err_t
3146RNBRemote::HandlePacket_s (const char *p)
3147{
3148 const nub_process_t pid = m_ctx.ProcessID();
3149 if (pid == INVALID_NUB_PROCESS)
3150 return SendPacket ("E32");
3151
3152 // Hardware supported stepping not supported on arm
3153 nub_thread_t tid = GetContinueThread ();
3154 if (tid == 0 || tid == -1)
3155 tid = GetCurrentThread();
3156
3157 if (tid == INVALID_NUB_THREAD)
3158 return SendPacket ("E33");
3159
3160 DNBThreadResumeActions thread_actions;
3161 thread_actions.AppendAction(tid, eStateStepping);
3162
3163 // Make all other threads stop when we are stepping
3164 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3165 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3166 return SendPacket ("E49");
3167 // Don't send an "OK" packet; response is the stopped/exited message.
3168 return rnb_success;
3169}
3170
3171/* `S sig [;addr]'
3172 Step with signal sig, optionally at address addr. */
3173
3174rnb_err_t
3175RNBRemote::HandlePacket_S (const char *p)
3176{
3177 const nub_process_t pid = m_ctx.ProcessID();
3178 if (pid == INVALID_NUB_PROCESS)
3179 return SendPacket ("E36");
3180
3181 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
3182
3183 if (*(p + 1) != '\0')
3184 {
3185 char *end = NULL;
3186 errno = 0;
3187 action.signal = strtoul (p + 1, &end, 16);
3188 if (errno != 0)
3189 return HandlePacket_ILLFORMED ("Could not parse signal in S packet");
3190 else if (*end == ';')
3191 {
3192 errno = 0;
3193 action.addr = strtoull (end + 1, NULL, 16);
3194 if (errno != 0 && action.addr == 0)
3195 {
3196 return HandlePacket_ILLFORMED ("Could not parse address in S packet");
3197 }
3198 }
3199 }
3200
3201 action.tid = GetContinueThread ();
3202 if (action.tid == 0 || action.tid == -1)
3203 return SendPacket ("E40");
3204
3205 nub_state_t tstate = DNBThreadGetState (pid, action.tid);
3206 if (tstate == eStateInvalid || tstate == eStateExited)
3207 return SendPacket ("E37");
3208
3209
3210 DNBThreadResumeActions thread_actions;
3211 thread_actions.Append (action);
3212
3213 // Make all other threads stop when we are stepping
3214 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
3215 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3216 return SendPacket ("E39");
3217
3218 // Don't send an "OK" packet; response is the stopped/exited message.
3219 return rnb_success;
3220}
3221
3222rnb_err_t
3223RNBRemote::HandlePacket_qHostInfo (const char *p)
3224{
3225 std::ostringstream strm;
3226
3227 uint32_t cputype, is_64_bit_capable;
3228 size_t len = sizeof(cputype);
3229 bool promoted_to_64 = false;
3230 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
3231 {
3232 len = sizeof (is_64_bit_capable);
3233 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
3234 {
3235 if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0))
3236 {
3237 promoted_to_64 = true;
3238 cputype |= CPU_ARCH_ABI64;
3239 }
3240 }
3241
3242 strm << "cputype:" << std::dec << cputype << ';';
3243 }
3244
3245 uint32_t cpusubtype;
3246 len = sizeof(cpusubtype);
3247 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
3248 {
3249 if (promoted_to_64 &&
3250 cputype == CPU_TYPE_X86_64 &&
3251 cpusubtype == CPU_SUBTYPE_486)
3252 cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3253
3254 strm << "cpusubtype:" << std::dec << cpusubtype << ';';
3255 }
3256
3257 char ostype[64];
3258 len = sizeof(ostype);
3259 if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
3260 strm << "ostype:" << std::dec << ostype << ';';
3261
3262 strm << "vendor:apple;";
3263
3264#if defined (__LITTLE_ENDIAN__)
3265 strm << "endian:little;";
3266#elif defined (__BIG_ENDIAN__)
3267 strm << "endian:big;";
3268#elif defined (__PDP_ENDIAN__)
3269 strm << "endian:pdp;";
3270#endif
3271
3272 strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
3273 return SendPacket (strm.str());
3274}
3275