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