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