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