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