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