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