RNBRemote.cpp revision 178e101a9e53ba2cb458c20702a98d76dd851c87
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_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL, "qGetPid", "Query process id")); 158// t.push_back (Packet (query_memory_crc, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qCRC:", "Compute CRC of memory region")); 159 t.push_back (Packet (query_thread_ids_first, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo", "Get list of active threads (first req)")); 160 t.push_back (Packet (query_thread_ids_subsequent, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo", "Get list of active threads (subsequent req)")); 161 // APPLE LOCAL: qThreadStopInfo 162 // syntax: qThreadStopInfoTTTT 163 // TTTT is hex thread ID 164 t.push_back (Packet (query_thread_stop_info, &RNBRemote::HandlePacket_qThreadStopInfo, NULL, "qThreadStopInfo", "Get detailed info on why the specified thread stopped")); 165 t.push_back (Packet (query_thread_extra_info, &RNBRemote::HandlePacket_qThreadExtraInfo,NULL, "qThreadExtraInfo", "Get printable status of a thread")); 166// t.push_back (Packet (query_image_offsets, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qOffsets", "Report offset of loaded program")); 167 t.push_back (Packet (query_launch_success, &RNBRemote::HandlePacket_qLaunchSuccess,NULL, "qLaunchSuccess", "Report the success or failure of the launch attempt")); 168 t.push_back (Packet (query_register_info, &RNBRemote::HandlePacket_qRegisterInfo, NULL, "qRegisterInfo", "Dynamically discover remote register context information.")); 169 t.push_back (Packet (query_shlib_notify_info_addr, &RNBRemote::HandlePacket_qShlibInfoAddr,NULL, "qShlibInfoAddr", "Returns the address that contains info needed for getting shared library notifications")); 170 t.push_back (Packet (query_step_packet_supported, &RNBRemote::HandlePacket_qStepPacketSupported,NULL, "qStepPacketSupported", "Replys with OK if the 's' packet is supported.")); 171 t.push_back (Packet (query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other.")); 172// t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups")); 173 t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets")); 174 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")); 175 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")); 176 t.push_back (Packet (set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle")); 177 t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle")); 178 t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_QEnvironment , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment")); 179 t.push_back (Packet (set_environment_variable_hex, &RNBRemote::HandlePacket_QEnvironmentHexEncoded , NULL, "QEnvironmentHexEncoded:", "Add an environment variable to the inferior's environment")); 180 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.")); 181 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")); 182 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")); 183 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")); 184 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")); 185 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")); 186// t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior")); 187 t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process.")); 188 t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process.")); 189} 190 191 192void 193RNBRemote::FlushSTDIO () 194{ 195 if (m_ctx.HasValidProcessID()) 196 { 197 nub_process_t pid = m_ctx.ProcessID(); 198 char buf[256]; 199 nub_size_t count; 200 do 201 { 202 count = DNBProcessGetAvailableSTDOUT(pid, buf, sizeof(buf)); 203 if (count > 0) 204 { 205 SendSTDOUTPacket (buf, count); 206 } 207 } while (count > 0); 208 209 do 210 { 211 count = DNBProcessGetAvailableSTDERR(pid, buf, sizeof(buf)); 212 if (count > 0) 213 { 214 SendSTDERRPacket (buf, count); 215 } 216 } while (count > 0); 217 } 218} 219 220rnb_err_t 221RNBRemote::SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer) 222{ 223 std::ostringstream packet_sstrm; 224 // Append the header cstr if there was one 225 if (header && header[0]) 226 packet_sstrm << header; 227 nub_size_t i; 228 const uint8_t *ubuf8 = (const uint8_t *)buf; 229 for (i=0; i<buf_len; i++) 230 { 231 packet_sstrm << RAWHEX8(ubuf8[i]); 232 } 233 // Append the footer cstr if there was one 234 if (footer && footer[0]) 235 packet_sstrm << footer; 236 237 return SendPacket(packet_sstrm.str()); 238} 239 240rnb_err_t 241RNBRemote::SendSTDOUTPacket (char *buf, nub_size_t buf_size) 242{ 243 if (buf_size == 0) 244 return rnb_success; 245 return SendHexEncodedBytePacket("O", buf, buf_size, NULL); 246} 247 248rnb_err_t 249RNBRemote::SendSTDERRPacket (char *buf, nub_size_t buf_size) 250{ 251 if (buf_size == 0) 252 return rnb_success; 253 return SendHexEncodedBytePacket("O", buf, buf_size, NULL); 254} 255 256rnb_err_t 257RNBRemote::SendPacket (const std::string &s) 258{ 259 DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, s.c_str()); 260 std::string sendpacket = "$" + s + "#"; 261 int cksum = 0; 262 char hexbuf[5]; 263 264 if (m_noack_mode) 265 { 266 sendpacket += "00"; 267 } 268 else 269 { 270 for (int i = 0; i != s.size(); ++i) 271 cksum += s[i]; 272 snprintf (hexbuf, sizeof hexbuf, "%02x", cksum & 0xff); 273 sendpacket += hexbuf; 274 } 275 276 rnb_err_t err = m_comm.Write (sendpacket.c_str(), sendpacket.size()); 277 if (err != rnb_success) 278 return err; 279 280 if (m_noack_mode) 281 return rnb_success; 282 283 std::string reply; 284 RNBRemote::Packet packet; 285 err = GetPacket (reply, packet, true); 286 287 if (err != rnb_success) 288 { 289 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()); 290 return err; 291 } 292 293 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()); 294 295 if (packet.type == ack) 296 return rnb_success; 297 298 // Should we try to resend the packet at this layer? 299 // if (packet.command == nack) 300 return rnb_err; 301} 302 303/* Get a packet via gdb remote protocol. 304 Strip off the prefix/suffix, verify the checksum to make sure 305 a valid packet was received, send an ACK if they match. */ 306 307rnb_err_t 308RNBRemote::GetPacketPayload (std::string &return_packet) 309{ 310 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 311 312 PThreadMutex::Locker locker(m_mutex); 313 if (m_rx_packets.empty()) 314 { 315 // Only reset the remote command available event if we have no more packets 316 m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available ); 317 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s error: no packets available...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 318 return rnb_err; 319 } 320 321 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s has %u queued packets", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, m_rx_packets.size()); 322 return_packet.swap(m_rx_packets.front()); 323 m_rx_packets.pop_front(); 324 locker.Reset(); // Release our lock on the mutex 325 326 if (m_rx_packets.empty()) 327 { 328 // Reset the remote command available event if we have no more packets 329 m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available ); 330 } 331 332 //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str()); 333 334 switch (return_packet[0]) 335 { 336 case '+': 337 case '-': 338 case '\x03': 339 break; 340 341 case '$': 342 { 343 int packet_checksum = 0; 344 if (!m_noack_mode) 345 { 346 for (int i = return_packet.size() - 2; i < return_packet.size(); ++i) 347 { 348 char checksum_char = tolower (return_packet[i]); 349 if (!isxdigit (checksum_char)) 350 { 351 m_comm.Write ("-", 1); 352 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()); 353 return rnb_err; 354 } 355 } 356 packet_checksum = strtol (&return_packet[return_packet.size() - 2], NULL, 16); 357 } 358 359 return_packet.erase(0,1); // Strip the leading '$' 360 return_packet.erase(return_packet.size() - 3);// Strip the #XX checksum 361 362 if (!m_noack_mode) 363 { 364 // Compute the checksum 365 int computed_checksum = 0; 366 for (std::string::iterator it = return_packet.begin (); 367 it != return_packet.end (); 368 ++it) 369 { 370 computed_checksum += *it; 371 } 372 373 if (packet_checksum == (computed_checksum & 0xff)) 374 { 375 //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str()); 376 m_comm.Write ("+", 1); 377 } 378 else 379 { 380 DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s' (error: packet checksum mismatch (0x%2.2x != 0x%2.2x))", 381 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 382 __FUNCTION__, 383 return_packet.c_str(), 384 packet_checksum, 385 computed_checksum); 386 m_comm.Write ("-", 1); 387 return rnb_err; 388 } 389 } 390 } 391 break; 392 393 default: 394 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s tossing unexpected packet???? %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str()); 395 if (!m_noack_mode) 396 m_comm.Write ("-", 1); 397 return rnb_err; 398 } 399 400 return rnb_success; 401} 402 403rnb_err_t 404RNBRemote::HandlePacket_UNIMPLEMENTED (const char* p) 405{ 406 DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s(\"%s\")", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p ? p : "NULL"); 407 return SendPacket (""); 408} 409 410rnb_err_t 411RNBRemote::HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description) 412{ 413 DNBLogThreadedIf (LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file, line, __FUNCTION__, p); 414 return SendPacket ("E03"); 415} 416 417rnb_err_t 418RNBRemote::GetPacket (std::string &packet_payload, RNBRemote::Packet& packet_info, bool wait) 419{ 420 std::string payload; 421 rnb_err_t err = GetPacketPayload (payload); 422 if (err != rnb_success) 423 { 424 PThreadEvent& events = m_ctx.Events(); 425 nub_event_t set_events = events.GetEventBits(); 426 // TODO: add timeout version of GetPacket?? We would then need to pass 427 // that timeout value along to DNBProcessTimedWaitForEvent. 428 if (!wait || ((set_events & RNBContext::event_read_thread_running) == 0)) 429 return err; 430 431 const nub_event_t events_to_wait_for = RNBContext::event_read_packet_available | RNBContext::event_read_thread_exiting; 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_qGetPid (const char *p) 1398{ 1399 nub_process_t pid; 1400 std::ostringstream rep; 1401 // If we haven't run the process yet, we tell the debugger the 1402 // pid is 0. That way it can know to tell use to run later on. 1403 if (m_ctx.HasValidProcessID()) 1404 pid = m_ctx.ProcessID(); 1405 else 1406 pid = 0; 1407 rep << std::hex << pid; 1408 return SendPacket (rep.str()); 1409} 1410 1411rnb_err_t 1412RNBRemote::HandlePacket_qRegisterInfo (const char *p) 1413{ 1414 if (g_num_reg_entries == 0) 1415 InitializeRegisters (); 1416 1417 p += strlen ("qRegisterInfo"); 1418 1419 nub_size_t num_reg_sets = 0; 1420 const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets); 1421 uint32_t reg_num = strtoul(p, 0, 16); 1422 1423 if (reg_num < g_num_reg_entries) 1424 { 1425 const register_map_entry_t *reg_entry = &g_reg_entries[reg_num]; 1426 std::ostringstream ostrm; 1427 ostrm << "name:" << reg_entry->gdb_name << ';'; 1428 1429 if (reg_entry->nub_info.name && ::strcmp (reg_entry->gdb_name, reg_entry->nub_info.name)) 1430 ostrm << "alt-name:" << reg_entry->nub_info.name << ';'; 1431 else if (reg_entry->nub_info.alt && ::strcmp (reg_entry->gdb_name, reg_entry->nub_info.alt)) 1432 ostrm << "alt-name:" << reg_entry->nub_info.alt << ';'; 1433 1434 ostrm << "bitsize:" << std::dec << reg_entry->gdb_size * 8 << ';'; 1435 ostrm << "offset:" << std::dec << reg_entry->nub_info.offset << ';'; 1436 1437 switch (reg_entry->nub_info.type) 1438 { 1439 case Uint: ostrm << "encoding:uint;"; break; 1440 case Sint: ostrm << "encoding:sint;"; break; 1441 case IEEE754: ostrm << "encoding:ieee754;"; break; 1442 case Vector: ostrm << "encoding:vector;"; break; 1443 } 1444 1445 switch (reg_entry->nub_info.format) 1446 { 1447 case Binary: ostrm << "format:binary;"; break; 1448 case Decimal: ostrm << "format:decimal;"; break; 1449 case Hex: ostrm << "format:hex;"; break; 1450 case Float: ostrm << "format:float;"; break; 1451 case VectorOfSInt8: ostrm << "format:vector-sint8;"; break; 1452 case VectorOfUInt8: ostrm << "format:vector-uint8;"; break; 1453 case VectorOfSInt16: ostrm << "format:vector-sint16;"; break; 1454 case VectorOfUInt16: ostrm << "format:vector-uint16;"; break; 1455 case VectorOfSInt32: ostrm << "format:vector-sint32;"; break; 1456 case VectorOfUInt32: ostrm << "format:vector-uint32;"; break; 1457 case VectorOfFloat32: ostrm << "format:vector-float32;"; break; 1458 case VectorOfUInt128: ostrm << "format:vector-uint128;"; break; 1459 }; 1460 1461 if (reg_set_info && reg_entry->nub_info.set < num_reg_sets) 1462 ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';'; 1463 1464 1465 if (g_reg_entries != g_dynamic_register_map.data()) 1466 { 1467 if (reg_entry->nub_info.reg_gdb != INVALID_NUB_REGNUM && reg_entry->nub_info.reg_gdb != reg_num) 1468 { 1469 printf("register %s is getting gdb reg_num of %u when the register info says %u\n", 1470 reg_entry->gdb_name, reg_num, reg_entry->nub_info.reg_gdb); 1471 } 1472 } 1473 1474 if (reg_entry->nub_info.reg_gcc != INVALID_NUB_REGNUM) 1475 ostrm << "gcc:" << std::dec << reg_entry->nub_info.reg_gcc << ';'; 1476 1477 if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM) 1478 ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';'; 1479 1480 1481 switch (reg_entry->nub_info.reg_generic) 1482 { 1483 case GENERIC_REGNUM_FP: ostrm << "generic:fp;"; break; 1484 case GENERIC_REGNUM_PC: ostrm << "generic:pc;"; break; 1485 case GENERIC_REGNUM_SP: ostrm << "generic:sp;"; break; 1486 case GENERIC_REGNUM_RA: ostrm << "generic:ra;"; break; 1487 case GENERIC_REGNUM_FLAGS: ostrm << "generic:flags;"; break; 1488 case GENERIC_REGNUM_ARG1: ostrm << "generic:arg1;"; break; 1489 case GENERIC_REGNUM_ARG2: ostrm << "generic:arg2;"; break; 1490 case GENERIC_REGNUM_ARG3: ostrm << "generic:arg3;"; break; 1491 case GENERIC_REGNUM_ARG4: ostrm << "generic:arg4;"; break; 1492 case GENERIC_REGNUM_ARG5: ostrm << "generic:arg5;"; break; 1493 case GENERIC_REGNUM_ARG6: ostrm << "generic:arg6;"; break; 1494 case GENERIC_REGNUM_ARG7: ostrm << "generic:arg7;"; break; 1495 case GENERIC_REGNUM_ARG8: ostrm << "generic:arg8;"; break; 1496 default: break; 1497 } 1498 1499 return SendPacket (ostrm.str ()); 1500 } 1501 return SendPacket ("E45"); 1502} 1503 1504 1505/* This expects a packet formatted like 1506 1507 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE; 1508 1509 with the "QSetLogging:" already removed from the start. Maybe in the 1510 future this packet will include other keyvalue pairs like 1511 1512 QSetLogging:bitmask=LOG_ALL;mode=asl; 1513 */ 1514 1515rnb_err_t 1516set_logging (const char *p) 1517{ 1518 int bitmask = 0; 1519 while (p && *p != '\0') 1520 { 1521 if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0) 1522 { 1523 p += sizeof ("bitmask=") - 1; 1524 while (p && *p != '\0' && *p != ';') 1525 { 1526 if (*p == '|') 1527 p++; 1528 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0) 1529 { 1530 p += sizeof ("LOG_VERBOSE") - 1; 1531 bitmask |= LOG_VERBOSE; 1532 } 1533 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0) 1534 { 1535 p += sizeof ("LOG_PROCESS") - 1; 1536 bitmask |= LOG_PROCESS; 1537 } 1538 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0) 1539 { 1540 p += sizeof ("LOG_THREAD") - 1; 1541 bitmask |= LOG_THREAD; 1542 } 1543 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0) 1544 { 1545 p += sizeof ("LOG_EXCEPTIONS") - 1; 1546 bitmask |= LOG_EXCEPTIONS; 1547 } 1548 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0) 1549 { 1550 p += sizeof ("LOG_SHLIB") - 1; 1551 bitmask |= LOG_SHLIB; 1552 } 1553 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0) 1554 { 1555 p += sizeof ("LOG_MEMORY") - 1; 1556 bitmask |= LOG_MEMORY; 1557 } 1558 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0) 1559 { 1560 p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1; 1561 bitmask |= LOG_MEMORY_DATA_SHORT; 1562 } 1563 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0) 1564 { 1565 p += sizeof ("LOG_MEMORY_DATA_LONG") - 1; 1566 bitmask |= LOG_MEMORY_DATA_LONG; 1567 } 1568 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0) 1569 { 1570 p += sizeof ("LOG_BREAKPOINTS") - 1; 1571 bitmask |= LOG_BREAKPOINTS; 1572 } 1573 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0) 1574 { 1575 p += sizeof ("LOG_ALL") - 1; 1576 bitmask |= LOG_ALL; 1577 } 1578 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0) 1579 { 1580 p += sizeof ("LOG_EVENTS") - 1; 1581 bitmask |= LOG_EVENTS; 1582 } 1583 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0) 1584 { 1585 p += sizeof ("LOG_DEFAULT") - 1; 1586 bitmask |= LOG_DEFAULT; 1587 } 1588 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0) 1589 { 1590 p += sizeof ("LOG_NONE") - 1; 1591 bitmask = 0; 1592 } 1593 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0) 1594 { 1595 p += sizeof ("LOG_RNB_MINIMAL") - 1; 1596 bitmask |= LOG_RNB_MINIMAL; 1597 } 1598 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0) 1599 { 1600 p += sizeof ("LOG_RNB_MEDIUM") - 1; 1601 bitmask |= LOG_RNB_MEDIUM; 1602 } 1603 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0) 1604 { 1605 p += sizeof ("LOG_RNB_MAX") - 1; 1606 bitmask |= LOG_RNB_MAX; 1607 } 1608 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0) 1609 { 1610 p += sizeof ("LOG_RNB_COMM") - 1; 1611 bitmask |= LOG_RNB_COMM; 1612 } 1613 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0) 1614 { 1615 p += sizeof ("LOG_RNB_REMOTE") - 1; 1616 bitmask |= LOG_RNB_REMOTE; 1617 } 1618 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0) 1619 { 1620 p += sizeof ("LOG_RNB_EVENTS") - 1; 1621 bitmask |= LOG_RNB_EVENTS; 1622 } 1623 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0) 1624 { 1625 p += sizeof ("LOG_RNB_PROC") - 1; 1626 bitmask |= LOG_RNB_PROC; 1627 } 1628 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0) 1629 { 1630 p += sizeof ("LOG_RNB_PACKETS") - 1; 1631 bitmask |= LOG_RNB_PACKETS; 1632 } 1633 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0) 1634 { 1635 p += sizeof ("LOG_RNB_ALL") - 1; 1636 bitmask |= LOG_RNB_ALL; 1637 } 1638 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0) 1639 { 1640 p += sizeof ("LOG_RNB_DEFAULT") - 1; 1641 bitmask |= LOG_RNB_DEFAULT; 1642 } 1643 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0) 1644 { 1645 p += sizeof ("LOG_RNB_NONE") - 1; 1646 bitmask = 0; 1647 } 1648 else 1649 { 1650 /* Unrecognized logging bit; ignore it. */ 1651 const char *c = strchr (p, '|'); 1652 if (c) 1653 { 1654 p = c; 1655 } 1656 else 1657 { 1658 c = strchr (p, ';'); 1659 if (c) 1660 { 1661 p = c; 1662 } 1663 else 1664 { 1665 // Improperly terminated word; just go to end of str 1666 p = strchr (p, '\0'); 1667 } 1668 } 1669 } 1670 } 1671 // Did we get a properly formatted logging bitmask? 1672 if (*p == ';') 1673 { 1674 // Enable DNB logging 1675 DNBLogSetLogCallback(ASLLogCallback, NULL); 1676 DNBLogSetLogMask (bitmask); 1677 p++; 1678 } 1679 } 1680 // We're not going to support logging to a file for now. All logging 1681 // goes through ASL. 1682#if 0 1683 else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0) 1684 { 1685 p += sizeof ("mode=") - 1; 1686 if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0) 1687 { 1688 DNBLogToASL (); 1689 p += sizeof ("asl;") - 1; 1690 } 1691 else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0) 1692 { 1693 DNBLogToFile (); 1694 p += sizeof ("file;") - 1; 1695 } 1696 else 1697 { 1698 // Ignore unknown argument 1699 const char *c = strchr (p, ';'); 1700 if (c) 1701 p = c + 1; 1702 else 1703 p = strchr (p, '\0'); 1704 } 1705 } 1706 else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0) 1707 { 1708 p += sizeof ("filename=") - 1; 1709 const char *c = strchr (p, ';'); 1710 if (c == NULL) 1711 { 1712 c = strchr (p, '\0'); 1713 continue; 1714 } 1715 char *fn = (char *) alloca (c - p + 1); 1716 strncpy (fn, p, c - p); 1717 fn[c - p] = '\0'; 1718 1719 // A file name of "asl" is special and is another way to indicate 1720 // that logging should be done via ASL, not by file. 1721 if (strcmp (fn, "asl") == 0) 1722 { 1723 DNBLogToASL (); 1724 } 1725 else 1726 { 1727 FILE *f = fopen (fn, "w"); 1728 if (f) 1729 { 1730 DNBLogSetLogFile (f); 1731 DNBEnableLogging (f, DNBLogGetLogMask ()); 1732 DNBLogToFile (); 1733 } 1734 } 1735 p = c + 1; 1736 } 1737#endif /* #if 0 to enforce ASL logging only. */ 1738 else 1739 { 1740 // Ignore unknown argument 1741 const char *c = strchr (p, ';'); 1742 if (c) 1743 p = c + 1; 1744 else 1745 p = strchr (p, '\0'); 1746 } 1747 } 1748 1749 return rnb_success; 1750} 1751 1752rnb_err_t 1753RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p) 1754{ 1755 m_thread_suffix_supported = true; 1756 return SendPacket ("OK"); 1757} 1758 1759rnb_err_t 1760RNBRemote::HandlePacket_QStartNoAckMode (const char *p) 1761{ 1762 // Send the OK packet first so the correct checksum is appended... 1763 rnb_err_t result = SendPacket ("OK"); 1764 m_noack_mode = true; 1765 return result; 1766} 1767 1768 1769rnb_err_t 1770RNBRemote::HandlePacket_QSetLogging (const char *p) 1771{ 1772 p += sizeof ("QSetLogging:") - 1; 1773 rnb_err_t result = set_logging (p); 1774 if (result == rnb_success) 1775 return SendPacket ("OK"); 1776 else 1777 return SendPacket ("E35"); 1778} 1779 1780rnb_err_t 1781RNBRemote::HandlePacket_QSetDisableASLR (const char *p) 1782{ 1783 extern int g_disable_aslr; 1784 p += sizeof ("QSetDisableASLR:") - 1; 1785 switch (*p) 1786 { 1787 case '0': g_disable_aslr = 0; break; 1788 case '1': g_disable_aslr = 1; break; 1789 default: 1790 return SendPacket ("E56"); 1791 } 1792 return SendPacket ("OK"); 1793} 1794 1795rnb_err_t 1796RNBRemote::HandlePacket_QSetSTDIO (const char *p) 1797{ 1798 // Only set stdin/out/err if we don't already have a process 1799 if (!m_ctx.HasValidProcessID()) 1800 { 1801 bool success = false; 1802 // Check the seventh character since the packet will be one of: 1803 // QSetSTDIN 1804 // QSetSTDOUT 1805 // QSetSTDERR 1806 StringExtractor packet(p); 1807 packet.SetFilePos (7); 1808 char ch = packet.GetChar(); 1809 while (packet.GetChar() != ':') 1810 /* Do nothing. */; 1811 1812 switch (ch) 1813 { 1814 case 'I': // STDIN 1815 packet.GetHexByteString (m_ctx.GetSTDIN()); 1816 success = !m_ctx.GetSTDIN().empty(); 1817 break; 1818 1819 case 'O': // STDOUT 1820 packet.GetHexByteString (m_ctx.GetSTDOUT()); 1821 success = !m_ctx.GetSTDOUT().empty(); 1822 break; 1823 1824 case 'E': // STDERR 1825 packet.GetHexByteString (m_ctx.GetSTDERR()); 1826 success = !m_ctx.GetSTDERR().empty(); 1827 break; 1828 1829 default: 1830 break; 1831 } 1832 if (success) 1833 return SendPacket ("OK"); 1834 return SendPacket ("E57"); 1835 } 1836 return SendPacket ("E58"); 1837} 1838 1839rnb_err_t 1840RNBRemote::HandlePacket_QSetWorkingDir (const char *p) 1841{ 1842 // Only set the working directory if we don't already have a process 1843 if (!m_ctx.HasValidProcessID()) 1844 { 1845 StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1); 1846 if (packet.GetHexByteString (m_ctx.GetWorkingDir())) 1847 { 1848 struct stat working_dir_stat; 1849 if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) 1850 { 1851 m_ctx.GetWorkingDir().clear(); 1852 return SendPacket ("E61"); // Working directory doesn't exist... 1853 } 1854 else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) 1855 { 1856 return SendPacket ("OK"); 1857 } 1858 else 1859 { 1860 m_ctx.GetWorkingDir().clear(); 1861 return SendPacket ("E62"); // Working directory isn't a directory... 1862 } 1863 } 1864 return SendPacket ("E59"); // Invalid path 1865 } 1866 return SendPacket ("E60"); // Already had a process, too late to set working dir 1867} 1868 1869 1870rnb_err_t 1871RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p) 1872{ 1873 /* The number of characters in a packet payload that gdb is 1874 prepared to accept. The packet-start char, packet-end char, 1875 2 checksum chars and terminating null character are not included 1876 in this size. */ 1877 p += sizeof ("QSetMaxPayloadSize:") - 1; 1878 errno = 0; 1879 uint32_t size = strtoul (p, NULL, 16); 1880 if (errno != 0 && size == 0) 1881 { 1882 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet"); 1883 } 1884 m_max_payload_size = size; 1885 return SendPacket ("OK"); 1886} 1887 1888rnb_err_t 1889RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p) 1890{ 1891 /* This tells us the largest packet that gdb can handle. 1892 i.e. the size of gdb's packet-reading buffer. 1893 QSetMaxPayloadSize is preferred because it is less ambiguous. */ 1894 p += sizeof ("QSetMaxPacketSize:") - 1; 1895 errno = 0; 1896 uint32_t size = strtoul (p, NULL, 16); 1897 if (errno != 0 && size == 0) 1898 { 1899 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet"); 1900 } 1901 m_max_payload_size = size - 5; 1902 return SendPacket ("OK"); 1903} 1904 1905 1906 1907 1908rnb_err_t 1909RNBRemote::HandlePacket_QEnvironment (const char *p) 1910{ 1911 /* This sets the environment for the target program. The packet is of the form: 1912 1913 QEnvironment:VARIABLE=VALUE 1914 1915 */ 1916 1917 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"", 1918 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 1919 1920 p += sizeof ("QEnvironment:") - 1; 1921 RNBContext& ctx = Context(); 1922 1923 ctx.PushEnvironment (p); 1924 return SendPacket ("OK"); 1925} 1926 1927rnb_err_t 1928RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p) 1929{ 1930 /* This sets the environment for the target program. The packet is of the form: 1931 1932 QEnvironmentHexEncoded:VARIABLE=VALUE 1933 1934 The VARIABLE=VALUE part is sent hex-encoded so chracters like '#' with special 1935 meaning in the remote protocol won't break it. 1936 */ 1937 1938 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"", 1939 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 1940 1941 p += sizeof ("QEnvironmentHexEncoded:") - 1; 1942 1943 std::string arg; 1944 const char *c; 1945 c = p; 1946 while (*c != '\0') 1947 { 1948 if (*(c + 1) == '\0') 1949 { 1950 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 1951 } 1952 char smallbuf[3]; 1953 smallbuf[0] = *c; 1954 smallbuf[1] = *(c + 1); 1955 smallbuf[2] = '\0'; 1956 errno = 0; 1957 int ch = strtoul (smallbuf, NULL, 16); 1958 if (errno != 0 && ch == 0) 1959 { 1960 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 1961 } 1962 arg.push_back(ch); 1963 c += 2; 1964 } 1965 1966 RNBContext& ctx = Context(); 1967 if (arg.length() > 0) 1968 ctx.PushEnvironment (arg.c_str()); 1969 1970 return SendPacket ("OK"); 1971} 1972 1973 1974rnb_err_t 1975RNBRemote::HandlePacket_QLaunchArch (const char *p) 1976{ 1977 p += sizeof ("QLaunchArch:") - 1; 1978 if (DNBSetArchitecture(p)) 1979 return SendPacket ("OK"); 1980 return SendPacket ("E63"); 1981} 1982 1983void 1984append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap) 1985{ 1986 int i; 1987 if (swap) 1988 { 1989 for (i = buf_size-1; i >= 0; i--) 1990 ostrm << RAWHEX8(buf[i]); 1991 } 1992 else 1993 { 1994 for (i = 0; i < buf_size; i++) 1995 ostrm << RAWHEX8(buf[i]); 1996 } 1997} 1998 1999 2000void 2001register_value_in_hex_fixed_width (std::ostream& ostrm, 2002 nub_process_t pid, 2003 nub_thread_t tid, 2004 const register_map_entry_t* reg) 2005{ 2006 if (reg != NULL) 2007 { 2008 DNBRegisterValue val; 2009 if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &val)) 2010 { 2011 append_hex_value (ostrm, val.value.v_uint8, reg->gdb_size, false); 2012 } 2013 else 2014 { 2015 // If we fail to read a regiser value, check if it has a default 2016 // fail value. If it does, return this instead in case some of 2017 // the registers are not available on the current system. 2018 if (reg->gdb_size > 0) 2019 { 2020 if (reg->fail_value != NULL) 2021 { 2022 append_hex_value (ostrm, reg->fail_value, reg->gdb_size, false); 2023 } 2024 else 2025 { 2026 std::basic_string<uint8_t> zeros(reg->gdb_size, '\0'); 2027 append_hex_value (ostrm, zeros.data(), zeros.size(), false); 2028 } 2029 } 2030 } 2031 } 2032} 2033 2034 2035void 2036gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm, 2037 nub_process_t pid, 2038 nub_thread_t tid, 2039 const register_map_entry_t* reg) 2040{ 2041 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX 2042 // gdb register number, and VVVVVVVV is the correct number of hex bytes 2043 // as ASCII for the register value. 2044 if (reg != NULL) 2045 { 2046 ostrm << RAWHEX8(reg->gdb_regnum) << ':'; 2047 register_value_in_hex_fixed_width (ostrm, pid, tid, reg); 2048 ostrm << ';'; 2049 } 2050} 2051 2052rnb_err_t 2053RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) 2054{ 2055 const nub_process_t pid = m_ctx.ProcessID(); 2056 if (pid == INVALID_NUB_PROCESS) 2057 return SendPacket("E50"); 2058 2059 struct DNBThreadStopInfo tid_stop_info; 2060 2061 /* Fill the remaining space in this packet with as many registers 2062 as we can stuff in there. */ 2063 2064 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) 2065 { 2066 std::ostringstream ostrm; 2067 // Output the T packet with the thread 2068 ostrm << 'T'; 2069 int signum = tid_stop_info.details.signal.signo; 2070 DNBLogThreadedIf (LOG_RNB_PROC, "%8d %s got signal signo = %u, exc_type = %u", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, signum, tid_stop_info.details.exception.type); 2071 2072 // Translate any mach exceptions to gdb versions, unless they are 2073 // common exceptions like a breakpoint or a soft signal. 2074 switch (tid_stop_info.details.exception.type) 2075 { 2076 default: signum = 0; break; 2077 case EXC_BREAKPOINT: signum = SIGTRAP; break; 2078 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break; 2079 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break; 2080 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break; 2081 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break; 2082 case EXC_SOFTWARE: 2083 if (tid_stop_info.details.exception.data_count == 2 && 2084 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2085 signum = tid_stop_info.details.exception.data[1]; 2086 else 2087 signum = TARGET_EXC_SOFTWARE; 2088 break; 2089 } 2090 2091 ostrm << RAWHEX8(signum & 0xff); 2092 2093 ostrm << std::hex << "thread:" << tid << ';'; 2094 2095 const char *thread_name = DNBThreadGetName (pid, tid); 2096 if (thread_name && thread_name[0]) 2097 { 2098 size_t thread_name_len = strlen(thread_name); 2099 2100 if (::strcspn (thread_name, "$#+-;:") == thread_name_len) 2101 ostrm << std::hex << "name:" << thread_name << ';'; 2102 else 2103 { 2104 // the thread name contains special chars, send as hex bytes 2105 ostrm << std::hex << "hexname:"; 2106 uint8_t *u_thread_name = (uint8_t *)thread_name; 2107 for (int i = 0; i < thread_name_len; i++) 2108 ostrm << RAWHEX8(u_thread_name[i]); 2109 ostrm << ';'; 2110 } 2111 } 2112 2113 thread_identifier_info_data_t thread_ident_info; 2114 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 2115 { 2116 if (thread_ident_info.dispatch_qaddr != 0) 2117 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';'; 2118 } 2119 if (g_num_reg_entries == 0) 2120 InitializeRegisters (); 2121 2122 DNBRegisterValue reg_value; 2123 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2124 { 2125 if (g_reg_entries[reg].expedite) 2126 { 2127 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 2128 continue; 2129 2130 gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg]); 2131 } 2132 } 2133 2134 if (tid_stop_info.details.exception.type) 2135 { 2136 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";"; 2137 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";"; 2138 for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i) 2139 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";"; 2140 } 2141 return SendPacket (ostrm.str ()); 2142 } 2143 return SendPacket("E51"); 2144} 2145 2146/* `?' 2147 The stop reply packet - tell gdb what the status of the inferior is. 2148 Often called the questionmark_packet. */ 2149 2150rnb_err_t 2151RNBRemote::HandlePacket_last_signal (const char *unused) 2152{ 2153 if (!m_ctx.HasValidProcessID()) 2154 { 2155 // Inferior is not yet specified/running 2156 return SendPacket ("E02"); 2157 } 2158 2159 nub_process_t pid = m_ctx.ProcessID(); 2160 nub_state_t pid_state = DNBProcessGetState (pid); 2161 2162 switch (pid_state) 2163 { 2164 case eStateAttaching: 2165 case eStateLaunching: 2166 case eStateRunning: 2167 case eStateStepping: 2168 case eStateDetached: 2169 return rnb_success; // Ignore 2170 2171 case eStateSuspended: 2172 case eStateStopped: 2173 case eStateCrashed: 2174 { 2175 nub_thread_t tid = DNBProcessGetCurrentThread (pid); 2176 // Make sure we set the current thread so g and p packets return 2177 // the data the gdb will expect. 2178 SetCurrentThread (tid); 2179 2180 SendStopReplyPacketForThread (tid); 2181 } 2182 break; 2183 2184 case eStateInvalid: 2185 case eStateUnloaded: 2186 case eStateExited: 2187 { 2188 char pid_exited_packet[16] = ""; 2189 int pid_status = 0; 2190 // Process exited with exit status 2191 if (!DNBProcessGetExitStatus(pid, &pid_status)) 2192 pid_status = 0; 2193 2194 if (pid_status) 2195 { 2196 if (WIFEXITED (pid_status)) 2197 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status)); 2198 else if (WIFSIGNALED (pid_status)) 2199 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status)); 2200 else if (WIFSTOPPED (pid_status)) 2201 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status)); 2202 } 2203 2204 // If we have an empty exit packet, lets fill one in to be safe. 2205 if (!pid_exited_packet[0]) 2206 { 2207 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1); 2208 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0'; 2209 } 2210 2211 return SendPacket (pid_exited_packet); 2212 } 2213 break; 2214 } 2215 return rnb_success; 2216} 2217 2218rnb_err_t 2219RNBRemote::HandlePacket_M (const char *p) 2220{ 2221 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2222 { 2223 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet"); 2224 } 2225 2226 char *c; 2227 p++; 2228 errno = 0; 2229 nub_addr_t addr = strtoull (p, &c, 16); 2230 if (errno != 0 && addr == 0) 2231 { 2232 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet"); 2233 } 2234 if (*c != ',') 2235 { 2236 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet"); 2237 } 2238 2239 /* Advance 'p' to the length part of the packet. */ 2240 p += (c - p) + 1; 2241 2242 errno = 0; 2243 uint32_t length = strtoul (p, &c, 16); 2244 if (errno != 0 && length == 0) 2245 { 2246 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet"); 2247 } 2248 if (length == 0) 2249 { 2250 return SendPacket ("OK"); 2251 } 2252 2253 if (*c != ':') 2254 { 2255 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet"); 2256 } 2257 /* Advance 'p' to the data part of the packet. */ 2258 p += (c - p) + 1; 2259 2260 int datalen = strlen (p); 2261 if (datalen & 0x1) 2262 { 2263 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet"); 2264 } 2265 if (datalen == 0) 2266 { 2267 return SendPacket ("OK"); 2268 } 2269 2270 uint8_t *buf = (uint8_t *) alloca (datalen / 2); 2271 uint8_t *i = buf; 2272 2273 while (*p != '\0' && *(p + 1) != '\0') 2274 { 2275 char hexbuf[3]; 2276 hexbuf[0] = *p; 2277 hexbuf[1] = *(p + 1); 2278 hexbuf[2] = '\0'; 2279 errno = 0; 2280 uint8_t byte = strtoul (hexbuf, NULL, 16); 2281 if (errno != 0 && byte == 0) 2282 { 2283 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet"); 2284 } 2285 *i++ = byte; 2286 p += 2; 2287 } 2288 2289 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf); 2290 if (wrote != length) 2291 return SendPacket ("E09"); 2292 else 2293 return SendPacket ("OK"); 2294} 2295 2296 2297rnb_err_t 2298RNBRemote::HandlePacket_m (const char *p) 2299{ 2300 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2301 { 2302 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet"); 2303 } 2304 2305 char *c; 2306 p++; 2307 errno = 0; 2308 nub_addr_t addr = strtoull (p, &c, 16); 2309 if (errno != 0 && addr == 0) 2310 { 2311 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet"); 2312 } 2313 if (*c != ',') 2314 { 2315 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet"); 2316 } 2317 2318 /* Advance 'p' to the length part of the packet. */ 2319 p += (c - p) + 1; 2320 2321 errno = 0; 2322 uint32_t length = strtoul (p, NULL, 16); 2323 if (errno != 0 && length == 0) 2324 { 2325 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2326 } 2327 if (length == 0) 2328 { 2329 return SendPacket (""); 2330 } 2331 2332 uint8_t buf[length]; 2333 int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf); 2334 if (bytes_read == 0) 2335 { 2336 return SendPacket ("E08"); 2337 } 2338 2339 // "The reply may contain fewer bytes than requested if the server was able 2340 // to read only part of the region of memory." 2341 length = bytes_read; 2342 2343 std::ostringstream ostrm; 2344 for (int i = 0; i < length; i++) 2345 ostrm << RAWHEX8(buf[i]); 2346 return SendPacket (ostrm.str ()); 2347} 2348 2349rnb_err_t 2350RNBRemote::HandlePacket_X (const char *p) 2351{ 2352 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2353 { 2354 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 2355 } 2356 2357 char *c; 2358 p++; 2359 errno = 0; 2360 nub_addr_t addr = strtoull (p, &c, 16); 2361 if (errno != 0 && addr == 0) 2362 { 2363 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 2364 } 2365 if (*c != ',') 2366 { 2367 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 2368 } 2369 2370 /* Advance 'p' to the length part of the packet. */ 2371 p += (c - p) + 1; 2372 2373 errno = 0; 2374 int length = strtoul (p, NULL, 16); 2375 if (errno != 0 && length == 0) 2376 { 2377 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2378 } 2379 2380 // I think gdb sends a zero length write request to test whether this 2381 // packet is accepted. 2382 if (length == 0) 2383 { 2384 return SendPacket ("OK"); 2385 } 2386 2387 std::vector<uint8_t> data = decode_binary_data (c, -1); 2388 std::vector<uint8_t>::const_iterator it; 2389 uint8_t *buf = (uint8_t *) alloca (data.size ()); 2390 uint8_t *i = buf; 2391 for (it = data.begin (); it != data.end (); ++it) 2392 { 2393 *i++ = *it; 2394 } 2395 2396 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf); 2397 if (wrote != data.size ()) 2398 return SendPacket ("E08"); 2399 return SendPacket ("OK"); 2400} 2401 2402/* `g' -- read registers 2403 Get the contents of the registers for the current thread, 2404 send them to gdb. 2405 Should the setting of the Hg packet determine which thread's registers 2406 are returned? */ 2407 2408rnb_err_t 2409RNBRemote::HandlePacket_g (const char *p) 2410{ 2411 std::ostringstream ostrm; 2412 if (!m_ctx.HasValidProcessID()) 2413 { 2414 return SendPacket ("E11"); 2415 } 2416 2417 if (g_num_reg_entries == 0) 2418 InitializeRegisters (); 2419 2420 nub_process_t pid = m_ctx.ProcessID (); 2421 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1); 2422 if (tid == INVALID_NUB_THREAD) 2423 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2424 2425 if (m_use_native_regs) 2426 { 2427 // Get the register context size first by calling with NULL buffer 2428 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2429 if (reg_ctx_size) 2430 { 2431 // Now allocate enough space for the entire register context 2432 std::vector<uint8_t> reg_ctx; 2433 reg_ctx.resize(reg_ctx_size); 2434 // Now read the register context 2435 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 2436 if (reg_ctx_size) 2437 { 2438 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false); 2439 return SendPacket (ostrm.str ()); 2440 } 2441 } 2442 } 2443 2444 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2445 register_value_in_hex_fixed_width (ostrm, pid, tid, &g_reg_entries[reg]); 2446 2447 return SendPacket (ostrm.str ()); 2448} 2449 2450/* `G XXX...' -- write registers 2451 How is the thread for these specified, beyond "the current thread"? 2452 Does gdb actually use the Hg packet to set this? */ 2453 2454rnb_err_t 2455RNBRemote::HandlePacket_G (const char *p) 2456{ 2457 if (!m_ctx.HasValidProcessID()) 2458 { 2459 return SendPacket ("E11"); 2460 } 2461 2462 if (g_num_reg_entries == 0) 2463 InitializeRegisters (); 2464 2465 StringExtractor packet(p); 2466 packet.SetFilePos(1); // Skip the 'G' 2467 2468 nub_process_t pid = m_ctx.ProcessID(); 2469 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2470 if (tid == INVALID_NUB_THREAD) 2471 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2472 2473 if (m_use_native_regs) 2474 { 2475 // Get the register context size first by calling with NULL buffer 2476 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2477 if (reg_ctx_size) 2478 { 2479 // Now allocate enough space for the entire register context 2480 std::vector<uint8_t> reg_ctx; 2481 reg_ctx.resize(reg_ctx_size); 2482 2483 if (packet.GetHexBytes (®_ctx[0], reg_ctx.size(), 0xcc) == reg_ctx.size()) 2484 { 2485 // Now write the register context 2486 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 2487 if (reg_ctx_size == reg_ctx.size()) 2488 return SendPacket ("OK"); 2489 else 2490 return SendPacket ("E55"); 2491 } 2492 } 2493 } 2494 2495 2496 DNBRegisterValue reg_value; 2497 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2498 { 2499 const register_map_entry_t *reg_entry = &g_reg_entries[reg]; 2500 2501 reg_value.info = reg_entry->nub_info; 2502 if (packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc) != reg_entry->gdb_size) 2503 break; 2504 2505 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 2506 return SendPacket ("E15"); 2507 } 2508 return SendPacket ("OK"); 2509} 2510 2511static bool 2512RNBRemoteShouldCancelCallback (void *not_used) 2513{ 2514 RNBRemoteSP remoteSP(g_remoteSP); 2515 if (remoteSP.get() != NULL) 2516 { 2517 RNBRemote* remote = remoteSP.get(); 2518 if (remote->Comm().IsConnected()) 2519 return false; 2520 else 2521 return true; 2522 } 2523 return true; 2524} 2525 2526 2527// FORMAT: _MXXXXXX,PPP 2528// XXXXXX: big endian hex chars 2529// PPP: permissions can be any combo of r w x chars 2530// 2531// RESPONSE: XXXXXX 2532// XXXXXX: hex address of the newly allocated memory 2533// EXX: error code 2534// 2535// EXAMPLES: 2536// _M123000,rw 2537// _M123000,rwx 2538// _M123000,xw 2539 2540rnb_err_t 2541RNBRemote::HandlePacket_AllocateMemory (const char *p) 2542{ 2543 StringExtractor packet (p); 2544 packet.SetFilePos(2); // Skip the "_M" 2545 2546 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0); 2547 if (size != 0) 2548 { 2549 if (packet.GetChar() == ',') 2550 { 2551 uint32_t permissions = 0; 2552 char ch; 2553 bool success = true; 2554 while (success && (ch = packet.GetChar()) != '\0') 2555 { 2556 switch (ch) 2557 { 2558 case 'r': permissions |= eMemoryPermissionsReadable; break; 2559 case 'w': permissions |= eMemoryPermissionsWritable; break; 2560 case 'x': permissions |= eMemoryPermissionsExecutable; break; 2561 default: success = false; break; 2562 } 2563 } 2564 2565 if (success) 2566 { 2567 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions); 2568 if (addr != INVALID_NUB_ADDRESS) 2569 { 2570 std::ostringstream ostrm; 2571 ostrm << RAW_HEXBASE << addr; 2572 return SendPacket (ostrm.str ()); 2573 } 2574 } 2575 } 2576 } 2577 return SendPacket ("E53"); 2578} 2579 2580// FORMAT: _mXXXXXX 2581// XXXXXX: address that was previosly allocated 2582// 2583// RESPONSE: XXXXXX 2584// OK: address was deallocated 2585// EXX: error code 2586// 2587// EXAMPLES: 2588// _m123000 2589 2590rnb_err_t 2591RNBRemote::HandlePacket_DeallocateMemory (const char *p) 2592{ 2593 StringExtractor packet (p); 2594 packet.SetFilePos(2); // Skip the "_m" 2595 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS); 2596 2597 if (addr != INVALID_NUB_ADDRESS) 2598 { 2599 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr)) 2600 return SendPacket ("OK"); 2601 } 2602 return SendPacket ("E54"); 2603} 2604 2605/* 2606 vAttach;pid 2607 2608 Attach to a new process with the specified process ID. pid is a hexadecimal integer 2609 identifying the process. If the stub is currently controlling a process, it is 2610 killed. The attached process is stopped.This packet is only available in extended 2611 mode (see extended mode). 2612 2613 Reply: 2614 "ENN" for an error 2615 "Any Stop Reply Packet" for success 2616 */ 2617 2618rnb_err_t 2619RNBRemote::HandlePacket_v (const char *p) 2620{ 2621 if (strcmp (p, "vCont;c") == 0) 2622 { 2623 // Simple continue 2624 return RNBRemote::HandlePacket_c("c"); 2625 } 2626 else if (strcmp (p, "vCont;s") == 0) 2627 { 2628 // Simple step 2629 return RNBRemote::HandlePacket_s("s"); 2630 } 2631 else if (strstr (p, "vCont") == p) 2632 { 2633 rnb_err_t rnb_err = rnb_success; 2634 typedef struct 2635 { 2636 nub_thread_t tid; 2637 char action; 2638 int signal; 2639 } vcont_action_t; 2640 2641 DNBThreadResumeActions thread_actions; 2642 char *c = (char *)(p += strlen("vCont")); 2643 char *c_end = c + strlen(c); 2644 if (*c == '?') 2645 return SendPacket ("vCont;c;C;s;S"); 2646 2647 while (c < c_end && *c == ';') 2648 { 2649 ++c; // Skip the semi-colon 2650 DNBThreadResumeAction thread_action; 2651 thread_action.tid = INVALID_NUB_THREAD; 2652 thread_action.state = eStateInvalid; 2653 thread_action.signal = 0; 2654 thread_action.addr = INVALID_NUB_ADDRESS; 2655 2656 char action = *c++; 2657 2658 switch (action) 2659 { 2660 case 'C': 2661 errno = 0; 2662 thread_action.signal = strtoul (c, &c, 16); 2663 if (errno != 0) 2664 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2665 // Fall through to next case... 2666 2667 case 'c': 2668 // Continue 2669 thread_action.state = eStateRunning; 2670 break; 2671 2672 case 'S': 2673 errno = 0; 2674 thread_action.signal = strtoul (c, &c, 16); 2675 if (errno != 0) 2676 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2677 // Fall through to next case... 2678 2679 case 's': 2680 // Step 2681 thread_action.state = eStateStepping; 2682 break; 2683 2684 break; 2685 2686 default: 2687 rnb_err = HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet"); 2688 break; 2689 } 2690 if (*c == ':') 2691 { 2692 errno = 0; 2693 thread_action.tid = strtoul (++c, &c, 16); 2694 if (errno != 0) 2695 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet"); 2696 } 2697 2698 thread_actions.Append (thread_action); 2699 } 2700 2701 // If a default action for all other threads wasn't mentioned 2702 // then we should stop the threads 2703 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 2704 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize()); 2705 return rnb_success; 2706 } 2707 else if (strstr (p, "vAttach") == p) 2708 { 2709 nub_process_t attach_pid = INVALID_NUB_PROCESS; 2710 char err_str[1024]={'\0'}; 2711 if (strstr (p, "vAttachWait;") == p) 2712 { 2713 p += strlen("vAttachWait;"); 2714 std::string attach_name; 2715 while (*p != '\0') 2716 { 2717 char smallbuf[3]; 2718 smallbuf[0] = *p; 2719 smallbuf[1] = *(p + 1); 2720 smallbuf[2] = '\0'; 2721 2722 errno = 0; 2723 int ch = strtoul (smallbuf, NULL, 16); 2724 if (errno != 0 && ch == 0) 2725 { 2726 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 2727 } 2728 2729 attach_name.push_back(ch); 2730 p += 2; 2731 } 2732 2733 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 2734 2735 } 2736 else if (strstr (p, "vAttachName;") == p) 2737 { 2738 p += strlen("vAttachName;"); 2739 std::string attach_name; 2740 while (*p != '\0') 2741 { 2742 char smallbuf[3]; 2743 smallbuf[0] = *p; 2744 smallbuf[1] = *(p + 1); 2745 smallbuf[2] = '\0'; 2746 2747 errno = 0; 2748 int ch = strtoul (smallbuf, NULL, 16); 2749 if (errno != 0 && ch == 0) 2750 { 2751 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 2752 } 2753 2754 attach_name.push_back(ch); 2755 p += 2; 2756 } 2757 2758 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str)); 2759 2760 } 2761 else if (strstr (p, "vAttach;") == p) 2762 { 2763 p += strlen("vAttach;"); 2764 char *end = NULL; 2765 attach_pid = strtoul (p, &end, 16); // PID will be in hex, so use base 16 to decode 2766 if (p != end && *end == '\0') 2767 { 2768 // Wait at most 30 second for attach 2769 struct timespec attach_timeout_abstime; 2770 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 2771 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str)); 2772 } 2773 } 2774 else 2775 return HandlePacket_UNIMPLEMENTED(p); 2776 2777 2778 if (attach_pid != INVALID_NUB_PROCESS) 2779 { 2780 if (m_ctx.ProcessID() != attach_pid) 2781 m_ctx.SetProcessID(attach_pid); 2782 // Send a stop reply packet to indicate we successfully attached! 2783 NotifyThatProcessStopped (); 2784 return rnb_success; 2785 } 2786 else 2787 { 2788 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 2789 if (err_str[0]) 2790 m_ctx.LaunchStatus().SetErrorString(err_str); 2791 else 2792 m_ctx.LaunchStatus().SetErrorString("attach failed"); 2793 return SendPacket ("E01"); // E01 is our magic error value for attach failed. 2794 } 2795 } 2796 2797 // All other failures come through here 2798 return HandlePacket_UNIMPLEMENTED(p); 2799} 2800 2801/* `T XX' -- status of thread 2802 Check if the specified thread is alive. 2803 The thread number is in hex? */ 2804 2805rnb_err_t 2806RNBRemote::HandlePacket_T (const char *p) 2807{ 2808 p++; 2809 if (p == NULL || *p == '\0') 2810 { 2811 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet"); 2812 } 2813 if (!m_ctx.HasValidProcessID()) 2814 { 2815 return SendPacket ("E15"); 2816 } 2817 errno = 0; 2818 nub_thread_t tid = strtoul (p, NULL, 16); 2819 if (errno != 0 && tid == 0) 2820 { 2821 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet"); 2822 } 2823 2824 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid); 2825 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) 2826 { 2827 return SendPacket ("E16"); 2828 } 2829 2830 return SendPacket ("OK"); 2831} 2832 2833 2834rnb_err_t 2835RNBRemote::HandlePacket_z (const char *p) 2836{ 2837 if (p == NULL || *p == '\0') 2838 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet"); 2839 2840 if (!m_ctx.HasValidProcessID()) 2841 return SendPacket ("E15"); 2842 2843 char packet_cmd = *p++; 2844 char break_type = *p++; 2845 2846 if (*p++ != ',') 2847 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 2848 2849 char *c = NULL; 2850 nub_process_t pid = m_ctx.ProcessID(); 2851 errno = 0; 2852 nub_addr_t addr = strtoull (p, &c, 16); 2853 if (errno != 0 && addr == 0) 2854 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet"); 2855 p = c; 2856 if (*p++ != ',') 2857 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 2858 2859 errno = 0; 2860 uint32_t byte_size = strtoul (p, &c, 16); 2861 if (errno != 0 && byte_size == 0) 2862 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet"); 2863 2864 if (packet_cmd == 'Z') 2865 { 2866 // set 2867 switch (break_type) 2868 { 2869 case '0': // set software breakpoint 2870 case '1': // set hardware breakpoint 2871 { 2872 // gdb can send multiple Z packets for the same address and 2873 // these calls must be ref counted. 2874 bool hardware = (break_type == '1'); 2875 2876 // Check if we currently have a breakpoint already set at this address 2877 BreakpointMapIter pos = m_breakpoints.find(addr); 2878 if (pos != m_breakpoints.end()) 2879 { 2880 // We do already have a breakpoint at this address, increment 2881 // its reference count and return OK 2882 pos->second.Retain(); 2883 return SendPacket ("OK"); 2884 } 2885 else 2886 { 2887 // We do NOT already have a breakpoint at this address, So lets 2888 // create one. 2889 nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware); 2890 if (break_id != INVALID_NUB_BREAK_ID) 2891 { 2892 // We successfully created a breakpoint, now lets full out 2893 // a ref count structure with the breakID and add it to our 2894 // map. 2895 Breakpoint rnbBreakpoint(break_id); 2896 m_breakpoints[addr] = rnbBreakpoint; 2897 return SendPacket ("OK"); 2898 } 2899 else 2900 { 2901 // We failed to set the software breakpoint 2902 return SendPacket ("E09"); 2903 } 2904 } 2905 } 2906 break; 2907 2908 case '2': // set write watchpoint 2909 case '3': // set read watchpoint 2910 case '4': // set access watchpoint 2911 { 2912 bool hardware = true; 2913 uint32_t watch_flags = 0; 2914 if (break_type == '2') 2915 watch_flags = WATCH_TYPE_WRITE; 2916 else if (break_type == '3') 2917 watch_flags = WATCH_TYPE_READ; 2918 else 2919 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 2920 2921 // Check if we currently have a watchpoint already set at this address 2922 BreakpointMapIter pos = m_watchpoints.find(addr); 2923 if (pos != m_watchpoints.end()) 2924 { 2925 // We do already have a watchpoint at this address, increment 2926 // its reference count and return OK 2927 pos->second.Retain(); 2928 return SendPacket ("OK"); 2929 } 2930 else 2931 { 2932 // We do NOT already have a breakpoint at this address, So lets 2933 // create one. 2934 nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware); 2935 if (watch_id != INVALID_NUB_BREAK_ID) 2936 { 2937 // We successfully created a watchpoint, now lets full out 2938 // a ref count structure with the watch_id and add it to our 2939 // map. 2940 Breakpoint rnbWatchpoint(watch_id); 2941 m_watchpoints[addr] = rnbWatchpoint; 2942 return SendPacket ("OK"); 2943 } 2944 else 2945 { 2946 // We failed to set the watchpoint 2947 return SendPacket ("E09"); 2948 } 2949 } 2950 } 2951 break; 2952 2953 default: 2954 break; 2955 } 2956 } 2957 else if (packet_cmd == 'z') 2958 { 2959 // remove 2960 switch (break_type) 2961 { 2962 case '0': // remove software breakpoint 2963 case '1': // remove hardware breakpoint 2964 { 2965 // gdb can send multiple z packets for the same address and 2966 // these calls must be ref counted. 2967 BreakpointMapIter pos = m_breakpoints.find(addr); 2968 if (pos != m_breakpoints.end()) 2969 { 2970 // We currently have a breakpoint at address ADDR. Decrement 2971 // its reference count, and it that count is now zero we 2972 // can clear the breakpoint. 2973 pos->second.Release(); 2974 if (pos->second.RefCount() == 0) 2975 { 2976 if (DNBBreakpointClear (pid, pos->second.BreakID())) 2977 { 2978 m_breakpoints.erase(pos); 2979 return SendPacket ("OK"); 2980 } 2981 else 2982 { 2983 return SendPacket ("E08"); 2984 } 2985 } 2986 else 2987 { 2988 // We still have references to this breakpoint don't 2989 // delete it, just decrementing the reference count 2990 // is enough. 2991 return SendPacket ("OK"); 2992 } 2993 } 2994 else 2995 { 2996 // We don't know about any breakpoints at this address 2997 return SendPacket ("E08"); 2998 } 2999 } 3000 break; 3001 3002 case '2': // remove write watchpoint 3003 case '3': // remove read watchpoint 3004 case '4': // remove access watchpoint 3005 { 3006 // gdb can send multiple z packets for the same address and 3007 // these calls must be ref counted. 3008 BreakpointMapIter pos = m_watchpoints.find(addr); 3009 if (pos != m_watchpoints.end()) 3010 { 3011 // We currently have a watchpoint at address ADDR. Decrement 3012 // its reference count, and it that count is now zero we 3013 // can clear the watchpoint. 3014 pos->second.Release(); 3015 if (pos->second.RefCount() == 0) 3016 { 3017 if (DNBWatchpointClear (pid, pos->second.BreakID())) 3018 { 3019 m_watchpoints.erase(pos); 3020 return SendPacket ("OK"); 3021 } 3022 else 3023 { 3024 return SendPacket ("E08"); 3025 } 3026 } 3027 else 3028 { 3029 // We still have references to this watchpoint don't 3030 // delete it, just decrementing the reference count 3031 // is enough. 3032 return SendPacket ("OK"); 3033 } 3034 } 3035 else 3036 { 3037 // We don't know about any watchpoints at this address 3038 return SendPacket ("E08"); 3039 } 3040 } 3041 break; 3042 3043 default: 3044 break; 3045 } 3046 } 3047 return HandlePacket_UNIMPLEMENTED(p); 3048} 3049 3050// Extract the thread number from the thread suffix that might be appended to 3051// thread specific packets. This will only be enabled if m_thread_suffix_supported 3052// is true. 3053nub_thread_t 3054RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p) 3055{ 3056 if (m_thread_suffix_supported) 3057 { 3058 nub_thread_t tid = INVALID_NUB_THREAD; 3059 if (p) 3060 { 3061 const char *tid_cstr = strstr (p, "thread:"); 3062 if (tid_cstr) 3063 { 3064 tid_cstr += strlen ("thread:"); 3065 tid = strtoul(tid_cstr, NULL, 16); 3066 } 3067 } 3068 return tid; 3069 } 3070 return GetCurrentThread(); 3071 3072} 3073 3074/* `p XX' 3075 print the contents of register X */ 3076 3077rnb_err_t 3078RNBRemote::HandlePacket_p (const char *p) 3079{ 3080 if (g_num_reg_entries == 0) 3081 InitializeRegisters (); 3082 3083 if (p == NULL || *p == '\0') 3084 { 3085 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3086 } 3087 if (!m_ctx.HasValidProcessID()) 3088 { 3089 return SendPacket ("E15"); 3090 } 3091 nub_process_t pid = m_ctx.ProcessID(); 3092 errno = 0; 3093 char *tid_cstr = NULL; 3094 uint32_t reg = strtoul (p + 1, &tid_cstr, 16); 3095 if (errno != 0 && reg == 0) 3096 { 3097 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet"); 3098 } 3099 3100 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr); 3101 if (tid == INVALID_NUB_THREAD) 3102 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3103 3104 const register_map_entry_t *reg_entry; 3105 3106 if (reg < g_num_reg_entries) 3107 reg_entry = &g_reg_entries[reg]; 3108 else 3109 reg_entry = NULL; 3110 3111 std::ostringstream ostrm; 3112 if (reg_entry == NULL) 3113 { 3114 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg); 3115 ostrm << "00000000"; 3116 } 3117 else if (reg_entry->nub_info.reg == -1) 3118 { 3119 if (reg_entry->gdb_size > 0) 3120 { 3121 if (reg_entry->fail_value != NULL) 3122 { 3123 append_hex_value(ostrm, reg_entry->fail_value, reg_entry->gdb_size, false); 3124 } 3125 else 3126 { 3127 std::basic_string<uint8_t> zeros(reg_entry->gdb_size, '\0'); 3128 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 3129 } 3130 } 3131 } 3132 else 3133 { 3134 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry); 3135 } 3136 return SendPacket (ostrm.str()); 3137} 3138 3139/* `Pnn=rrrrr' 3140 Set register number n to value r. 3141 n and r are hex strings. */ 3142 3143rnb_err_t 3144RNBRemote::HandlePacket_P (const char *p) 3145{ 3146 if (g_num_reg_entries == 0) 3147 InitializeRegisters (); 3148 3149 if (p == NULL || *p == '\0') 3150 { 3151 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet"); 3152 } 3153 if (!m_ctx.HasValidProcessID()) 3154 { 3155 return SendPacket ("E28"); 3156 } 3157 3158 nub_process_t pid = m_ctx.ProcessID(); 3159 3160 StringExtractor packet (p); 3161 3162 const char cmd_char = packet.GetChar(); 3163 // Register ID is always in big endian 3164 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX); 3165 const char equal_char = packet.GetChar(); 3166 3167 if (cmd_char != 'P') 3168 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet"); 3169 3170 if (reg == UINT32_MAX) 3171 return SendPacket ("E29"); 3172 3173 if (equal_char != '=') 3174 return SendPacket ("E30"); 3175 3176 const register_map_entry_t *reg_entry; 3177 3178 if (reg >= g_num_reg_entries) 3179 return SendPacket("E47"); 3180 3181 reg_entry = &g_reg_entries[reg]; 3182 3183 if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1) 3184 { 3185 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); 3186 return SendPacket("E48"); 3187 } 3188 3189 DNBRegisterValue reg_value; 3190 reg_value.info = reg_entry->nub_info; 3191 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc); 3192 3193 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3194 if (tid == INVALID_NUB_THREAD) 3195 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3196 3197 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 3198 { 3199 return SendPacket ("E32"); 3200 } 3201 return SendPacket ("OK"); 3202} 3203 3204/* `c [addr]' 3205 Continue, optionally from a specified address. */ 3206 3207rnb_err_t 3208RNBRemote::HandlePacket_c (const char *p) 3209{ 3210 const nub_process_t pid = m_ctx.ProcessID(); 3211 3212 if (pid == INVALID_NUB_PROCESS) 3213 return SendPacket ("E23"); 3214 3215 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3216 3217 if (*(p + 1) != '\0') 3218 { 3219 action.tid = GetContinueThread(); 3220 errno = 0; 3221 action.addr = strtoull (p + 1, NULL, 16); 3222 if (errno != 0 && action.addr == 0) 3223 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet"); 3224 } 3225 3226 DNBThreadResumeActions thread_actions; 3227 thread_actions.Append(action); 3228 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 3229 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3230 return SendPacket ("E25"); 3231 // Don't send an "OK" packet; response is the stopped/exited message. 3232 return rnb_success; 3233} 3234 3235/* `C sig [;addr]' 3236 Resume with signal sig, optionally at address addr. */ 3237 3238rnb_err_t 3239RNBRemote::HandlePacket_C (const char *p) 3240{ 3241 const nub_process_t pid = m_ctx.ProcessID(); 3242 3243 if (pid == INVALID_NUB_PROCESS) 3244 return SendPacket ("E36"); 3245 3246 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3247 int process_signo = -1; 3248 if (*(p + 1) != '\0') 3249 { 3250 action.tid = GetContinueThread(); 3251 char *end = NULL; 3252 errno = 0; 3253 process_signo = strtoul (p + 1, &end, 16); 3254 if (errno != 0) 3255 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet"); 3256 else if (*end == ';') 3257 { 3258 errno = 0; 3259 action.addr = strtoull (end + 1, NULL, 16); 3260 if (errno != 0 && action.addr == 0) 3261 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet"); 3262 } 3263 } 3264 3265 DNBThreadResumeActions thread_actions; 3266 thread_actions.Append (action); 3267 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal); 3268 if (!DNBProcessSignal(pid, process_signo)) 3269 return SendPacket ("E52"); 3270 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3271 return SendPacket ("E38"); 3272 /* Don't send an "OK" packet; response is the stopped/exited message. */ 3273 return rnb_success; 3274} 3275 3276//---------------------------------------------------------------------- 3277// 'D' packet 3278// Detach from gdb. 3279//---------------------------------------------------------------------- 3280rnb_err_t 3281RNBRemote::HandlePacket_D (const char *p) 3282{ 3283 // We are not supposed to send a response for deatch. 3284 //SendPacket ("OK"); 3285 if (m_ctx.HasValidProcessID()) 3286 DNBProcessDetach(m_ctx.ProcessID()); 3287 return rnb_success; 3288} 3289 3290/* `k' 3291 Kill the inferior process. */ 3292 3293rnb_err_t 3294RNBRemote::HandlePacket_k (const char *p) 3295{ 3296 // No response to should be sent to the kill packet 3297 if (m_ctx.HasValidProcessID()) 3298 DNBProcessKill (m_ctx.ProcessID()); 3299 SendPacket ("W09"); 3300 return rnb_success; 3301} 3302 3303rnb_err_t 3304RNBRemote::HandlePacket_stop_process (const char *p) 3305{ 3306 DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP); 3307 //DNBProcessSignal (m_ctx.ProcessID(), SIGINT); 3308 // Do not send any response packet! Wait for the stop reply packet to naturally happen 3309 return rnb_success; 3310} 3311 3312/* `s' 3313 Step the inferior process. */ 3314 3315rnb_err_t 3316RNBRemote::HandlePacket_s (const char *p) 3317{ 3318 const nub_process_t pid = m_ctx.ProcessID(); 3319 if (pid == INVALID_NUB_PROCESS) 3320 return SendPacket ("E32"); 3321 3322 // Hardware supported stepping not supported on arm 3323 nub_thread_t tid = GetContinueThread (); 3324 if (tid == 0 || tid == -1) 3325 tid = GetCurrentThread(); 3326 3327 if (tid == INVALID_NUB_THREAD) 3328 return SendPacket ("E33"); 3329 3330 DNBThreadResumeActions thread_actions; 3331 thread_actions.AppendAction(tid, eStateStepping); 3332 3333 // Make all other threads stop when we are stepping 3334 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3335 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3336 return SendPacket ("E49"); 3337 // Don't send an "OK" packet; response is the stopped/exited message. 3338 return rnb_success; 3339} 3340 3341/* `S sig [;addr]' 3342 Step with signal sig, optionally at address addr. */ 3343 3344rnb_err_t 3345RNBRemote::HandlePacket_S (const char *p) 3346{ 3347 const nub_process_t pid = m_ctx.ProcessID(); 3348 if (pid == INVALID_NUB_PROCESS) 3349 return SendPacket ("E36"); 3350 3351 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 3352 3353 if (*(p + 1) != '\0') 3354 { 3355 char *end = NULL; 3356 errno = 0; 3357 action.signal = strtoul (p + 1, &end, 16); 3358 if (errno != 0) 3359 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 3360 else if (*end == ';') 3361 { 3362 errno = 0; 3363 action.addr = strtoull (end + 1, NULL, 16); 3364 if (errno != 0 && action.addr == 0) 3365 { 3366 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 3367 } 3368 } 3369 } 3370 3371 action.tid = GetContinueThread (); 3372 if (action.tid == 0 || action.tid == -1) 3373 return SendPacket ("E40"); 3374 3375 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 3376 if (tstate == eStateInvalid || tstate == eStateExited) 3377 return SendPacket ("E37"); 3378 3379 3380 DNBThreadResumeActions thread_actions; 3381 thread_actions.Append (action); 3382 3383 // Make all other threads stop when we are stepping 3384 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3385 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3386 return SendPacket ("E39"); 3387 3388 // Don't send an "OK" packet; response is the stopped/exited message. 3389 return rnb_success; 3390} 3391 3392rnb_err_t 3393RNBRemote::HandlePacket_qHostInfo (const char *p) 3394{ 3395 std::ostringstream strm; 3396 3397 uint32_t cputype, is_64_bit_capable; 3398 size_t len = sizeof(cputype); 3399 bool promoted_to_64 = false; 3400 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 3401 { 3402 len = sizeof (is_64_bit_capable); 3403 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 3404 { 3405 if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0)) 3406 { 3407 promoted_to_64 = true; 3408 cputype |= CPU_ARCH_ABI64; 3409 } 3410 } 3411 3412 strm << "cputype:" << std::dec << cputype << ';'; 3413 } 3414 3415 uint32_t cpusubtype; 3416 len = sizeof(cpusubtype); 3417 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 3418 { 3419 if (promoted_to_64 && 3420 cputype == CPU_TYPE_X86_64 && 3421 cpusubtype == CPU_SUBTYPE_486) 3422 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3423 3424 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 3425 } 3426 3427 char ostype[64]; 3428 len = sizeof(ostype); 3429 if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 3430 { 3431 len = strlen(ostype); 3432 std::transform (ostype, ostype + len, ostype, tolower); 3433 strm << "ostype:" << std::dec << ostype << ';'; 3434 } 3435 3436 strm << "vendor:apple;"; 3437 3438#if defined (__LITTLE_ENDIAN__) 3439 strm << "endian:little;"; 3440#elif defined (__BIG_ENDIAN__) 3441 strm << "endian:big;"; 3442#elif defined (__PDP_ENDIAN__) 3443 strm << "endian:pdp;"; 3444#endif 3445 3446 if (promoted_to_64) 3447 strm << "ptrsize:8;"; 3448 else 3449 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 3450 return SendPacket (strm.str()); 3451} 3452