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