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