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