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