RNBRemote.cpp revision 679ba16fbf2be2ef93d3c654e2639ab0cb32c598
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_SetEnableAsyncProfiling, NULL, "QSetEnableAsyncProfiling", "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 if (reg_entry->nub_info.pseudo_regs && reg_entry->nub_info.pseudo_regs[0] != INVALID_NUB_REGNUM) 1557 { 1558 ostrm << "container-regs:"; 1559 for (unsigned i=0; reg_entry->nub_info.pseudo_regs[i] != INVALID_NUB_REGNUM; ++i) 1560 { 1561 if (i > 0) 1562 ostrm << ','; 1563 ostrm << DECIMAL << reg_entry->nub_info.pseudo_regs[i]; 1564 } 1565 ostrm << ';'; 1566 } 1567 1568 if (reg_entry->nub_info.update_regs && reg_entry->nub_info.update_regs[0] != INVALID_NUB_REGNUM) 1569 { 1570 ostrm << "invalidate-regs:"; 1571 for (unsigned i=0; reg_entry->nub_info.update_regs[i] != INVALID_NUB_REGNUM; ++i) 1572 { 1573 if (i > 0) 1574 ostrm << ','; 1575 ostrm << RAW_HEXBASE << reg_entry->nub_info.update_regs[i]; 1576 } 1577 ostrm << ';'; 1578 } 1579 1580 return SendPacket (ostrm.str ()); 1581 } 1582 return SendPacket ("E45"); 1583} 1584 1585 1586/* This expects a packet formatted like 1587 1588 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE; 1589 1590 with the "QSetLogging:" already removed from the start. Maybe in the 1591 future this packet will include other keyvalue pairs like 1592 1593 QSetLogging:bitmask=LOG_ALL;mode=asl; 1594 */ 1595 1596rnb_err_t 1597set_logging (const char *p) 1598{ 1599 int bitmask = 0; 1600 while (p && *p != '\0') 1601 { 1602 if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0) 1603 { 1604 p += sizeof ("bitmask=") - 1; 1605 while (p && *p != '\0' && *p != ';') 1606 { 1607 if (*p == '|') 1608 p++; 1609 1610// to regenerate the LOG_ entries (not including the LOG_RNB entries) 1611// $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'` 1612// do 1613// echo " else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)" 1614// echo " {" 1615// echo " p += sizeof (\"$logname\") - 1;" 1616// echo " bitmask |= $logname;" 1617// echo " }" 1618// done 1619 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0) 1620 { 1621 p += sizeof ("LOG_VERBOSE") - 1; 1622 bitmask |= LOG_VERBOSE; 1623 } 1624 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0) 1625 { 1626 p += sizeof ("LOG_PROCESS") - 1; 1627 bitmask |= LOG_PROCESS; 1628 } 1629 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0) 1630 { 1631 p += sizeof ("LOG_THREAD") - 1; 1632 bitmask |= LOG_THREAD; 1633 } 1634 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0) 1635 { 1636 p += sizeof ("LOG_EXCEPTIONS") - 1; 1637 bitmask |= LOG_EXCEPTIONS; 1638 } 1639 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0) 1640 { 1641 p += sizeof ("LOG_SHLIB") - 1; 1642 bitmask |= LOG_SHLIB; 1643 } 1644 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0) 1645 { 1646 p += sizeof ("LOG_MEMORY") - 1; 1647 bitmask |= LOG_MEMORY; 1648 } 1649 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0) 1650 { 1651 p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1; 1652 bitmask |= LOG_MEMORY_DATA_SHORT; 1653 } 1654 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0) 1655 { 1656 p += sizeof ("LOG_MEMORY_DATA_LONG") - 1; 1657 bitmask |= LOG_MEMORY_DATA_LONG; 1658 } 1659 else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0) 1660 { 1661 p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1; 1662 bitmask |= LOG_MEMORY_PROTECTIONS; 1663 } 1664 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0) 1665 { 1666 p += sizeof ("LOG_BREAKPOINTS") - 1; 1667 bitmask |= LOG_BREAKPOINTS; 1668 } 1669 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0) 1670 { 1671 p += sizeof ("LOG_EVENTS") - 1; 1672 bitmask |= LOG_EVENTS; 1673 } 1674 else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0) 1675 { 1676 p += sizeof ("LOG_WATCHPOINTS") - 1; 1677 bitmask |= LOG_WATCHPOINTS; 1678 } 1679 else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0) 1680 { 1681 p += sizeof ("LOG_STEP") - 1; 1682 bitmask |= LOG_STEP; 1683 } 1684 else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0) 1685 { 1686 p += sizeof ("LOG_TASK") - 1; 1687 bitmask |= LOG_TASK; 1688 } 1689 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0) 1690 { 1691 p += sizeof ("LOG_ALL") - 1; 1692 bitmask |= LOG_ALL; 1693 } 1694 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0) 1695 { 1696 p += sizeof ("LOG_DEFAULT") - 1; 1697 bitmask |= LOG_DEFAULT; 1698 } 1699// end of auto-generated entries 1700 1701 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0) 1702 { 1703 p += sizeof ("LOG_NONE") - 1; 1704 bitmask = 0; 1705 } 1706 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0) 1707 { 1708 p += sizeof ("LOG_RNB_MINIMAL") - 1; 1709 bitmask |= LOG_RNB_MINIMAL; 1710 } 1711 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0) 1712 { 1713 p += sizeof ("LOG_RNB_MEDIUM") - 1; 1714 bitmask |= LOG_RNB_MEDIUM; 1715 } 1716 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0) 1717 { 1718 p += sizeof ("LOG_RNB_MAX") - 1; 1719 bitmask |= LOG_RNB_MAX; 1720 } 1721 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0) 1722 { 1723 p += sizeof ("LOG_RNB_COMM") - 1; 1724 bitmask |= LOG_RNB_COMM; 1725 } 1726 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0) 1727 { 1728 p += sizeof ("LOG_RNB_REMOTE") - 1; 1729 bitmask |= LOG_RNB_REMOTE; 1730 } 1731 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0) 1732 { 1733 p += sizeof ("LOG_RNB_EVENTS") - 1; 1734 bitmask |= LOG_RNB_EVENTS; 1735 } 1736 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0) 1737 { 1738 p += sizeof ("LOG_RNB_PROC") - 1; 1739 bitmask |= LOG_RNB_PROC; 1740 } 1741 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0) 1742 { 1743 p += sizeof ("LOG_RNB_PACKETS") - 1; 1744 bitmask |= LOG_RNB_PACKETS; 1745 } 1746 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0) 1747 { 1748 p += sizeof ("LOG_RNB_ALL") - 1; 1749 bitmask |= LOG_RNB_ALL; 1750 } 1751 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0) 1752 { 1753 p += sizeof ("LOG_RNB_DEFAULT") - 1; 1754 bitmask |= LOG_RNB_DEFAULT; 1755 } 1756 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0) 1757 { 1758 p += sizeof ("LOG_RNB_NONE") - 1; 1759 bitmask = 0; 1760 } 1761 else 1762 { 1763 /* Unrecognized logging bit; ignore it. */ 1764 const char *c = strchr (p, '|'); 1765 if (c) 1766 { 1767 p = c; 1768 } 1769 else 1770 { 1771 c = strchr (p, ';'); 1772 if (c) 1773 { 1774 p = c; 1775 } 1776 else 1777 { 1778 // Improperly terminated word; just go to end of str 1779 p = strchr (p, '\0'); 1780 } 1781 } 1782 } 1783 } 1784 // Did we get a properly formatted logging bitmask? 1785 if (p && *p == ';') 1786 { 1787 // Enable DNB logging 1788 DNBLogSetLogCallback(ASLLogCallback, NULL); 1789 DNBLogSetLogMask (bitmask); 1790 p++; 1791 } 1792 } 1793 // We're not going to support logging to a file for now. All logging 1794 // goes through ASL. 1795#if 0 1796 else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0) 1797 { 1798 p += sizeof ("mode=") - 1; 1799 if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0) 1800 { 1801 DNBLogToASL (); 1802 p += sizeof ("asl;") - 1; 1803 } 1804 else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0) 1805 { 1806 DNBLogToFile (); 1807 p += sizeof ("file;") - 1; 1808 } 1809 else 1810 { 1811 // Ignore unknown argument 1812 const char *c = strchr (p, ';'); 1813 if (c) 1814 p = c + 1; 1815 else 1816 p = strchr (p, '\0'); 1817 } 1818 } 1819 else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0) 1820 { 1821 p += sizeof ("filename=") - 1; 1822 const char *c = strchr (p, ';'); 1823 if (c == NULL) 1824 { 1825 c = strchr (p, '\0'); 1826 continue; 1827 } 1828 char *fn = (char *) alloca (c - p + 1); 1829 strncpy (fn, p, c - p); 1830 fn[c - p] = '\0'; 1831 1832 // A file name of "asl" is special and is another way to indicate 1833 // that logging should be done via ASL, not by file. 1834 if (strcmp (fn, "asl") == 0) 1835 { 1836 DNBLogToASL (); 1837 } 1838 else 1839 { 1840 FILE *f = fopen (fn, "w"); 1841 if (f) 1842 { 1843 DNBLogSetLogFile (f); 1844 DNBEnableLogging (f, DNBLogGetLogMask ()); 1845 DNBLogToFile (); 1846 } 1847 } 1848 p = c + 1; 1849 } 1850#endif /* #if 0 to enforce ASL logging only. */ 1851 else 1852 { 1853 // Ignore unknown argument 1854 const char *c = strchr (p, ';'); 1855 if (c) 1856 p = c + 1; 1857 else 1858 p = strchr (p, '\0'); 1859 } 1860 } 1861 1862 return rnb_success; 1863} 1864 1865rnb_err_t 1866RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p) 1867{ 1868 m_thread_suffix_supported = true; 1869 return SendPacket ("OK"); 1870} 1871 1872rnb_err_t 1873RNBRemote::HandlePacket_QStartNoAckMode (const char *p) 1874{ 1875 // Send the OK packet first so the correct checksum is appended... 1876 rnb_err_t result = SendPacket ("OK"); 1877 m_noack_mode = true; 1878 return result; 1879} 1880 1881 1882rnb_err_t 1883RNBRemote::HandlePacket_QSetLogging (const char *p) 1884{ 1885 p += sizeof ("QSetLogging:") - 1; 1886 rnb_err_t result = set_logging (p); 1887 if (result == rnb_success) 1888 return SendPacket ("OK"); 1889 else 1890 return SendPacket ("E35"); 1891} 1892 1893rnb_err_t 1894RNBRemote::HandlePacket_QSetDisableASLR (const char *p) 1895{ 1896 extern int g_disable_aslr; 1897 p += sizeof ("QSetDisableASLR:") - 1; 1898 switch (*p) 1899 { 1900 case '0': g_disable_aslr = 0; break; 1901 case '1': g_disable_aslr = 1; break; 1902 default: 1903 return SendPacket ("E56"); 1904 } 1905 return SendPacket ("OK"); 1906} 1907 1908rnb_err_t 1909RNBRemote::HandlePacket_QSetSTDIO (const char *p) 1910{ 1911 // Only set stdin/out/err if we don't already have a process 1912 if (!m_ctx.HasValidProcessID()) 1913 { 1914 bool success = false; 1915 // Check the seventh character since the packet will be one of: 1916 // QSetSTDIN 1917 // QSetSTDOUT 1918 // QSetSTDERR 1919 StringExtractor packet(p); 1920 packet.SetFilePos (7); 1921 char ch = packet.GetChar(); 1922 while (packet.GetChar() != ':') 1923 /* Do nothing. */; 1924 1925 switch (ch) 1926 { 1927 case 'I': // STDIN 1928 packet.GetHexByteString (m_ctx.GetSTDIN()); 1929 success = !m_ctx.GetSTDIN().empty(); 1930 break; 1931 1932 case 'O': // STDOUT 1933 packet.GetHexByteString (m_ctx.GetSTDOUT()); 1934 success = !m_ctx.GetSTDOUT().empty(); 1935 break; 1936 1937 case 'E': // STDERR 1938 packet.GetHexByteString (m_ctx.GetSTDERR()); 1939 success = !m_ctx.GetSTDERR().empty(); 1940 break; 1941 1942 default: 1943 break; 1944 } 1945 if (success) 1946 return SendPacket ("OK"); 1947 return SendPacket ("E57"); 1948 } 1949 return SendPacket ("E58"); 1950} 1951 1952rnb_err_t 1953RNBRemote::HandlePacket_QSetWorkingDir (const char *p) 1954{ 1955 // Only set the working directory if we don't already have a process 1956 if (!m_ctx.HasValidProcessID()) 1957 { 1958 StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1); 1959 if (packet.GetHexByteString (m_ctx.GetWorkingDir())) 1960 { 1961 struct stat working_dir_stat; 1962 if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) 1963 { 1964 m_ctx.GetWorkingDir().clear(); 1965 return SendPacket ("E61"); // Working directory doesn't exist... 1966 } 1967 else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) 1968 { 1969 return SendPacket ("OK"); 1970 } 1971 else 1972 { 1973 m_ctx.GetWorkingDir().clear(); 1974 return SendPacket ("E62"); // Working directory isn't a directory... 1975 } 1976 } 1977 return SendPacket ("E59"); // Invalid path 1978 } 1979 return SendPacket ("E60"); // Already had a process, too late to set working dir 1980} 1981 1982rnb_err_t 1983RNBRemote::HandlePacket_QSyncThreadState (const char *p) 1984{ 1985 if (!m_ctx.HasValidProcessID()) 1986 { 1987 // We allow gdb to connect to a server that hasn't started running 1988 // the target yet. gdb still wants to ask questions about it and 1989 // freaks out if it gets an error. So just return OK here. 1990 return SendPacket ("OK"); 1991 } 1992 1993 errno = 0; 1994 p += strlen("QSyncThreadState:"); 1995 nub_thread_t tid = strtoul (p, NULL, 16); 1996 if (errno != 0 && tid == 0) 1997 { 1998 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet"); 1999 } 2000 if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid)) 2001 return SendPacket("OK"); 2002 else 2003 return SendPacket ("E61"); 2004} 2005 2006rnb_err_t 2007RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p) 2008{ 2009 // If this packet is received, it allows us to send an extra key/value 2010 // pair in the stop reply packets where we will list all of the thread IDs 2011 // separated by commas: 2012 // 2013 // "threads:10a,10b,10c;" 2014 // 2015 // This will get included in the stop reply packet as something like: 2016 // 2017 // "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;" 2018 // 2019 // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and 2020 // speed things up a bit. 2021 // 2022 // Send the OK packet first so the correct checksum is appended... 2023 rnb_err_t result = SendPacket ("OK"); 2024 m_list_threads_in_stop_reply = true; 2025 return result; 2026} 2027 2028 2029rnb_err_t 2030RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p) 2031{ 2032 /* The number of characters in a packet payload that gdb is 2033 prepared to accept. The packet-start char, packet-end char, 2034 2 checksum chars and terminating null character are not included 2035 in this size. */ 2036 p += sizeof ("QSetMaxPayloadSize:") - 1; 2037 errno = 0; 2038 uint32_t size = strtoul (p, NULL, 16); 2039 if (errno != 0 && size == 0) 2040 { 2041 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet"); 2042 } 2043 m_max_payload_size = size; 2044 return SendPacket ("OK"); 2045} 2046 2047rnb_err_t 2048RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p) 2049{ 2050 /* This tells us the largest packet that gdb can handle. 2051 i.e. the size of gdb's packet-reading buffer. 2052 QSetMaxPayloadSize is preferred because it is less ambiguous. */ 2053 p += sizeof ("QSetMaxPacketSize:") - 1; 2054 errno = 0; 2055 uint32_t size = strtoul (p, NULL, 16); 2056 if (errno != 0 && size == 0) 2057 { 2058 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet"); 2059 } 2060 m_max_payload_size = size - 5; 2061 return SendPacket ("OK"); 2062} 2063 2064 2065 2066 2067rnb_err_t 2068RNBRemote::HandlePacket_QEnvironment (const char *p) 2069{ 2070 /* This sets the environment for the target program. The packet is of the form: 2071 2072 QEnvironment:VARIABLE=VALUE 2073 2074 */ 2075 2076 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"", 2077 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2078 2079 p += sizeof ("QEnvironment:") - 1; 2080 RNBContext& ctx = Context(); 2081 2082 ctx.PushEnvironment (p); 2083 return SendPacket ("OK"); 2084} 2085 2086rnb_err_t 2087RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p) 2088{ 2089 /* This sets the environment for the target program. The packet is of the form: 2090 2091 QEnvironmentHexEncoded:VARIABLE=VALUE 2092 2093 The VARIABLE=VALUE part is sent hex-encoded so chracters like '#' with special 2094 meaning in the remote protocol won't break it. 2095 */ 2096 2097 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"", 2098 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2099 2100 p += sizeof ("QEnvironmentHexEncoded:") - 1; 2101 2102 std::string arg; 2103 const char *c; 2104 c = p; 2105 while (*c != '\0') 2106 { 2107 if (*(c + 1) == '\0') 2108 { 2109 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2110 } 2111 char smallbuf[3]; 2112 smallbuf[0] = *c; 2113 smallbuf[1] = *(c + 1); 2114 smallbuf[2] = '\0'; 2115 errno = 0; 2116 int ch = strtoul (smallbuf, NULL, 16); 2117 if (errno != 0 && ch == 0) 2118 { 2119 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2120 } 2121 arg.push_back(ch); 2122 c += 2; 2123 } 2124 2125 RNBContext& ctx = Context(); 2126 if (arg.length() > 0) 2127 ctx.PushEnvironment (arg.c_str()); 2128 2129 return SendPacket ("OK"); 2130} 2131 2132 2133rnb_err_t 2134RNBRemote::HandlePacket_QLaunchArch (const char *p) 2135{ 2136 p += sizeof ("QLaunchArch:") - 1; 2137 if (DNBSetArchitecture(p)) 2138 return SendPacket ("OK"); 2139 return SendPacket ("E63"); 2140} 2141 2142void 2143append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap) 2144{ 2145 int i; 2146 if (swap) 2147 { 2148 for (i = buf_size-1; i >= 0; i--) 2149 ostrm << RAWHEX8(buf[i]); 2150 } 2151 else 2152 { 2153 for (i = 0; i < buf_size; i++) 2154 ostrm << RAWHEX8(buf[i]); 2155 } 2156} 2157 2158 2159void 2160register_value_in_hex_fixed_width (std::ostream& ostrm, 2161 nub_process_t pid, 2162 nub_thread_t tid, 2163 const register_map_entry_t* reg, 2164 const DNBRegisterValue *reg_value_ptr) 2165{ 2166 if (reg != NULL) 2167 { 2168 DNBRegisterValue reg_value; 2169 if (reg_value_ptr == NULL) 2170 { 2171 if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, ®_value)) 2172 reg_value_ptr = ®_value; 2173 } 2174 2175 if (reg_value_ptr) 2176 { 2177 append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->gdb_size, false); 2178 } 2179 else 2180 { 2181 // If we fail to read a regiser value, check if it has a default 2182 // fail value. If it does, return this instead in case some of 2183 // the registers are not available on the current system. 2184 if (reg->gdb_size > 0) 2185 { 2186 if (reg->fail_value != NULL) 2187 { 2188 append_hex_value (ostrm, reg->fail_value, reg->gdb_size, false); 2189 } 2190 else 2191 { 2192 std::basic_string<uint8_t> zeros(reg->gdb_size, '\0'); 2193 append_hex_value (ostrm, zeros.data(), zeros.size(), false); 2194 } 2195 } 2196 } 2197 } 2198} 2199 2200 2201void 2202gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm, 2203 nub_process_t pid, 2204 nub_thread_t tid, 2205 const register_map_entry_t* reg, 2206 const DNBRegisterValue *reg_value_ptr) 2207{ 2208 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX 2209 // gdb register number, and VVVVVVVV is the correct number of hex bytes 2210 // as ASCII for the register value. 2211 if (reg != NULL) 2212 { 2213 ostrm << RAWHEX8(reg->gdb_regnum) << ':'; 2214 register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr); 2215 ostrm << ';'; 2216 } 2217} 2218 2219rnb_err_t 2220RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) 2221{ 2222 const nub_process_t pid = m_ctx.ProcessID(); 2223 if (pid == INVALID_NUB_PROCESS) 2224 return SendPacket("E50"); 2225 2226 struct DNBThreadStopInfo tid_stop_info; 2227 2228 /* Fill the remaining space in this packet with as many registers 2229 as we can stuff in there. */ 2230 2231 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) 2232 { 2233 std::ostringstream ostrm; 2234 // Output the T packet with the thread 2235 ostrm << 'T'; 2236 int signum = tid_stop_info.details.signal.signo; 2237 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); 2238 2239 // Translate any mach exceptions to gdb versions, unless they are 2240 // common exceptions like a breakpoint or a soft signal. 2241 switch (tid_stop_info.details.exception.type) 2242 { 2243 default: signum = 0; break; 2244 case EXC_BREAKPOINT: signum = SIGTRAP; break; 2245 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break; 2246 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break; 2247 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break; 2248 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break; 2249 case EXC_SOFTWARE: 2250 if (tid_stop_info.details.exception.data_count == 2 && 2251 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2252 signum = tid_stop_info.details.exception.data[1]; 2253 else 2254 signum = TARGET_EXC_SOFTWARE; 2255 break; 2256 } 2257 2258 ostrm << RAWHEX8(signum & 0xff); 2259 2260 ostrm << std::hex << "thread:" << tid << ';'; 2261 2262 const char *thread_name = DNBThreadGetName (pid, tid); 2263 if (thread_name && thread_name[0]) 2264 { 2265 size_t thread_name_len = strlen(thread_name); 2266 2267 if (::strcspn (thread_name, "$#+-;:") == thread_name_len) 2268 ostrm << std::hex << "name:" << thread_name << ';'; 2269 else 2270 { 2271 // the thread name contains special chars, send as hex bytes 2272 ostrm << std::hex << "hexname:"; 2273 uint8_t *u_thread_name = (uint8_t *)thread_name; 2274 for (int i = 0; i < thread_name_len; i++) 2275 ostrm << RAWHEX8(u_thread_name[i]); 2276 ostrm << ';'; 2277 } 2278 } 2279 2280 thread_identifier_info_data_t thread_ident_info; 2281 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 2282 { 2283 if (thread_ident_info.dispatch_qaddr != 0) 2284 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';'; 2285 } 2286 2287 // If a 'QListThreadsInStopReply' was sent to enable this feature, we 2288 // will send all thread IDs back in the "threads" key whose value is 2289 // a listc of hex thread IDs separated by commas: 2290 // "threads:10a,10b,10c;" 2291 // This will save the debugger from having to send a pair of qfThreadInfo 2292 // and qsThreadInfo packets, but it also might take a lot of room in the 2293 // stop reply packet, so it must be enabled only on systems where there 2294 // are no limits on packet lengths. 2295 2296 if (m_list_threads_in_stop_reply) 2297 { 2298 const nub_size_t numthreads = DNBProcessGetNumThreads (pid); 2299 if (numthreads > 0) 2300 { 2301 ostrm << std::hex << "threads:"; 2302 for (nub_size_t i = 0; i < numthreads; ++i) 2303 { 2304 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 2305 if (i > 0) 2306 ostrm << ','; 2307 ostrm << std::hex << th; 2308 } 2309 ostrm << ';'; 2310 } 2311 } 2312 2313 if (g_num_reg_entries == 0) 2314 InitializeRegisters (); 2315 2316 if (g_reg_entries != NULL) 2317 { 2318 DNBRegisterValue reg_value; 2319 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2320 { 2321 if (g_reg_entries[reg].expedite) 2322 { 2323 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 2324 continue; 2325 2326 gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], ®_value); 2327 } 2328 } 2329 } 2330 2331 if (tid_stop_info.details.exception.type) 2332 { 2333 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";"; 2334 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";"; 2335 for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i) 2336 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";"; 2337 } 2338 return SendPacket (ostrm.str ()); 2339 } 2340 return SendPacket("E51"); 2341} 2342 2343/* '?' 2344 The stop reply packet - tell gdb what the status of the inferior is. 2345 Often called the questionmark_packet. */ 2346 2347rnb_err_t 2348RNBRemote::HandlePacket_last_signal (const char *unused) 2349{ 2350 if (!m_ctx.HasValidProcessID()) 2351 { 2352 // Inferior is not yet specified/running 2353 return SendPacket ("E02"); 2354 } 2355 2356 nub_process_t pid = m_ctx.ProcessID(); 2357 nub_state_t pid_state = DNBProcessGetState (pid); 2358 2359 switch (pid_state) 2360 { 2361 case eStateAttaching: 2362 case eStateLaunching: 2363 case eStateRunning: 2364 case eStateStepping: 2365 case eStateDetached: 2366 return rnb_success; // Ignore 2367 2368 case eStateSuspended: 2369 case eStateStopped: 2370 case eStateCrashed: 2371 { 2372 nub_thread_t tid = DNBProcessGetCurrentThread (pid); 2373 // Make sure we set the current thread so g and p packets return 2374 // the data the gdb will expect. 2375 SetCurrentThread (tid); 2376 2377 SendStopReplyPacketForThread (tid); 2378 } 2379 break; 2380 2381 case eStateInvalid: 2382 case eStateUnloaded: 2383 case eStateExited: 2384 { 2385 char pid_exited_packet[16] = ""; 2386 int pid_status = 0; 2387 // Process exited with exit status 2388 if (!DNBProcessGetExitStatus(pid, &pid_status)) 2389 pid_status = 0; 2390 2391 if (pid_status) 2392 { 2393 if (WIFEXITED (pid_status)) 2394 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status)); 2395 else if (WIFSIGNALED (pid_status)) 2396 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status)); 2397 else if (WIFSTOPPED (pid_status)) 2398 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status)); 2399 } 2400 2401 // If we have an empty exit packet, lets fill one in to be safe. 2402 if (!pid_exited_packet[0]) 2403 { 2404 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1); 2405 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0'; 2406 } 2407 2408 return SendPacket (pid_exited_packet); 2409 } 2410 break; 2411 } 2412 return rnb_success; 2413} 2414 2415rnb_err_t 2416RNBRemote::HandlePacket_M (const char *p) 2417{ 2418 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2419 { 2420 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet"); 2421 } 2422 2423 char *c; 2424 p++; 2425 errno = 0; 2426 nub_addr_t addr = strtoull (p, &c, 16); 2427 if (errno != 0 && addr == 0) 2428 { 2429 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet"); 2430 } 2431 if (*c != ',') 2432 { 2433 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet"); 2434 } 2435 2436 /* Advance 'p' to the length part of the packet. */ 2437 p += (c - p) + 1; 2438 2439 errno = 0; 2440 uint32_t length = strtoul (p, &c, 16); 2441 if (errno != 0 && length == 0) 2442 { 2443 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet"); 2444 } 2445 if (length == 0) 2446 { 2447 return SendPacket ("OK"); 2448 } 2449 2450 if (*c != ':') 2451 { 2452 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet"); 2453 } 2454 /* Advance 'p' to the data part of the packet. */ 2455 p += (c - p) + 1; 2456 2457 int datalen = strlen (p); 2458 if (datalen & 0x1) 2459 { 2460 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet"); 2461 } 2462 if (datalen == 0) 2463 { 2464 return SendPacket ("OK"); 2465 } 2466 2467 uint8_t *buf = (uint8_t *) alloca (datalen / 2); 2468 uint8_t *i = buf; 2469 2470 while (*p != '\0' && *(p + 1) != '\0') 2471 { 2472 char hexbuf[3]; 2473 hexbuf[0] = *p; 2474 hexbuf[1] = *(p + 1); 2475 hexbuf[2] = '\0'; 2476 errno = 0; 2477 uint8_t byte = strtoul (hexbuf, NULL, 16); 2478 if (errno != 0 && byte == 0) 2479 { 2480 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet"); 2481 } 2482 *i++ = byte; 2483 p += 2; 2484 } 2485 2486 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf); 2487 if (wrote != length) 2488 return SendPacket ("E09"); 2489 else 2490 return SendPacket ("OK"); 2491} 2492 2493 2494rnb_err_t 2495RNBRemote::HandlePacket_m (const char *p) 2496{ 2497 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2498 { 2499 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet"); 2500 } 2501 2502 char *c; 2503 p++; 2504 errno = 0; 2505 nub_addr_t addr = strtoull (p, &c, 16); 2506 if (errno != 0 && addr == 0) 2507 { 2508 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet"); 2509 } 2510 if (*c != ',') 2511 { 2512 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet"); 2513 } 2514 2515 /* Advance 'p' to the length part of the packet. */ 2516 p += (c - p) + 1; 2517 2518 errno = 0; 2519 uint32_t length = strtoul (p, NULL, 16); 2520 if (errno != 0 && length == 0) 2521 { 2522 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2523 } 2524 if (length == 0) 2525 { 2526 return SendPacket (""); 2527 } 2528 2529 uint8_t buf[length]; 2530 int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf); 2531 if (bytes_read == 0) 2532 { 2533 return SendPacket ("E08"); 2534 } 2535 2536 // "The reply may contain fewer bytes than requested if the server was able 2537 // to read only part of the region of memory." 2538 length = bytes_read; 2539 2540 std::ostringstream ostrm; 2541 for (int i = 0; i < length; i++) 2542 ostrm << RAWHEX8(buf[i]); 2543 return SendPacket (ostrm.str ()); 2544} 2545 2546rnb_err_t 2547RNBRemote::HandlePacket_X (const char *p) 2548{ 2549 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2550 { 2551 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 2552 } 2553 2554 char *c; 2555 p++; 2556 errno = 0; 2557 nub_addr_t addr = strtoull (p, &c, 16); 2558 if (errno != 0 && addr == 0) 2559 { 2560 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 2561 } 2562 if (*c != ',') 2563 { 2564 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 2565 } 2566 2567 /* Advance 'p' to the length part of the packet. */ 2568 p += (c - p) + 1; 2569 2570 errno = 0; 2571 int length = strtoul (p, NULL, 16); 2572 if (errno != 0 && length == 0) 2573 { 2574 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2575 } 2576 2577 // I think gdb sends a zero length write request to test whether this 2578 // packet is accepted. 2579 if (length == 0) 2580 { 2581 return SendPacket ("OK"); 2582 } 2583 2584 std::vector<uint8_t> data = decode_binary_data (c, -1); 2585 std::vector<uint8_t>::const_iterator it; 2586 uint8_t *buf = (uint8_t *) alloca (data.size ()); 2587 uint8_t *i = buf; 2588 for (it = data.begin (); it != data.end (); ++it) 2589 { 2590 *i++ = *it; 2591 } 2592 2593 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf); 2594 if (wrote != data.size ()) 2595 return SendPacket ("E08"); 2596 return SendPacket ("OK"); 2597} 2598 2599/* 'g' -- read registers 2600 Get the contents of the registers for the current thread, 2601 send them to gdb. 2602 Should the setting of the Hg packet determine which thread's registers 2603 are returned? */ 2604 2605rnb_err_t 2606RNBRemote::HandlePacket_g (const char *p) 2607{ 2608 std::ostringstream ostrm; 2609 if (!m_ctx.HasValidProcessID()) 2610 { 2611 return SendPacket ("E11"); 2612 } 2613 2614 if (g_num_reg_entries == 0) 2615 InitializeRegisters (); 2616 2617 nub_process_t pid = m_ctx.ProcessID (); 2618 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1); 2619 if (tid == INVALID_NUB_THREAD) 2620 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2621 2622 if (m_use_native_regs) 2623 { 2624 // Get the register context size first by calling with NULL buffer 2625 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2626 if (reg_ctx_size) 2627 { 2628 // Now allocate enough space for the entire register context 2629 std::vector<uint8_t> reg_ctx; 2630 reg_ctx.resize(reg_ctx_size); 2631 // Now read the register context 2632 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 2633 if (reg_ctx_size) 2634 { 2635 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false); 2636 return SendPacket (ostrm.str ()); 2637 } 2638 } 2639 } 2640 2641 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2642 register_value_in_hex_fixed_width (ostrm, pid, tid, &g_reg_entries[reg], NULL); 2643 2644 return SendPacket (ostrm.str ()); 2645} 2646 2647/* 'G XXX...' -- write registers 2648 How is the thread for these specified, beyond "the current thread"? 2649 Does gdb actually use the Hg packet to set this? */ 2650 2651rnb_err_t 2652RNBRemote::HandlePacket_G (const char *p) 2653{ 2654 if (!m_ctx.HasValidProcessID()) 2655 { 2656 return SendPacket ("E11"); 2657 } 2658 2659 if (g_num_reg_entries == 0) 2660 InitializeRegisters (); 2661 2662 StringExtractor packet(p); 2663 packet.SetFilePos(1); // Skip the 'G' 2664 2665 nub_process_t pid = m_ctx.ProcessID(); 2666 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2667 if (tid == INVALID_NUB_THREAD) 2668 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2669 2670 if (m_use_native_regs) 2671 { 2672 // Get the register context size first by calling with NULL buffer 2673 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2674 if (reg_ctx_size) 2675 { 2676 // Now allocate enough space for the entire register context 2677 std::vector<uint8_t> reg_ctx; 2678 reg_ctx.resize(reg_ctx_size); 2679 2680 const nub_size_t bytes_extracted = packet.GetHexBytes (®_ctx[0], reg_ctx.size(), 0xcc); 2681 if (bytes_extracted == reg_ctx.size()) 2682 { 2683 // Now write the register context 2684 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 2685 if (reg_ctx_size == reg_ctx.size()) 2686 return SendPacket ("OK"); 2687 else 2688 return SendPacket ("E55"); 2689 } 2690 else 2691 { 2692 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); 2693 return SendPacket ("E64"); 2694 } 2695 } 2696 else 2697 return SendPacket ("E65"); 2698 } 2699 2700 2701 DNBRegisterValue reg_value; 2702 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2703 { 2704 const register_map_entry_t *reg_entry = &g_reg_entries[reg]; 2705 2706 reg_value.info = reg_entry->nub_info; 2707 if (packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc) != reg_entry->gdb_size) 2708 break; 2709 2710 if (reg_entry->fail_value == NULL) 2711 { 2712 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 2713 return SendPacket ("E15"); 2714 } 2715 } 2716 return SendPacket ("OK"); 2717} 2718 2719static bool 2720RNBRemoteShouldCancelCallback (void *not_used) 2721{ 2722 RNBRemoteSP remoteSP(g_remoteSP); 2723 if (remoteSP.get() != NULL) 2724 { 2725 RNBRemote* remote = remoteSP.get(); 2726 if (remote->Comm().IsConnected()) 2727 return false; 2728 else 2729 return true; 2730 } 2731 return true; 2732} 2733 2734 2735// FORMAT: _MXXXXXX,PPP 2736// XXXXXX: big endian hex chars 2737// PPP: permissions can be any combo of r w x chars 2738// 2739// RESPONSE: XXXXXX 2740// XXXXXX: hex address of the newly allocated memory 2741// EXX: error code 2742// 2743// EXAMPLES: 2744// _M123000,rw 2745// _M123000,rwx 2746// _M123000,xw 2747 2748rnb_err_t 2749RNBRemote::HandlePacket_AllocateMemory (const char *p) 2750{ 2751 StringExtractor packet (p); 2752 packet.SetFilePos(2); // Skip the "_M" 2753 2754 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0); 2755 if (size != 0) 2756 { 2757 if (packet.GetChar() == ',') 2758 { 2759 uint32_t permissions = 0; 2760 char ch; 2761 bool success = true; 2762 while (success && (ch = packet.GetChar()) != '\0') 2763 { 2764 switch (ch) 2765 { 2766 case 'r': permissions |= eMemoryPermissionsReadable; break; 2767 case 'w': permissions |= eMemoryPermissionsWritable; break; 2768 case 'x': permissions |= eMemoryPermissionsExecutable; break; 2769 default: success = false; break; 2770 } 2771 } 2772 2773 if (success) 2774 { 2775 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions); 2776 if (addr != INVALID_NUB_ADDRESS) 2777 { 2778 std::ostringstream ostrm; 2779 ostrm << RAW_HEXBASE << addr; 2780 return SendPacket (ostrm.str ()); 2781 } 2782 } 2783 } 2784 } 2785 return SendPacket ("E53"); 2786} 2787 2788// FORMAT: _mXXXXXX 2789// XXXXXX: address that was previosly allocated 2790// 2791// RESPONSE: XXXXXX 2792// OK: address was deallocated 2793// EXX: error code 2794// 2795// EXAMPLES: 2796// _m123000 2797 2798rnb_err_t 2799RNBRemote::HandlePacket_DeallocateMemory (const char *p) 2800{ 2801 StringExtractor packet (p); 2802 packet.SetFilePos(2); // Skip the "_m" 2803 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS); 2804 2805 if (addr != INVALID_NUB_ADDRESS) 2806 { 2807 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr)) 2808 return SendPacket ("OK"); 2809 } 2810 return SendPacket ("E54"); 2811} 2812 2813static bool 2814GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name) 2815{ 2816 bool return_val = true; 2817 while (*p != '\0') 2818 { 2819 char smallbuf[3]; 2820 smallbuf[0] = *p; 2821 smallbuf[1] = *(p + 1); 2822 smallbuf[2] = '\0'; 2823 2824 errno = 0; 2825 int ch = strtoul (smallbuf, NULL, 16); 2826 if (errno != 0 && ch == 0) 2827 { 2828 return_val = false; 2829 break; 2830 } 2831 2832 attach_name.push_back(ch); 2833 p += 2; 2834 } 2835 return return_val; 2836} 2837 2838/* 2839 vAttach;pid 2840 2841 Attach to a new process with the specified process ID. pid is a hexadecimal integer 2842 identifying the process. If the stub is currently controlling a process, it is 2843 killed. The attached process is stopped.This packet is only available in extended 2844 mode (see extended mode). 2845 2846 Reply: 2847 "ENN" for an error 2848 "Any Stop Reply Packet" for success 2849 */ 2850 2851rnb_err_t 2852RNBRemote::HandlePacket_v (const char *p) 2853{ 2854 if (strcmp (p, "vCont;c") == 0) 2855 { 2856 // Simple continue 2857 return RNBRemote::HandlePacket_c("c"); 2858 } 2859 else if (strcmp (p, "vCont;s") == 0) 2860 { 2861 // Simple step 2862 return RNBRemote::HandlePacket_s("s"); 2863 } 2864 else if (strstr (p, "vCont") == p) 2865 { 2866 typedef struct 2867 { 2868 nub_thread_t tid; 2869 char action; 2870 int signal; 2871 } vcont_action_t; 2872 2873 DNBThreadResumeActions thread_actions; 2874 char *c = (char *)(p += strlen("vCont")); 2875 char *c_end = c + strlen(c); 2876 if (*c == '?') 2877 return SendPacket ("vCont;c;C;s;S"); 2878 2879 while (c < c_end && *c == ';') 2880 { 2881 ++c; // Skip the semi-colon 2882 DNBThreadResumeAction thread_action; 2883 thread_action.tid = INVALID_NUB_THREAD; 2884 thread_action.state = eStateInvalid; 2885 thread_action.signal = 0; 2886 thread_action.addr = INVALID_NUB_ADDRESS; 2887 2888 char action = *c++; 2889 2890 switch (action) 2891 { 2892 case 'C': 2893 errno = 0; 2894 thread_action.signal = strtoul (c, &c, 16); 2895 if (errno != 0) 2896 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2897 // Fall through to next case... 2898 2899 case 'c': 2900 // Continue 2901 thread_action.state = eStateRunning; 2902 break; 2903 2904 case 'S': 2905 errno = 0; 2906 thread_action.signal = strtoul (c, &c, 16); 2907 if (errno != 0) 2908 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2909 // Fall through to next case... 2910 2911 case 's': 2912 // Step 2913 thread_action.state = eStateStepping; 2914 break; 2915 2916 default: 2917 HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet"); 2918 break; 2919 } 2920 if (*c == ':') 2921 { 2922 errno = 0; 2923 thread_action.tid = strtoul (++c, &c, 16); 2924 if (errno != 0) 2925 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet"); 2926 } 2927 2928 thread_actions.Append (thread_action); 2929 } 2930 2931 // If a default action for all other threads wasn't mentioned 2932 // then we should stop the threads 2933 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 2934 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize()); 2935 return rnb_success; 2936 } 2937 else if (strstr (p, "vAttach") == p) 2938 { 2939 nub_process_t attach_pid = INVALID_NUB_PROCESS; 2940 char err_str[1024]={'\0'}; 2941 2942 if (strstr (p, "vAttachWait;") == p) 2943 { 2944 p += strlen("vAttachWait;"); 2945 std::string attach_name; 2946 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2947 { 2948 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 2949 } 2950 const bool ignore_existing = true; 2951 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 2952 2953 } 2954 else if (strstr (p, "vAttachOrWait;") == p) 2955 { 2956 p += strlen("vAttachOrWait;"); 2957 std::string attach_name; 2958 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2959 { 2960 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt"); 2961 } 2962 const bool ignore_existing = false; 2963 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 2964 } 2965 else if (strstr (p, "vAttachName;") == p) 2966 { 2967 p += strlen("vAttachName;"); 2968 std::string attach_name; 2969 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2970 { 2971 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 2972 } 2973 2974 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str)); 2975 2976 } 2977 else if (strstr (p, "vAttach;") == p) 2978 { 2979 p += strlen("vAttach;"); 2980 char *end = NULL; 2981 attach_pid = strtoul (p, &end, 16); // PID will be in hex, so use base 16 to decode 2982 if (p != end && *end == '\0') 2983 { 2984 // Wait at most 30 second for attach 2985 struct timespec attach_timeout_abstime; 2986 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 2987 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str)); 2988 } 2989 } 2990 else 2991 { 2992 return HandlePacket_UNIMPLEMENTED(p); 2993 } 2994 2995 2996 if (attach_pid != INVALID_NUB_PROCESS) 2997 { 2998 if (m_ctx.ProcessID() != attach_pid) 2999 m_ctx.SetProcessID(attach_pid); 3000 // Send a stop reply packet to indicate we successfully attached! 3001 NotifyThatProcessStopped (); 3002 return rnb_success; 3003 } 3004 else 3005 { 3006 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3007 if (err_str[0]) 3008 m_ctx.LaunchStatus().SetErrorString(err_str); 3009 else 3010 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3011 return SendPacket ("E01"); // E01 is our magic error value for attach failed. 3012 } 3013 } 3014 3015 // All other failures come through here 3016 return HandlePacket_UNIMPLEMENTED(p); 3017} 3018 3019/* 'T XX' -- status of thread 3020 Check if the specified thread is alive. 3021 The thread number is in hex? */ 3022 3023rnb_err_t 3024RNBRemote::HandlePacket_T (const char *p) 3025{ 3026 p++; 3027 if (p == NULL || *p == '\0') 3028 { 3029 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet"); 3030 } 3031 if (!m_ctx.HasValidProcessID()) 3032 { 3033 return SendPacket ("E15"); 3034 } 3035 errno = 0; 3036 nub_thread_t tid = strtoul (p, NULL, 16); 3037 if (errno != 0 && tid == 0) 3038 { 3039 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet"); 3040 } 3041 3042 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid); 3043 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) 3044 { 3045 return SendPacket ("E16"); 3046 } 3047 3048 return SendPacket ("OK"); 3049} 3050 3051 3052rnb_err_t 3053RNBRemote::HandlePacket_z (const char *p) 3054{ 3055 if (p == NULL || *p == '\0') 3056 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet"); 3057 3058 if (!m_ctx.HasValidProcessID()) 3059 return SendPacket ("E15"); 3060 3061 char packet_cmd = *p++; 3062 char break_type = *p++; 3063 3064 if (*p++ != ',') 3065 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3066 3067 char *c = NULL; 3068 nub_process_t pid = m_ctx.ProcessID(); 3069 errno = 0; 3070 nub_addr_t addr = strtoull (p, &c, 16); 3071 if (errno != 0 && addr == 0) 3072 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet"); 3073 p = c; 3074 if (*p++ != ',') 3075 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3076 3077 errno = 0; 3078 uint32_t byte_size = strtoul (p, &c, 16); 3079 if (errno != 0 && byte_size == 0) 3080 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet"); 3081 3082 if (packet_cmd == 'Z') 3083 { 3084 // set 3085 switch (break_type) 3086 { 3087 case '0': // set software breakpoint 3088 case '1': // set hardware breakpoint 3089 { 3090 // gdb can send multiple Z packets for the same address and 3091 // these calls must be ref counted. 3092 bool hardware = (break_type == '1'); 3093 3094 // Check if we currently have a breakpoint already set at this address 3095 BreakpointMapIter pos = m_breakpoints.find(addr); 3096 if (pos != m_breakpoints.end()) 3097 { 3098 // We do already have a breakpoint at this address, increment 3099 // its reference count and return OK 3100 pos->second.Retain(); 3101 return SendPacket ("OK"); 3102 } 3103 else 3104 { 3105 // We do NOT already have a breakpoint at this address, So lets 3106 // create one. 3107 nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware); 3108 if (NUB_BREAK_ID_IS_VALID(break_id)) 3109 { 3110 // We successfully created a breakpoint, now lets full out 3111 // a ref count structure with the breakID and add it to our 3112 // map. 3113 Breakpoint rnbBreakpoint(break_id); 3114 m_breakpoints[addr] = rnbBreakpoint; 3115 return SendPacket ("OK"); 3116 } 3117 else 3118 { 3119 // We failed to set the software breakpoint 3120 return SendPacket ("E09"); 3121 } 3122 } 3123 } 3124 break; 3125 3126 case '2': // set write watchpoint 3127 case '3': // set read watchpoint 3128 case '4': // set access watchpoint 3129 { 3130 bool hardware = true; 3131 uint32_t watch_flags = 0; 3132 if (break_type == '2') 3133 watch_flags = WATCH_TYPE_WRITE; 3134 else if (break_type == '3') 3135 watch_flags = WATCH_TYPE_READ; 3136 else 3137 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3138 3139 // Check if we currently have a watchpoint already set at this address 3140 BreakpointMapIter pos = m_watchpoints.find(addr); 3141 if (pos != m_watchpoints.end()) 3142 { 3143 // We do already have a watchpoint at this address, increment 3144 // its reference count and return OK 3145 pos->second.Retain(); 3146 return SendPacket ("OK"); 3147 } 3148 else 3149 { 3150 // We do NOT already have a watchpoint at this address, So lets 3151 // create one. 3152 nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware); 3153 if (NUB_WATCH_ID_IS_VALID(watch_id)) 3154 { 3155 // We successfully created a watchpoint, now lets full out 3156 // a ref count structure with the watch_id and add it to our 3157 // map. 3158 Breakpoint rnbWatchpoint(watch_id); 3159 m_watchpoints[addr] = rnbWatchpoint; 3160 return SendPacket ("OK"); 3161 } 3162 else 3163 { 3164 // We failed to set the watchpoint 3165 return SendPacket ("E09"); 3166 } 3167 } 3168 } 3169 break; 3170 3171 default: 3172 break; 3173 } 3174 } 3175 else if (packet_cmd == 'z') 3176 { 3177 // remove 3178 switch (break_type) 3179 { 3180 case '0': // remove software breakpoint 3181 case '1': // remove hardware breakpoint 3182 { 3183 // gdb can send multiple z packets for the same address and 3184 // these calls must be ref counted. 3185 BreakpointMapIter pos = m_breakpoints.find(addr); 3186 if (pos != m_breakpoints.end()) 3187 { 3188 // We currently have a breakpoint at address ADDR. Decrement 3189 // its reference count, and it that count is now zero we 3190 // can clear the breakpoint. 3191 pos->second.Release(); 3192 if (pos->second.RefCount() == 0) 3193 { 3194 if (DNBBreakpointClear (pid, pos->second.BreakID())) 3195 { 3196 m_breakpoints.erase(pos); 3197 return SendPacket ("OK"); 3198 } 3199 else 3200 { 3201 return SendPacket ("E08"); 3202 } 3203 } 3204 else 3205 { 3206 // We still have references to this breakpoint don't 3207 // delete it, just decrementing the reference count 3208 // is enough. 3209 return SendPacket ("OK"); 3210 } 3211 } 3212 else 3213 { 3214 // We don't know about any breakpoints at this address 3215 return SendPacket ("E08"); 3216 } 3217 } 3218 break; 3219 3220 case '2': // remove write watchpoint 3221 case '3': // remove read watchpoint 3222 case '4': // remove access watchpoint 3223 { 3224 // gdb can send multiple z packets for the same address and 3225 // these calls must be ref counted. 3226 BreakpointMapIter pos = m_watchpoints.find(addr); 3227 if (pos != m_watchpoints.end()) 3228 { 3229 // We currently have a watchpoint at address ADDR. Decrement 3230 // its reference count, and it that count is now zero we 3231 // can clear the watchpoint. 3232 pos->second.Release(); 3233 if (pos->second.RefCount() == 0) 3234 { 3235 if (DNBWatchpointClear (pid, pos->second.BreakID())) 3236 { 3237 m_watchpoints.erase(pos); 3238 return SendPacket ("OK"); 3239 } 3240 else 3241 { 3242 return SendPacket ("E08"); 3243 } 3244 } 3245 else 3246 { 3247 // We still have references to this watchpoint don't 3248 // delete it, just decrementing the reference count 3249 // is enough. 3250 return SendPacket ("OK"); 3251 } 3252 } 3253 else 3254 { 3255 // We don't know about any watchpoints at this address 3256 return SendPacket ("E08"); 3257 } 3258 } 3259 break; 3260 3261 default: 3262 break; 3263 } 3264 } 3265 return HandlePacket_UNIMPLEMENTED(p); 3266} 3267 3268// Extract the thread number from the thread suffix that might be appended to 3269// thread specific packets. This will only be enabled if m_thread_suffix_supported 3270// is true. 3271nub_thread_t 3272RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p) 3273{ 3274 if (m_thread_suffix_supported) 3275 { 3276 nub_thread_t tid = INVALID_NUB_THREAD; 3277 if (p) 3278 { 3279 const char *tid_cstr = strstr (p, "thread:"); 3280 if (tid_cstr) 3281 { 3282 tid_cstr += strlen ("thread:"); 3283 tid = strtoul(tid_cstr, NULL, 16); 3284 } 3285 } 3286 return tid; 3287 } 3288 return GetCurrentThread(); 3289 3290} 3291 3292/* 'p XX' 3293 print the contents of register X */ 3294 3295rnb_err_t 3296RNBRemote::HandlePacket_p (const char *p) 3297{ 3298 if (g_num_reg_entries == 0) 3299 InitializeRegisters (); 3300 3301 if (p == NULL || *p == '\0') 3302 { 3303 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3304 } 3305 if (!m_ctx.HasValidProcessID()) 3306 { 3307 return SendPacket ("E15"); 3308 } 3309 nub_process_t pid = m_ctx.ProcessID(); 3310 errno = 0; 3311 char *tid_cstr = NULL; 3312 uint32_t reg = strtoul (p + 1, &tid_cstr, 16); 3313 if (errno != 0 && reg == 0) 3314 { 3315 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet"); 3316 } 3317 3318 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr); 3319 if (tid == INVALID_NUB_THREAD) 3320 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3321 3322 const register_map_entry_t *reg_entry; 3323 3324 if (reg < g_num_reg_entries) 3325 reg_entry = &g_reg_entries[reg]; 3326 else 3327 reg_entry = NULL; 3328 3329 std::ostringstream ostrm; 3330 if (reg_entry == NULL) 3331 { 3332 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg); 3333 ostrm << "00000000"; 3334 } 3335 else if (reg_entry->nub_info.reg == -1) 3336 { 3337 if (reg_entry->gdb_size > 0) 3338 { 3339 if (reg_entry->fail_value != NULL) 3340 { 3341 append_hex_value(ostrm, reg_entry->fail_value, reg_entry->gdb_size, false); 3342 } 3343 else 3344 { 3345 std::basic_string<uint8_t> zeros(reg_entry->gdb_size, '\0'); 3346 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 3347 } 3348 } 3349 } 3350 else 3351 { 3352 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL); 3353 } 3354 return SendPacket (ostrm.str()); 3355} 3356 3357/* 'Pnn=rrrrr' 3358 Set register number n to value r. 3359 n and r are hex strings. */ 3360 3361rnb_err_t 3362RNBRemote::HandlePacket_P (const char *p) 3363{ 3364 if (g_num_reg_entries == 0) 3365 InitializeRegisters (); 3366 3367 if (p == NULL || *p == '\0') 3368 { 3369 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet"); 3370 } 3371 if (!m_ctx.HasValidProcessID()) 3372 { 3373 return SendPacket ("E28"); 3374 } 3375 3376 nub_process_t pid = m_ctx.ProcessID(); 3377 3378 StringExtractor packet (p); 3379 3380 const char cmd_char = packet.GetChar(); 3381 // Register ID is always in big endian 3382 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX); 3383 const char equal_char = packet.GetChar(); 3384 3385 if (cmd_char != 'P') 3386 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet"); 3387 3388 if (reg == UINT32_MAX) 3389 return SendPacket ("E29"); 3390 3391 if (equal_char != '=') 3392 return SendPacket ("E30"); 3393 3394 const register_map_entry_t *reg_entry; 3395 3396 if (reg >= g_num_reg_entries) 3397 return SendPacket("E47"); 3398 3399 reg_entry = &g_reg_entries[reg]; 3400 3401 if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1) 3402 { 3403 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); 3404 return SendPacket("E48"); 3405 } 3406 3407 DNBRegisterValue reg_value; 3408 reg_value.info = reg_entry->nub_info; 3409 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc); 3410 3411 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3412 if (tid == INVALID_NUB_THREAD) 3413 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3414 3415 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 3416 { 3417 return SendPacket ("E32"); 3418 } 3419 return SendPacket ("OK"); 3420} 3421 3422/* 'c [addr]' 3423 Continue, optionally from a specified address. */ 3424 3425rnb_err_t 3426RNBRemote::HandlePacket_c (const char *p) 3427{ 3428 const nub_process_t pid = m_ctx.ProcessID(); 3429 3430 if (pid == INVALID_NUB_PROCESS) 3431 return SendPacket ("E23"); 3432 3433 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3434 3435 if (*(p + 1) != '\0') 3436 { 3437 action.tid = GetContinueThread(); 3438 errno = 0; 3439 action.addr = strtoull (p + 1, NULL, 16); 3440 if (errno != 0 && action.addr == 0) 3441 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet"); 3442 } 3443 3444 DNBThreadResumeActions thread_actions; 3445 thread_actions.Append(action); 3446 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 3447 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3448 return SendPacket ("E25"); 3449 // Don't send an "OK" packet; response is the stopped/exited message. 3450 return rnb_success; 3451} 3452 3453rnb_err_t 3454RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) 3455{ 3456 /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code) 3457 for the memory region containing a given address and return that information. 3458 3459 Users of this packet must be prepared for three results: 3460 3461 Region information is returned 3462 Region information is unavailable for this address because the address is in unmapped memory 3463 Region lookup cannot be performed on this platform or process is not yet launched 3464 This packet isn't implemented 3465 3466 Examples of use: 3467 qMemoryRegionInfo:3a55140 3468 start:3a50000,size:100000,permissions:rwx 3469 3470 qMemoryRegionInfo:0 3471 error:address in unmapped region 3472 3473 qMemoryRegionInfo:3a551140 (on a different platform) 3474 error:region lookup cannot be performed 3475 3476 qMemoryRegionInfo 3477 OK // this packet is implemented by the remote nub 3478 */ 3479 3480 p += sizeof ("qMemoryRegionInfo") - 1; 3481 if (*p == '\0') 3482 return SendPacket ("OK"); 3483 if (*p++ != ':') 3484 return SendPacket ("E67"); 3485 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 3486 p += 2; 3487 3488 errno = 0; 3489 uint64_t address = strtoul (p, NULL, 16); 3490 if (errno != 0 && address == 0) 3491 { 3492 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 3493 } 3494 3495 DNBRegionInfo region_info = { 0, 0, 0 }; 3496 DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); 3497 std::ostringstream ostrm; 3498 3499 // start:3a50000,size:100000,permissions:rwx 3500 ostrm << "start:" << std::hex << region_info.addr << ';'; 3501 3502 if (region_info.size > 0) 3503 ostrm << "size:" << std::hex << region_info.size << ';'; 3504 3505 if (region_info.permissions) 3506 { 3507 ostrm << "permissions:"; 3508 3509 if (region_info.permissions & eMemoryPermissionsReadable) 3510 ostrm << 'r'; 3511 if (region_info.permissions & eMemoryPermissionsWritable) 3512 ostrm << 'w'; 3513 if (region_info.permissions & eMemoryPermissionsExecutable) 3514 ostrm << 'x'; 3515 ostrm << ';'; 3516 } 3517 return SendPacket (ostrm.str()); 3518} 3519 3520rnb_err_t 3521RNBRemote::HandlePacket_GetProfileData (const char *p) 3522{ 3523 nub_process_t pid = m_ctx.ProcessID(); 3524 if (pid == INVALID_NUB_PROCESS) 3525 return SendPacket ("OK"); 3526 3527 std::string data = DNBProcessGetProfileData(pid); 3528 if (!data.empty()) 3529 { 3530 return SendPacket (data.c_str()); 3531 } 3532 else 3533 { 3534 return SendPacket ("OK"); 3535 } 3536} 3537 3538 3539// QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX; 3540rnb_err_t 3541RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p) 3542{ 3543 nub_process_t pid = m_ctx.ProcessID(); 3544 if (pid == INVALID_NUB_PROCESS) 3545 return SendPacket (""); 3546 3547 StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling:") - 1); 3548 bool enable = false; 3549 uint64_t interval_usec = 0; 3550 std::string name; 3551 std::string value; 3552 while (packet.GetNameColonValue(name, value)) 3553 { 3554 if (name.compare ("enable") == 0) 3555 { 3556 enable = strtoul(value.c_str(), NULL, 10) > 0; 3557 } 3558 else if (name.compare ("interval_usec") == 0) 3559 { 3560 interval_usec = strtoul(value.c_str(), NULL, 10); 3561 } 3562 } 3563 3564 if (interval_usec == 0) 3565 { 3566 enable = 0; 3567 } 3568 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec); 3569 return SendPacket ("OK"); 3570} 3571 3572rnb_err_t 3573RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p) 3574{ 3575 /* This packet simply returns the number of supported hardware watchpoints. 3576 3577 Examples of use: 3578 qWatchpointSupportInfo: 3579 num:4 3580 3581 qWatchpointSupportInfo 3582 OK // this packet is implemented by the remote nub 3583 */ 3584 3585 p += sizeof ("qWatchpointSupportInfo") - 1; 3586 if (*p == '\0') 3587 return SendPacket ("OK"); 3588 if (*p++ != ':') 3589 return SendPacket ("E67"); 3590 3591 errno = 0; 3592 uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID()); 3593 std::ostringstream ostrm; 3594 3595 // size:4 3596 ostrm << "num:" << std::dec << num << ';'; 3597 return SendPacket (ostrm.str()); 3598} 3599 3600/* 'C sig [;addr]' 3601 Resume with signal sig, optionally at address addr. */ 3602 3603rnb_err_t 3604RNBRemote::HandlePacket_C (const char *p) 3605{ 3606 const nub_process_t pid = m_ctx.ProcessID(); 3607 3608 if (pid == INVALID_NUB_PROCESS) 3609 return SendPacket ("E36"); 3610 3611 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3612 int process_signo = -1; 3613 if (*(p + 1) != '\0') 3614 { 3615 action.tid = GetContinueThread(); 3616 char *end = NULL; 3617 errno = 0; 3618 process_signo = strtoul (p + 1, &end, 16); 3619 if (errno != 0) 3620 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet"); 3621 else if (*end == ';') 3622 { 3623 errno = 0; 3624 action.addr = strtoull (end + 1, NULL, 16); 3625 if (errno != 0 && action.addr == 0) 3626 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet"); 3627 } 3628 } 3629 3630 DNBThreadResumeActions thread_actions; 3631 thread_actions.Append (action); 3632 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal); 3633 if (!DNBProcessSignal(pid, process_signo)) 3634 return SendPacket ("E52"); 3635 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3636 return SendPacket ("E38"); 3637 /* Don't send an "OK" packet; response is the stopped/exited message. */ 3638 return rnb_success; 3639} 3640 3641//---------------------------------------------------------------------- 3642// 'D' packet 3643// Detach from gdb. 3644//---------------------------------------------------------------------- 3645rnb_err_t 3646RNBRemote::HandlePacket_D (const char *p) 3647{ 3648 SendPacket ("OK"); 3649 if (m_ctx.HasValidProcessID()) 3650 DNBProcessDetach(m_ctx.ProcessID()); 3651 return rnb_success; 3652} 3653 3654/* 'k' 3655 Kill the inferior process. */ 3656 3657rnb_err_t 3658RNBRemote::HandlePacket_k (const char *p) 3659{ 3660 // No response to should be sent to the kill packet 3661 if (m_ctx.HasValidProcessID()) 3662 DNBProcessKill (m_ctx.ProcessID()); 3663 SendPacket ("W09"); 3664 return rnb_success; 3665} 3666 3667rnb_err_t 3668RNBRemote::HandlePacket_stop_process (const char *p) 3669{ 3670//#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt 3671#if defined(TEST_EXIT_ON_INTERRUPT) 3672 rnb_err_t err = HandlePacket_k (p); 3673 m_comm.Disconnect(true); 3674 return err; 3675#else 3676 DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP); 3677 //DNBProcessSignal (m_ctx.ProcessID(), SIGINT); 3678 // Do not send any response packet! Wait for the stop reply packet to naturally happen 3679 return rnb_success; 3680#endif 3681} 3682 3683/* 's' 3684 Step the inferior process. */ 3685 3686rnb_err_t 3687RNBRemote::HandlePacket_s (const char *p) 3688{ 3689 const nub_process_t pid = m_ctx.ProcessID(); 3690 if (pid == INVALID_NUB_PROCESS) 3691 return SendPacket ("E32"); 3692 3693 // Hardware supported stepping not supported on arm 3694 nub_thread_t tid = GetContinueThread (); 3695 if (tid == 0 || tid == -1) 3696 tid = GetCurrentThread(); 3697 3698 if (tid == INVALID_NUB_THREAD) 3699 return SendPacket ("E33"); 3700 3701 DNBThreadResumeActions thread_actions; 3702 thread_actions.AppendAction(tid, eStateStepping); 3703 3704 // Make all other threads stop when we are stepping 3705 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3706 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3707 return SendPacket ("E49"); 3708 // Don't send an "OK" packet; response is the stopped/exited message. 3709 return rnb_success; 3710} 3711 3712/* 'S sig [;addr]' 3713 Step with signal sig, optionally at address addr. */ 3714 3715rnb_err_t 3716RNBRemote::HandlePacket_S (const char *p) 3717{ 3718 const nub_process_t pid = m_ctx.ProcessID(); 3719 if (pid == INVALID_NUB_PROCESS) 3720 return SendPacket ("E36"); 3721 3722 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 3723 3724 if (*(p + 1) != '\0') 3725 { 3726 char *end = NULL; 3727 errno = 0; 3728 action.signal = strtoul (p + 1, &end, 16); 3729 if (errno != 0) 3730 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 3731 else if (*end == ';') 3732 { 3733 errno = 0; 3734 action.addr = strtoull (end + 1, NULL, 16); 3735 if (errno != 0 && action.addr == 0) 3736 { 3737 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 3738 } 3739 } 3740 } 3741 3742 action.tid = GetContinueThread (); 3743 if (action.tid == 0 || action.tid == -1) 3744 return SendPacket ("E40"); 3745 3746 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 3747 if (tstate == eStateInvalid || tstate == eStateExited) 3748 return SendPacket ("E37"); 3749 3750 3751 DNBThreadResumeActions thread_actions; 3752 thread_actions.Append (action); 3753 3754 // Make all other threads stop when we are stepping 3755 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3756 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3757 return SendPacket ("E39"); 3758 3759 // Don't send an "OK" packet; response is the stopped/exited message. 3760 return rnb_success; 3761} 3762 3763rnb_err_t 3764RNBRemote::HandlePacket_qHostInfo (const char *p) 3765{ 3766 std::ostringstream strm; 3767 3768 uint32_t cputype, is_64_bit_capable; 3769 size_t len = sizeof(cputype); 3770 bool promoted_to_64 = false; 3771 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 3772 { 3773 len = sizeof (is_64_bit_capable); 3774 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 3775 { 3776 if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0)) 3777 { 3778 promoted_to_64 = true; 3779 cputype |= CPU_ARCH_ABI64; 3780 } 3781 } 3782 3783 strm << "cputype:" << std::dec << cputype << ';'; 3784 } 3785 3786 uint32_t cpusubtype; 3787 len = sizeof(cpusubtype); 3788 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 3789 { 3790 if (promoted_to_64 && 3791 cputype == CPU_TYPE_X86_64 && 3792 cpusubtype == CPU_SUBTYPE_486) 3793 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3794 3795 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 3796 } 3797 3798 // The OS in the triple should be "ios" or "macosx" which doesn't match our 3799 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 3800 // this for now. 3801 if (cputype == CPU_TYPE_ARM) 3802 { 3803 strm << "ostype:ios;"; 3804 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 3805 strm << "watchpoint_exceptions_received:before;"; 3806 } 3807 else 3808 { 3809 strm << "ostype:macosx;"; 3810 strm << "watchpoint_exceptions_received:after;"; 3811 } 3812// char ostype[64]; 3813// len = sizeof(ostype); 3814// if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 3815// { 3816// len = strlen(ostype); 3817// std::transform (ostype, ostype + len, ostype, tolower); 3818// strm << "ostype:" << std::dec << ostype << ';'; 3819// } 3820 3821 strm << "vendor:apple;"; 3822 3823#if defined (__LITTLE_ENDIAN__) 3824 strm << "endian:little;"; 3825#elif defined (__BIG_ENDIAN__) 3826 strm << "endian:big;"; 3827#elif defined (__PDP_ENDIAN__) 3828 strm << "endian:pdp;"; 3829#endif 3830 3831 if (promoted_to_64) 3832 strm << "ptrsize:8;"; 3833 else 3834 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 3835 return SendPacket (strm.str()); 3836} 3837 3838 3839// Note that all numeric values returned by qProcessInfo are hex encoded, 3840// including the pid and the cpu type. 3841 3842rnb_err_t 3843RNBRemote::HandlePacket_qProcessInfo (const char *p) 3844{ 3845 nub_process_t pid; 3846 std::ostringstream rep; 3847 3848 // If we haven't run the process yet, return an error. 3849 if (!m_ctx.HasValidProcessID()) 3850 return SendPacket ("E68"); 3851 3852 pid = m_ctx.ProcessID(); 3853 3854 rep << "pid:" << std::hex << pid << ";"; 3855 3856 int procpid_mib[4]; 3857 procpid_mib[0] = CTL_KERN; 3858 procpid_mib[1] = KERN_PROC; 3859 procpid_mib[2] = KERN_PROC_PID; 3860 procpid_mib[3] = pid; 3861 struct kinfo_proc proc_kinfo; 3862 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 3863 3864 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 3865 { 3866 if (proc_kinfo_size > 0) 3867 { 3868 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";"; 3869 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";"; 3870 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";"; 3871 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";"; 3872 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 3873 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";"; 3874 } 3875 } 3876 3877 int cputype_mib[CTL_MAXNAME]={0,}; 3878 size_t cputype_mib_len = CTL_MAXNAME; 3879 cpu_type_t cputype = -1; 3880 if (::sysctlnametomib("sysctl.proc_cputype", cputype_mib, &cputype_mib_len) == 0) 3881 { 3882 cputype_mib[cputype_mib_len] = pid; 3883 cputype_mib_len++; 3884 size_t len = sizeof(cputype); 3885 if (::sysctl (cputype_mib, cputype_mib_len, &cputype, &len, 0, 0) == 0) 3886 { 3887 rep << "cputype:" << std::hex << cputype << ";"; 3888 } 3889 } 3890 3891 uint32_t cpusubtype; 3892 size_t cpusubtype_len = sizeof(cpusubtype); 3893 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 3894 { 3895 if (cputype == CPU_TYPE_X86_64 && cpusubtype == CPU_SUBTYPE_486) 3896 { 3897 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3898 } 3899 3900 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 3901 } 3902 3903 // The OS in the triple should be "ios" or "macosx" which doesn't match our 3904 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 3905 // this for now. 3906 if (cputype == CPU_TYPE_ARM) 3907 rep << "ostype:ios;"; 3908 else 3909 rep << "ostype:macosx;"; 3910 3911 rep << "vendor:apple;"; 3912 3913#if defined (__LITTLE_ENDIAN__) 3914 rep << "endian:little;"; 3915#elif defined (__BIG_ENDIAN__) 3916 rep << "endian:big;"; 3917#elif defined (__PDP_ENDIAN__) 3918 rep << "endian:pdp;"; 3919#endif 3920 3921 nub_thread_t thread = DNBProcessGetCurrentThread (pid); 3922 kern_return_t kr; 3923 3924#if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 3925 x86_thread_state_t gp_regs; 3926 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 3927 kr = thread_get_state (thread, x86_THREAD_STATE, 3928 (thread_state_t) &gp_regs, &gp_count); 3929 if (kr == KERN_SUCCESS) 3930 { 3931 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 3932 rep << "ptrsize:8;"; 3933 else 3934 rep << "ptrsize:4;"; 3935 } 3936#elif defined (__arm__) 3937 rep << "ptrsize:4;"; 3938#endif 3939 3940 return SendPacket (rep.str()); 3941} 3942 3943