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