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