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