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