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