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