RNBRemote.cpp revision 3b2c41c9d12bafdad87cc271fadd1f816081b9a8
1//===-- RNBRemote.cpp -------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Created by Greg Clayton on 12/12/07. 11// 12//===----------------------------------------------------------------------===// 13 14#include "RNBRemote.h" 15 16#include <errno.h> 17#include <unistd.h> 18#include <signal.h> 19#include <mach/exception_types.h> 20#include <sys/sysctl.h> 21 22#include "DNB.h" 23#include "DNBLog.h" 24#include "DNBThreadResumeActions.h" 25#include "RNBContext.h" 26#include "RNBServices.h" 27#include "RNBSocket.h" 28#include "Utility/StringExtractor.h" 29 30#include <iomanip> 31#include <sstream> 32 33#include <TargetConditionals.h> // for endianness predefines 34 35//---------------------------------------------------------------------- 36// std::iostream formatting macros 37//---------------------------------------------------------------------- 38#define RAW_HEXBASE std::setfill('0') << std::hex << std::right 39#define HEXBASE '0' << 'x' << RAW_HEXBASE 40#define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)((uint8_t)x)) 41#define RAWHEX16 RAW_HEXBASE << std::setw(4) 42#define RAWHEX32 RAW_HEXBASE << std::setw(8) 43#define RAWHEX64 RAW_HEXBASE << std::setw(16) 44#define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x)) 45#define HEX16 HEXBASE << std::setw(4) 46#define HEX32 HEXBASE << std::setw(8) 47#define HEX64 HEXBASE << std::setw(16) 48#define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x)*2) << (x) 49#define HEX(x) HEXBASE << std::setw(sizeof(x)*2) << (x) 50#define RAWHEX_SIZE(x, sz) RAW_HEXBASE << std::setw((sz)) << (x) 51#define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x) 52#define STRING_WIDTH(w) std::setfill(' ') << std::setw(w) 53#define LEFT_STRING_WIDTH(s, w) std::left << std::setfill(' ') << std::setw(w) << (s) << std::right 54#define DECIMAL std::dec << std::setfill(' ') 55#define DECIMAL_WIDTH(w) DECIMAL << std::setw(w) 56#define FLOAT(n, d) std::setfill(' ') << std::setw((n)+(d)+1) << std::setprecision(d) << std::showpoint << std::fixed 57#define INDENT_WITH_SPACES(iword_idx) std::setfill(' ') << std::setw((iword_idx)) << "" 58#define INDENT_WITH_TABS(iword_idx) std::setfill('\t') << std::setw((iword_idx)) << "" 59// Class to handle communications via gdb remote protocol. 60 61extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 62 63RNBRemote::RNBRemote (bool use_native_regs) : 64 m_ctx(), 65 m_comm(), 66 m_extended_mode(false), 67 m_noack_mode(false), 68 m_continue_thread(-1), 69 m_thread(-1), 70 m_mutex(), 71 m_packets_recvd(0), 72 m_packets(), 73 m_rx_packets(), 74 m_rx_partial_data(), 75 m_rx_pthread(0), 76 m_breakpoints(), 77 m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4), 78 m_use_native_regs (use_native_regs) 79{ 80 DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); 81 CreatePacketTable (); 82} 83 84 85RNBRemote::~RNBRemote() 86{ 87 DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); 88 StopReadRemoteDataThread(); 89} 90 91void 92RNBRemote::CreatePacketTable () 93{ 94 // Step required to add new packets: 95 // 1 - Add new enumeration to RNBRemote::PacketEnum 96 // 2 - Create a the RNBRemote::HandlePacket_ function if a new function is needed 97 // 3 - Register the Packet definition with any needed callbacks in this fucntion 98 // - If no response is needed for a command, then use NULL for the normal callback 99 // - If the packet is not supported while the target is running, use NULL for the async callback 100 // 4 - If the packet is a standard packet (starts with a '$' character 101 // followed by the payload and then '#' and checksum, then you are done 102 // else go on to step 5 103 // 5 - if the packet is a fixed length packet: 104 // - modify the switch statement for the first character in the payload 105 // in RNBRemote::CommDataReceived so it doesn't reject the new packet 106 // type as invalid 107 // - modify the switch statement for the first character in the payload 108 // in RNBRemote::GetPacketPayload and make sure the payload of the packet 109 // is returned correctly 110 111 std::vector <Packet> &t = m_packets; 112 t.push_back (Packet (ack, NULL, NULL, "+", "ACK")); 113 t.push_back (Packet (nack, NULL, NULL, "-", "!ACK")); 114 t.push_back (Packet (read_memory, &RNBRemote::HandlePacket_m, NULL, "m", "Read memory")); 115 t.push_back (Packet (read_register, &RNBRemote::HandlePacket_p, NULL, "p", "Read one register")); 116 t.push_back (Packet (read_general_regs, &RNBRemote::HandlePacket_g, NULL, "g", "Read registers")); 117 t.push_back (Packet (write_memory, &RNBRemote::HandlePacket_M, NULL, "M", "Write memory")); 118 t.push_back (Packet (write_register, &RNBRemote::HandlePacket_P, NULL, "P", "Write one register")); 119 t.push_back (Packet (write_general_regs, &RNBRemote::HandlePacket_G, NULL, "G", "Write registers")); 120 t.push_back (Packet (insert_mem_bp, &RNBRemote::HandlePacket_z, NULL, "Z0", "Insert memory breakpoint")); 121 t.push_back (Packet (remove_mem_bp, &RNBRemote::HandlePacket_z, NULL, "z0", "Remove memory breakpoint")); 122 t.push_back (Packet (single_step, &RNBRemote::HandlePacket_s, NULL, "s", "Single step")); 123 t.push_back (Packet (cont, &RNBRemote::HandlePacket_c, NULL, "c", "continue")); 124 t.push_back (Packet (single_step_with_sig, &RNBRemote::HandlePacket_S, NULL, "S", "Single step with signal")); 125 t.push_back (Packet (set_thread, &RNBRemote::HandlePacket_H, NULL, "H", "Set thread")); 126 t.push_back (Packet (halt, &RNBRemote::HandlePacket_last_signal, &RNBRemote::HandlePacket_stop_process, "\x03", "^C")); 127// t.push_back (Packet (use_extended_mode, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode")); 128 t.push_back (Packet (why_halted, &RNBRemote::HandlePacket_last_signal, NULL, "?", "Why did target halt")); 129 t.push_back (Packet (set_argv, &RNBRemote::HandlePacket_A, NULL, "A", "Set argv")); 130// t.push_back (Packet (set_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear breakpoint")); 131 t.push_back (Packet (continue_with_sig, &RNBRemote::HandlePacket_C, NULL, "C", "Continue with signal")); 132 t.push_back (Packet (detach, &RNBRemote::HandlePacket_D, NULL, "D", "Detach gdb from remote system")); 133// t.push_back (Packet (step_inferior_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one clock cycle")); 134// t.push_back (Packet (signal_and_step_inf_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then step one clock cyle")); 135 t.push_back (Packet (kill, &RNBRemote::HandlePacket_k, NULL, "k", "Kill")); 136// t.push_back (Packet (restart, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior")); 137// t.push_back (Packet (search_mem_backwards, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory backwards")); 138 t.push_back (Packet (thread_alive_p, &RNBRemote::HandlePacket_T, NULL, "T", "Is thread alive")); 139 t.push_back (Packet (vattach, &RNBRemote::HandlePacket_v, NULL, "vAttach", "Attach to a new process")); 140 t.push_back (Packet (vattachwait, &RNBRemote::HandlePacket_v, NULL, "vAttachWait", "Wait for a process to start up then attach to it")); 141 t.push_back (Packet (vattachname, &RNBRemote::HandlePacket_v, NULL, "vAttachName", "Attach to an existing process by name")); 142 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")); 175 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")); 176// 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}, 831 { 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}, 839 { 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 1756 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 1770 /* 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) 1952 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';'; 1953 } 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, ®_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, ®_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 (®_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, ®_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 } 2555 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 } 2580 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, ®_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 // We are not supposed to send a response for deatch. 3068 //SendPacket ("OK"); 3069 if (m_ctx.HasValidProcessID()) 3070 DNBProcessDetach(m_ctx.ProcessID()); 3071 return rnb_success; 3072} 3073 3074/* `k' 3075 Kill the inferior process. */ 3076 3077rnb_err_t 3078RNBRemote::HandlePacket_k (const char *p) 3079{ 3080 if (!m_ctx.HasValidProcessID()) 3081 return SendPacket ("E26"); 3082 if (!DNBProcessKill (m_ctx.ProcessID())) 3083 return SendPacket ("E27"); 3084 return SendPacket ("OK"); 3085} 3086 3087rnb_err_t 3088RNBRemote::HandlePacket_stop_process (const char *p) 3089{ 3090 DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP); 3091 //DNBProcessSignal (m_ctx.ProcessID(), SIGINT); 3092 // Do not send any response packet! Wait for the stop reply packet to naturally happen 3093 return rnb_success; 3094} 3095 3096/* `s' 3097 Step the inferior process. */ 3098 3099rnb_err_t 3100RNBRemote::HandlePacket_s (const char *p) 3101{ 3102 const nub_process_t pid = m_ctx.ProcessID(); 3103 if (pid == INVALID_NUB_PROCESS) 3104 return SendPacket ("E32"); 3105 3106 // Hardware supported stepping not supported on arm 3107 nub_thread_t tid = GetContinueThread (); 3108 if (tid == 0 || tid == -1) 3109 tid = GetCurrentThread(); 3110 3111 if (tid == INVALID_NUB_THREAD) 3112 return SendPacket ("E33"); 3113 3114 DNBThreadResumeActions thread_actions; 3115 thread_actions.AppendAction(tid, eStateStepping); 3116 3117 // Make all other threads stop when we are stepping 3118 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3119 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3120 return SendPacket ("E49"); 3121 // Don't send an "OK" packet; response is the stopped/exited message. 3122 return rnb_success; 3123} 3124 3125/* `S sig [;addr]' 3126 Step with signal sig, optionally at address addr. */ 3127 3128rnb_err_t 3129RNBRemote::HandlePacket_S (const char *p) 3130{ 3131 const nub_process_t pid = m_ctx.ProcessID(); 3132 if (pid == INVALID_NUB_PROCESS) 3133 return SendPacket ("E36"); 3134 3135 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 3136 3137 if (*(p + 1) != '\0') 3138 { 3139 char *end = NULL; 3140 errno = 0; 3141 action.signal = strtoul (p + 1, &end, 16); 3142 if (errno != 0) 3143 return HandlePacket_ILLFORMED ("Could not parse signal in S packet"); 3144 else if (*end == ';') 3145 { 3146 errno = 0; 3147 action.addr = strtoull (end + 1, NULL, 16); 3148 if (errno != 0 && action.addr == 0) 3149 { 3150 return HandlePacket_ILLFORMED ("Could not parse address in S packet"); 3151 } 3152 } 3153 } 3154 3155 action.tid = GetContinueThread (); 3156 if (action.tid == 0 || action.tid == -1) 3157 return SendPacket ("E40"); 3158 3159 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 3160 if (tstate == eStateInvalid || tstate == eStateExited) 3161 return SendPacket ("E37"); 3162 3163 3164 DNBThreadResumeActions thread_actions; 3165 thread_actions.Append (action); 3166 3167 // Make all other threads stop when we are stepping 3168 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3169 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3170 return SendPacket ("E39"); 3171 3172 // Don't send an "OK" packet; response is the stopped/exited message. 3173 return rnb_success; 3174} 3175 3176rnb_err_t 3177RNBRemote::HandlePacket_qHostInfo (const char *p) 3178{ 3179 std::ostringstream strm; 3180 3181 uint32_t cputype, is_64_bit_capable; 3182 size_t len = sizeof(cputype); 3183 bool promoted_to_64 = false; 3184 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 3185 { 3186 len = sizeof (is_64_bit_capable); 3187 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 3188 { 3189 if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0)) 3190 { 3191 promoted_to_64 = true; 3192 cputype |= CPU_ARCH_ABI64; 3193 } 3194 } 3195 3196 strm << "cputype:" << std::dec << cputype << ';'; 3197 } 3198 3199 uint32_t cpusubtype; 3200 len = sizeof(cpusubtype); 3201 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 3202 { 3203 if (promoted_to_64 && 3204 cputype == CPU_TYPE_X86_64 && 3205 cpusubtype == CPU_SUBTYPE_486) 3206 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3207 3208 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 3209 } 3210 3211 char ostype[64]; 3212 len = sizeof(ostype); 3213 if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 3214 strm << "ostype:" << std::dec << ostype << ';'; 3215 3216 strm << "vendor:apple;"; 3217 3218#if defined (__LITTLE_ENDIAN__) 3219 strm << "endian:little;"; 3220#elif defined (__BIG_ENDIAN__) 3221 strm << "endian:big;"; 3222#elif defined (__PDP_ENDIAN__) 3223 strm << "endian:pdp;"; 3224#endif 3225 3226 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 3227 return SendPacket (strm.str()); 3228} 3229 3230