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