1 //===-- RNBRemote.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Created by Greg Clayton on 12/12/07. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "RNBRemote.h" 14 15 #include <errno.h> 16 #include <mach-o/loader.h> 17 #include <mach/exception_types.h> 18 #include <signal.h> 19 #include <sys/stat.h> 20 #include <sys/sysctl.h> 21 #include <unistd.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 "DarwinLogCollector.h" 33 #include "DarwinLogEvent.h" 34 #include "JSON.h" 35 #include "JSONGenerator.h" 36 #include "JSONGenerator.h" 37 #include "MacOSX/Genealogy.h" 38 #include "OsLogger.h" 39 #include "RNBContext.h" 40 #include "RNBServices.h" 41 #include "RNBSocket.h" 42 #include "StdStringExtractor.h" 43 44 #include <compression.h> 45 46 #include <TargetConditionals.h> 47 #include <iomanip> 48 #include <memory> 49 #include <sstream> 50 #include <unordered_set> 51 52 // constants 53 54 static const std::string OS_LOG_EVENTS_KEY_NAME("events"); 55 static const std::string JSON_ASYNC_TYPE_KEY_NAME("type"); 56 static const DarwinLogEventVector::size_type DARWIN_LOG_MAX_EVENTS_PER_PACKET = 57 10; 58 59 // std::iostream formatting macros 60 #define RAW_HEXBASE std::setfill('0') << std::hex << std::right 61 #define HEXBASE '0' << 'x' << RAW_HEXBASE 62 #define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)((uint8_t)x)) 63 #define RAWHEX16 RAW_HEXBASE << std::setw(4) 64 #define RAWHEX32 RAW_HEXBASE << std::setw(8) 65 #define RAWHEX64 RAW_HEXBASE << std::setw(16) 66 #define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x)) 67 #define HEX16 HEXBASE << std::setw(4) 68 #define HEX32 HEXBASE << std::setw(8) 69 #define HEX64 HEXBASE << std::setw(16) 70 #define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x) * 2) << (x) 71 #define HEX(x) HEXBASE << std::setw(sizeof(x) * 2) << (x) 72 #define RAWHEX_SIZE(x, sz) RAW_HEXBASE << std::setw((sz)) << (x) 73 #define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x) 74 #define STRING_WIDTH(w) std::setfill(' ') << std::setw(w) 75 #define LEFT_STRING_WIDTH(s, w) \ 76 std::left << std::setfill(' ') << std::setw(w) << (s) << std::right 77 #define DECIMAL std::dec << std::setfill(' ') 78 #define DECIMAL_WIDTH(w) DECIMAL << std::setw(w) 79 #define FLOAT(n, d) \ 80 std::setfill(' ') << std::setw((n) + (d) + 1) << std::setprecision(d) \ 81 << std::showpoint << std::fixed 82 #define INDENT_WITH_SPACES(iword_idx) \ 83 std::setfill(' ') << std::setw((iword_idx)) << "" 84 #define INDENT_WITH_TABS(iword_idx) \ 85 std::setfill('\t') << std::setw((iword_idx)) << "" 86 // Class to handle communications via gdb remote protocol. 87 88 // Prototypes 89 90 static std::string binary_encode_string(const std::string &s); 91 92 // Decode a single hex character and return the hex value as a number or 93 // -1 if "ch" is not a hex character. 94 static inline int xdigit_to_sint(char ch) { 95 if (ch >= 'a' && ch <= 'f') 96 return 10 + ch - 'a'; 97 if (ch >= 'A' && ch <= 'F') 98 return 10 + ch - 'A'; 99 if (ch >= '0' && ch <= '9') 100 return ch - '0'; 101 return -1; 102 } 103 104 // Decode a single hex ASCII byte. Return -1 on failure, a value 0-255 105 // on success. 106 static inline int decoded_hex_ascii_char(const char *p) { 107 const int hi_nibble = xdigit_to_sint(p[0]); 108 if (hi_nibble == -1) 109 return -1; 110 const int lo_nibble = xdigit_to_sint(p[1]); 111 if (lo_nibble == -1) 112 return -1; 113 return (uint8_t)((hi_nibble << 4) + lo_nibble); 114 } 115 116 // Decode a hex ASCII string back into a string 117 static std::string decode_hex_ascii_string(const char *p, 118 uint32_t max_length = UINT32_MAX) { 119 std::string arg; 120 if (p) { 121 for (const char *c = p; ((c - p) / 2) < max_length; c += 2) { 122 int ch = decoded_hex_ascii_char(c); 123 if (ch == -1) 124 break; 125 else 126 arg.push_back(ch); 127 } 128 } 129 return arg; 130 } 131 132 uint64_t decode_uint64(const char *p, int base, char **end = nullptr, 133 uint64_t fail_value = 0) { 134 nub_addr_t addr = strtoull(p, end, 16); 135 if (addr == 0 && errno != 0) 136 return fail_value; 137 return addr; 138 } 139 140 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, 141 va_list args); 142 143 #if defined(__APPLE__) && \ 144 (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000) 145 // from System.framework/Versions/B/PrivateHeaders/sys/codesign.h 146 extern "C" { 147 #define CS_OPS_STATUS 0 /* return status */ 148 #define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */ 149 int csops(pid_t pid, unsigned int ops, void *useraddr, size_t usersize); 150 151 // from rootless.h 152 bool rootless_allows_task_for_pid(pid_t pid); 153 154 // from sys/csr.h 155 typedef uint32_t csr_config_t; 156 #define CSR_ALLOW_TASK_FOR_PID (1 << 2) 157 int csr_check(csr_config_t mask); 158 } 159 #endif 160 161 RNBRemote::RNBRemote() 162 : m_ctx(), m_comm(), m_arch(), m_continue_thread(-1), m_thread(-1), 163 m_mutex(), m_dispatch_queue_offsets(), 164 m_dispatch_queue_offsets_addr(INVALID_NUB_ADDRESS), 165 m_qSymbol_index(UINT32_MAX), m_packets_recvd(0), m_packets(), 166 m_rx_packets(), m_rx_partial_data(), m_rx_pthread(0), 167 m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4), 168 m_extended_mode(false), m_noack_mode(false), 169 m_thread_suffix_supported(false), m_list_threads_in_stop_reply(false), 170 m_compression_minsize(384), m_enable_compression_next_send_packet(false), 171 m_compression_mode(compression_types::none) { 172 DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); 173 CreatePacketTable(); 174 } 175 176 RNBRemote::~RNBRemote() { 177 DNBLogThreadedIf(LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); 178 StopReadRemoteDataThread(); 179 } 180 181 void RNBRemote::CreatePacketTable() { 182 // Step required to add new packets: 183 // 1 - Add new enumeration to RNBRemote::PacketEnum 184 // 2 - Create the RNBRemote::HandlePacket_ function if a new function is 185 // needed 186 // 3 - Register the Packet definition with any needed callbacks in this 187 // function 188 // - If no response is needed for a command, then use NULL for the 189 // normal callback 190 // - If the packet is not supported while the target is running, use 191 // NULL for the async callback 192 // 4 - If the packet is a standard packet (starts with a '$' character 193 // followed by the payload and then '#' and checksum, then you are done 194 // else go on to step 5 195 // 5 - if the packet is a fixed length packet: 196 // - modify the switch statement for the first character in the payload 197 // in RNBRemote::CommDataReceived so it doesn't reject the new packet 198 // type as invalid 199 // - modify the switch statement for the first character in the payload 200 // in RNBRemote::GetPacketPayload and make sure the payload of the 201 // packet 202 // is returned correctly 203 204 std::vector<Packet> &t = m_packets; 205 t.push_back(Packet(ack, NULL, NULL, "+", "ACK")); 206 t.push_back(Packet(nack, NULL, NULL, "-", "!ACK")); 207 t.push_back(Packet(read_memory, &RNBRemote::HandlePacket_m, NULL, "m", 208 "Read memory")); 209 t.push_back(Packet(read_register, &RNBRemote::HandlePacket_p, NULL, "p", 210 "Read one register")); 211 t.push_back(Packet(read_general_regs, &RNBRemote::HandlePacket_g, NULL, "g", 212 "Read registers")); 213 t.push_back(Packet(write_memory, &RNBRemote::HandlePacket_M, NULL, "M", 214 "Write memory")); 215 t.push_back(Packet(write_register, &RNBRemote::HandlePacket_P, NULL, "P", 216 "Write one register")); 217 t.push_back(Packet(write_general_regs, &RNBRemote::HandlePacket_G, NULL, "G", 218 "Write registers")); 219 t.push_back(Packet(insert_mem_bp, &RNBRemote::HandlePacket_z, NULL, "Z0", 220 "Insert memory breakpoint")); 221 t.push_back(Packet(remove_mem_bp, &RNBRemote::HandlePacket_z, NULL, "z0", 222 "Remove memory breakpoint")); 223 t.push_back(Packet(single_step, &RNBRemote::HandlePacket_s, NULL, "s", 224 "Single step")); 225 t.push_back(Packet(cont, &RNBRemote::HandlePacket_c, NULL, "c", "continue")); 226 t.push_back(Packet(single_step_with_sig, &RNBRemote::HandlePacket_S, NULL, 227 "S", "Single step with signal")); 228 t.push_back( 229 Packet(set_thread, &RNBRemote::HandlePacket_H, NULL, "H", "Set thread")); 230 t.push_back(Packet(halt, &RNBRemote::HandlePacket_last_signal, 231 &RNBRemote::HandlePacket_stop_process, "\x03", "^C")); 232 // t.push_back (Packet (use_extended_mode, 233 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode")); 234 t.push_back(Packet(why_halted, &RNBRemote::HandlePacket_last_signal, NULL, 235 "?", "Why did target halt")); 236 t.push_back( 237 Packet(set_argv, &RNBRemote::HandlePacket_A, NULL, "A", "Set argv")); 238 // t.push_back (Packet (set_bp, 239 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear 240 // breakpoint")); 241 t.push_back(Packet(continue_with_sig, &RNBRemote::HandlePacket_C, NULL, "C", 242 "Continue with signal")); 243 t.push_back(Packet(detach, &RNBRemote::HandlePacket_D, NULL, "D", 244 "Detach gdb from remote system")); 245 // t.push_back (Packet (step_inferior_one_cycle, 246 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one 247 // clock cycle")); 248 // t.push_back (Packet (signal_and_step_inf_one_cycle, 249 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then 250 // step one clock cycle")); 251 t.push_back(Packet(kill, &RNBRemote::HandlePacket_k, NULL, "k", "Kill")); 252 // t.push_back (Packet (restart, 253 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior")); 254 // t.push_back (Packet (search_mem_backwards, 255 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory 256 // backwards")); 257 t.push_back(Packet(thread_alive_p, &RNBRemote::HandlePacket_T, NULL, "T", 258 "Is thread alive")); 259 t.push_back(Packet(query_supported_features, 260 &RNBRemote::HandlePacket_qSupported, NULL, "qSupported", 261 "Query about supported features")); 262 t.push_back(Packet(vattach, &RNBRemote::HandlePacket_v, NULL, "vAttach", 263 "Attach to a new process")); 264 t.push_back(Packet(vattachwait, &RNBRemote::HandlePacket_v, NULL, 265 "vAttachWait", 266 "Wait for a process to start up then attach to it")); 267 t.push_back(Packet(vattachorwait, &RNBRemote::HandlePacket_v, NULL, 268 "vAttachOrWait", "Attach to the process or if it doesn't " 269 "exist, wait for the process to start up " 270 "then attach to it")); 271 t.push_back(Packet(vattachname, &RNBRemote::HandlePacket_v, NULL, 272 "vAttachName", "Attach to an existing process by name")); 273 t.push_back(Packet(vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, 274 "vCont;", "Verbose resume with thread actions")); 275 t.push_back(Packet(vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, 276 "vCont?", 277 "List valid continue-with-thread-actions actions")); 278 t.push_back(Packet(read_data_from_memory, &RNBRemote::HandlePacket_x, NULL, 279 "x", "Read data from memory")); 280 t.push_back(Packet(write_data_to_memory, &RNBRemote::HandlePacket_X, NULL, 281 "X", "Write data to memory")); 282 // t.push_back (Packet (insert_hardware_bp, 283 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware 284 // breakpoint")); 285 // t.push_back (Packet (remove_hardware_bp, 286 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware 287 // breakpoint")); 288 t.push_back(Packet(insert_write_watch_bp, &RNBRemote::HandlePacket_z, NULL, 289 "Z2", "Insert write watchpoint")); 290 t.push_back(Packet(remove_write_watch_bp, &RNBRemote::HandlePacket_z, NULL, 291 "z2", "Remove write watchpoint")); 292 t.push_back(Packet(insert_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, 293 "Z3", "Insert read watchpoint")); 294 t.push_back(Packet(remove_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, 295 "z3", "Remove read watchpoint")); 296 t.push_back(Packet(insert_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, 297 "Z4", "Insert access watchpoint")); 298 t.push_back(Packet(remove_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, 299 "z4", "Remove access watchpoint")); 300 t.push_back(Packet(query_monitor, &RNBRemote::HandlePacket_qRcmd, NULL, 301 "qRcmd", "Monitor command")); 302 t.push_back(Packet(query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL, 303 "qC", "Query current thread ID")); 304 t.push_back(Packet(query_echo, &RNBRemote::HandlePacket_qEcho, NULL, "qEcho:", 305 "Echo the packet back to allow the debugger to sync up " 306 "with this server")); 307 t.push_back(Packet(query_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL, 308 "qGetPid", "Query process id")); 309 t.push_back(Packet(query_thread_ids_first, 310 &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo", 311 "Get list of active threads (first req)")); 312 t.push_back(Packet(query_thread_ids_subsequent, 313 &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo", 314 "Get list of active threads (subsequent req)")); 315 // APPLE LOCAL: qThreadStopInfo 316 // syntax: qThreadStopInfoTTTT 317 // TTTT is hex thread ID 318 t.push_back(Packet(query_thread_stop_info, 319 &RNBRemote::HandlePacket_qThreadStopInfo, NULL, 320 "qThreadStopInfo", 321 "Get detailed info on why the specified thread stopped")); 322 t.push_back(Packet(query_thread_extra_info, 323 &RNBRemote::HandlePacket_qThreadExtraInfo, NULL, 324 "qThreadExtraInfo", "Get printable status of a thread")); 325 // t.push_back (Packet (query_image_offsets, 326 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qOffsets", "Report offset 327 // of loaded program")); 328 t.push_back(Packet( 329 query_launch_success, &RNBRemote::HandlePacket_qLaunchSuccess, NULL, 330 "qLaunchSuccess", "Report the success or failure of the launch attempt")); 331 t.push_back( 332 Packet(query_register_info, &RNBRemote::HandlePacket_qRegisterInfo, NULL, 333 "qRegisterInfo", 334 "Dynamically discover remote register context information.")); 335 t.push_back(Packet( 336 query_shlib_notify_info_addr, &RNBRemote::HandlePacket_qShlibInfoAddr, 337 NULL, "qShlibInfoAddr", "Returns the address that contains info needed " 338 "for getting shared library notifications")); 339 t.push_back(Packet(query_step_packet_supported, 340 &RNBRemote::HandlePacket_qStepPacketSupported, NULL, 341 "qStepPacketSupported", 342 "Replys with OK if the 's' packet is supported.")); 343 t.push_back( 344 Packet(query_vattachorwait_supported, 345 &RNBRemote::HandlePacket_qVAttachOrWaitSupported, NULL, 346 "qVAttachOrWaitSupported", 347 "Replys with OK if the 'vAttachOrWait' packet is supported.")); 348 t.push_back( 349 Packet(query_sync_thread_state_supported, 350 &RNBRemote::HandlePacket_qSyncThreadStateSupported, NULL, 351 "qSyncThreadStateSupported", 352 "Replys with OK if the 'QSyncThreadState:' packet is supported.")); 353 t.push_back(Packet( 354 query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo", 355 "Replies with multiple 'key:value;' tuples appended to each other.")); 356 t.push_back(Packet( 357 query_gdb_server_version, &RNBRemote::HandlePacket_qGDBServerVersion, 358 NULL, "qGDBServerVersion", 359 "Replies with multiple 'key:value;' tuples appended to each other.")); 360 t.push_back(Packet( 361 query_process_info, &RNBRemote::HandlePacket_qProcessInfo, NULL, 362 "qProcessInfo", 363 "Replies with multiple 'key:value;' tuples appended to each other.")); 364 t.push_back(Packet( 365 query_symbol_lookup, &RNBRemote::HandlePacket_qSymbol, NULL, "qSymbol:", 366 "Notify that host debugger is ready to do symbol lookups")); 367 t.push_back(Packet(json_query_thread_extended_info, 368 &RNBRemote::HandlePacket_jThreadExtendedInfo, NULL, 369 "jThreadExtendedInfo", 370 "Replies with JSON data of thread extended information.")); 371 t.push_back(Packet(json_query_get_loaded_dynamic_libraries_infos, 372 &RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos, 373 NULL, "jGetLoadedDynamicLibrariesInfos", 374 "Replies with JSON data of all the shared libraries " 375 "loaded in this process.")); 376 t.push_back( 377 Packet(json_query_threads_info, &RNBRemote::HandlePacket_jThreadsInfo, 378 NULL, "jThreadsInfo", 379 "Replies with JSON data with information about all threads.")); 380 t.push_back(Packet(json_query_get_shared_cache_info, 381 &RNBRemote::HandlePacket_jGetSharedCacheInfo, NULL, 382 "jGetSharedCacheInfo", "Replies with JSON data about the " 383 "location and uuid of the shared " 384 "cache in the inferior process.")); 385 t.push_back(Packet(start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode, 386 NULL, "QStartNoAckMode", 387 "Request that " DEBUGSERVER_PROGRAM_NAME 388 " stop acking remote protocol packets")); 389 t.push_back(Packet(prefix_reg_packets_with_tid, 390 &RNBRemote::HandlePacket_QThreadSuffixSupported, NULL, 391 "QThreadSuffixSupported", 392 "Check if thread specific packets (register packets 'g', " 393 "'G', 'p', and 'P') support having the thread ID appended " 394 "to the end of the command")); 395 t.push_back(Packet(set_logging_mode, &RNBRemote::HandlePacket_QSetLogging, 396 NULL, "QSetLogging:", "Check if register packets ('g', " 397 "'G', 'p', and 'P' support having " 398 "the thread ID prefix")); 399 t.push_back(Packet( 400 set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize, NULL, 401 "QSetMaxPacketSize:", 402 "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle")); 403 t.push_back(Packet( 404 set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize, NULL, 405 "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME 406 " the max sized payload gdb can handle")); 407 t.push_back( 408 Packet(set_environment_variable, &RNBRemote::HandlePacket_QEnvironment, 409 NULL, "QEnvironment:", 410 "Add an environment variable to the inferior's environment")); 411 t.push_back( 412 Packet(set_environment_variable_hex, 413 &RNBRemote::HandlePacket_QEnvironmentHexEncoded, NULL, 414 "QEnvironmentHexEncoded:", 415 "Add an environment variable to the inferior's environment")); 416 t.push_back(Packet(set_launch_arch, &RNBRemote::HandlePacket_QLaunchArch, 417 NULL, "QLaunchArch:", "Set the architecture to use when " 418 "launching a process for hosts that " 419 "can run multiple architecture " 420 "slices from universal files.")); 421 t.push_back(Packet(set_disable_aslr, &RNBRemote::HandlePacket_QSetDisableASLR, 422 NULL, "QSetDisableASLR:", 423 "Set whether to disable ASLR when launching the process " 424 "with the set argv ('A') packet")); 425 t.push_back(Packet(set_stdin, &RNBRemote::HandlePacket_QSetSTDIO, NULL, 426 "QSetSTDIN:", "Set the standard input for a process to be " 427 "launched with the 'A' packet")); 428 t.push_back(Packet(set_stdout, &RNBRemote::HandlePacket_QSetSTDIO, NULL, 429 "QSetSTDOUT:", "Set the standard output for a process to " 430 "be launched with the 'A' packet")); 431 t.push_back(Packet(set_stderr, &RNBRemote::HandlePacket_QSetSTDIO, NULL, 432 "QSetSTDERR:", "Set the standard error for a process to " 433 "be launched with the 'A' packet")); 434 t.push_back(Packet(set_working_dir, &RNBRemote::HandlePacket_QSetWorkingDir, 435 NULL, "QSetWorkingDir:", "Set the working directory for a " 436 "process to be launched with the " 437 "'A' packet")); 438 t.push_back(Packet(set_list_threads_in_stop_reply, 439 &RNBRemote::HandlePacket_QListThreadsInStopReply, NULL, 440 "QListThreadsInStopReply", 441 "Set if the 'threads' key should be added to the stop " 442 "reply packets with a list of all thread IDs.")); 443 t.push_back(Packet( 444 sync_thread_state, &RNBRemote::HandlePacket_QSyncThreadState, NULL, 445 "QSyncThreadState:", "Do whatever is necessary to make sure 'thread' is " 446 "in a safe state to call functions on.")); 447 // t.push_back (Packet (pass_signals_to_inferior, 448 // &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify 449 // which signals are passed to the inferior")); 450 t.push_back(Packet(allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, 451 NULL, "_M", "Allocate memory in the inferior process.")); 452 t.push_back(Packet(deallocate_memory, 453 &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", 454 "Deallocate memory in the inferior process.")); 455 t.push_back(Packet( 456 save_register_state, &RNBRemote::HandlePacket_SaveRegisterState, NULL, 457 "QSaveRegisterState", "Save the register state for the current thread " 458 "and return a decimal save ID.")); 459 t.push_back(Packet(restore_register_state, 460 &RNBRemote::HandlePacket_RestoreRegisterState, NULL, 461 "QRestoreRegisterState:", 462 "Restore the register state given a save ID previously " 463 "returned from a call to QSaveRegisterState.")); 464 t.push_back(Packet( 465 memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL, 466 "qMemoryRegionInfo", "Return size and attributes of a memory region that " 467 "contains the given address")); 468 t.push_back(Packet(get_profile_data, &RNBRemote::HandlePacket_GetProfileData, 469 NULL, "qGetProfileData", 470 "Return profiling data of the current target.")); 471 t.push_back(Packet(set_enable_profiling, 472 &RNBRemote::HandlePacket_SetEnableAsyncProfiling, NULL, 473 "QSetEnableAsyncProfiling", 474 "Enable or disable the profiling of current target.")); 475 t.push_back(Packet(enable_compression, 476 &RNBRemote::HandlePacket_QEnableCompression, NULL, 477 "QEnableCompression:", 478 "Enable compression for the remainder of the connection")); 479 t.push_back(Packet(watchpoint_support_info, 480 &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, 481 "qWatchpointSupportInfo", 482 "Return the number of supported hardware watchpoints")); 483 t.push_back(Packet(set_process_event, 484 &RNBRemote::HandlePacket_QSetProcessEvent, NULL, 485 "QSetProcessEvent:", "Set a process event, to be passed " 486 "to the process, can be set before " 487 "the process is started, or after.")); 488 t.push_back( 489 Packet(set_detach_on_error, &RNBRemote::HandlePacket_QSetDetachOnError, 490 NULL, "QSetDetachOnError:", 491 "Set whether debugserver will detach (1) or kill (0) from the " 492 "process it is controlling if it loses connection to lldb.")); 493 t.push_back(Packet( 494 speed_test, &RNBRemote::HandlePacket_qSpeedTest, NULL, "qSpeedTest:", 495 "Test the maximum speed at which packet can be sent/received.")); 496 t.push_back(Packet(query_transfer, &RNBRemote::HandlePacket_qXfer, NULL, 497 "qXfer:", "Support the qXfer packet.")); 498 t.push_back( 499 Packet(query_supported_async_json_packets, 500 &RNBRemote::HandlePacket_qStructuredDataPlugins, NULL, 501 "qStructuredDataPlugins", 502 "Query for the structured data plugins supported by the remote.")); 503 t.push_back( 504 Packet(configure_darwin_log, &RNBRemote::HandlePacket_QConfigureDarwinLog, 505 NULL, "QConfigureDarwinLog:", 506 "Configure the DarwinLog structured data plugin support.")); 507 } 508 509 void RNBRemote::FlushSTDIO() { 510 if (m_ctx.HasValidProcessID()) { 511 nub_process_t pid = m_ctx.ProcessID(); 512 char buf[256]; 513 nub_size_t count; 514 do { 515 count = DNBProcessGetAvailableSTDOUT(pid, buf, sizeof(buf)); 516 if (count > 0) { 517 SendSTDOUTPacket(buf, count); 518 } 519 } while (count > 0); 520 521 do { 522 count = DNBProcessGetAvailableSTDERR(pid, buf, sizeof(buf)); 523 if (count > 0) { 524 SendSTDERRPacket(buf, count); 525 } 526 } while (count > 0); 527 } 528 } 529 530 void RNBRemote::SendAsyncProfileData() { 531 if (m_ctx.HasValidProcessID()) { 532 nub_process_t pid = m_ctx.ProcessID(); 533 char buf[1024]; 534 nub_size_t count; 535 do { 536 count = DNBProcessGetAvailableProfileData(pid, buf, sizeof(buf)); 537 if (count > 0) { 538 SendAsyncProfileDataPacket(buf, count); 539 } 540 } while (count > 0); 541 } 542 } 543 544 void RNBRemote::SendAsyncDarwinLogData() { 545 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): enter", __FUNCTION__); 546 547 if (!m_ctx.HasValidProcessID()) { 548 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): ignoring due to" 549 "invalid process id", 550 __FUNCTION__); 551 return; 552 } 553 554 nub_process_t pid = m_ctx.ProcessID(); 555 DarwinLogEventVector::size_type entry_count = 0; 556 557 // NOTE: the current looping structure here does nothing 558 // to guarantee that we can send off async packets faster 559 // than we generate them. It will keep sending as long 560 // as there's data to send. 561 do { 562 DarwinLogEventVector events = DNBProcessGetAvailableDarwinLogEvents(pid); 563 entry_count = events.size(); 564 565 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): outer loop enter", 566 __FUNCTION__); 567 568 for (DarwinLogEventVector::size_type base_entry = 0; 569 base_entry < entry_count; 570 base_entry += DARWIN_LOG_MAX_EVENTS_PER_PACKET) { 571 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): inner loop enter", 572 __FUNCTION__); 573 574 // We limit the total number of entries we pack 575 // into a single JSON async packet just so it 576 // doesn't get too large. 577 JSONGenerator::Dictionary async_dictionary; 578 579 // Specify the type of the JSON async data we're sending. 580 async_dictionary.AddStringItem(JSON_ASYNC_TYPE_KEY_NAME, "DarwinLog"); 581 582 // Create an array entry in the dictionary to hold all 583 // the events going in this packet. 584 JSONGenerator::ArraySP events_array(new JSONGenerator::Array()); 585 async_dictionary.AddItem(OS_LOG_EVENTS_KEY_NAME, events_array); 586 587 // We bundle up to DARWIN_LOG_MAX_EVENTS_PER_PACKET events in 588 // a single packet. 589 const auto inner_loop_bound = 590 std::min(base_entry + DARWIN_LOG_MAX_EVENTS_PER_PACKET, entry_count); 591 for (DarwinLogEventVector::size_type i = base_entry; i < inner_loop_bound; 592 ++i) { 593 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): adding " 594 "entry index %lu to the JSON packet", 595 __FUNCTION__, i); 596 events_array->AddItem(events[i]); 597 } 598 599 // Send off the packet. 600 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): sending JSON " 601 "packet, %lu entries remain", 602 __FUNCTION__, entry_count - inner_loop_bound); 603 SendAsyncJSONPacket(async_dictionary); 604 } 605 606 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): outer loop exit", 607 __FUNCTION__); 608 609 } while (entry_count > 0); 610 611 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): exit", 612 __PRETTY_FUNCTION__); 613 } 614 615 rnb_err_t RNBRemote::SendHexEncodedBytePacket(const char *header, 616 const void *buf, size_t buf_len, 617 const char *footer) { 618 std::ostringstream packet_sstrm; 619 // Append the header cstr if there was one 620 if (header && header[0]) 621 packet_sstrm << header; 622 nub_size_t i; 623 const uint8_t *ubuf8 = (const uint8_t *)buf; 624 for (i = 0; i < buf_len; i++) { 625 packet_sstrm << RAWHEX8(ubuf8[i]); 626 } 627 // Append the footer cstr if there was one 628 if (footer && footer[0]) 629 packet_sstrm << footer; 630 631 return SendPacket(packet_sstrm.str()); 632 } 633 634 rnb_err_t RNBRemote::SendSTDOUTPacket(char *buf, nub_size_t buf_size) { 635 if (buf_size == 0) 636 return rnb_success; 637 return SendHexEncodedBytePacket("O", buf, buf_size, NULL); 638 } 639 640 rnb_err_t RNBRemote::SendSTDERRPacket(char *buf, nub_size_t buf_size) { 641 if (buf_size == 0) 642 return rnb_success; 643 return SendHexEncodedBytePacket("O", buf, buf_size, NULL); 644 } 645 646 // This makes use of asynchronous bit 'A' in the gdb remote protocol. 647 rnb_err_t RNBRemote::SendAsyncProfileDataPacket(char *buf, 648 nub_size_t buf_size) { 649 if (buf_size == 0) 650 return rnb_success; 651 652 std::string packet("A"); 653 packet.append(buf, buf_size); 654 return SendPacket(packet); 655 } 656 657 rnb_err_t 658 RNBRemote::SendAsyncJSONPacket(const JSONGenerator::Dictionary &dictionary) { 659 std::ostringstream stream; 660 // We're choosing something that is easy to spot if we somehow get one 661 // of these coming out at the wrong time (i.e. when the remote side 662 // is not waiting for a process control completion response). 663 stream << "JSON-async:"; 664 dictionary.Dump(stream); 665 const std::string payload = binary_encode_string(stream.str()); 666 return SendPacket(payload); 667 } 668 669 // Given a std::string packet contents to send, possibly encode/compress it. 670 // If compression is enabled, the returned std::string will be in one of two 671 // forms: 672 // 673 // N<original packet contents uncompressed> 674 // C<size of original decompressed packet>:<packet compressed with the 675 // requested compression scheme> 676 // 677 // If compression is not requested, the original packet contents are returned 678 679 std::string RNBRemote::CompressString(const std::string &orig) { 680 std::string compressed; 681 compression_types compression_type = GetCompressionType(); 682 if (compression_type != compression_types::none) { 683 bool compress_this_packet = false; 684 685 if (orig.size() > m_compression_minsize) { 686 compress_this_packet = true; 687 } 688 689 if (compress_this_packet) { 690 const size_t encoded_data_buf_size = orig.size() + 128; 691 std::vector<uint8_t> encoded_data(encoded_data_buf_size); 692 size_t compressed_size = 0; 693 694 // Allocate a scratch buffer for libcompression the first 695 // time we see a different compression type; reuse it in 696 // all compression_encode_buffer calls so it doesn't need 697 // to allocate / free its own scratch buffer each time. 698 // This buffer will only be freed when compression type 699 // changes; otherwise it will persist until debugserver 700 // exit. 701 702 static compression_types g_libcompress_scratchbuf_type = compression_types::none; 703 static void *g_libcompress_scratchbuf = nullptr; 704 705 if (g_libcompress_scratchbuf_type != compression_type) { 706 if (g_libcompress_scratchbuf) { 707 free (g_libcompress_scratchbuf); 708 g_libcompress_scratchbuf = nullptr; 709 } 710 size_t scratchbuf_size = 0; 711 switch (compression_type) { 712 case compression_types::lz4: 713 scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_LZ4_RAW); 714 break; 715 case compression_types::zlib_deflate: 716 scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_ZLIB); 717 break; 718 case compression_types::lzma: 719 scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_LZMA); 720 break; 721 case compression_types::lzfse: 722 scratchbuf_size = compression_encode_scratch_buffer_size (COMPRESSION_LZFSE); 723 break; 724 default: 725 break; 726 } 727 if (scratchbuf_size > 0) { 728 g_libcompress_scratchbuf = (void*) malloc (scratchbuf_size); 729 g_libcompress_scratchbuf_type = compression_type; 730 } 731 } 732 733 if (compression_type == compression_types::lz4) { 734 compressed_size = compression_encode_buffer( 735 encoded_data.data(), encoded_data_buf_size, 736 (const uint8_t *)orig.c_str(), orig.size(), 737 g_libcompress_scratchbuf, 738 COMPRESSION_LZ4_RAW); 739 } 740 if (compression_type == compression_types::zlib_deflate) { 741 compressed_size = compression_encode_buffer( 742 encoded_data.data(), encoded_data_buf_size, 743 (const uint8_t *)orig.c_str(), orig.size(), 744 g_libcompress_scratchbuf, 745 COMPRESSION_ZLIB); 746 } 747 if (compression_type == compression_types::lzma) { 748 compressed_size = compression_encode_buffer( 749 encoded_data.data(), encoded_data_buf_size, 750 (const uint8_t *)orig.c_str(), orig.size(), 751 g_libcompress_scratchbuf, 752 COMPRESSION_LZMA); 753 } 754 if (compression_type == compression_types::lzfse) { 755 compressed_size = compression_encode_buffer( 756 encoded_data.data(), encoded_data_buf_size, 757 (const uint8_t *)orig.c_str(), orig.size(), 758 g_libcompress_scratchbuf, 759 COMPRESSION_LZFSE); 760 } 761 762 if (compressed_size > 0) { 763 compressed.clear(); 764 compressed.reserve(compressed_size); 765 compressed = "C"; 766 char numbuf[16]; 767 snprintf(numbuf, sizeof(numbuf), "%zu:", orig.size()); 768 numbuf[sizeof(numbuf) - 1] = '\0'; 769 compressed.append(numbuf); 770 771 for (size_t i = 0; i < compressed_size; i++) { 772 uint8_t byte = encoded_data[i]; 773 if (byte == '#' || byte == '$' || byte == '}' || byte == '*' || 774 byte == '\0') { 775 compressed.push_back(0x7d); 776 compressed.push_back(byte ^ 0x20); 777 } else { 778 compressed.push_back(byte); 779 } 780 } 781 } else { 782 compressed = "N" + orig; 783 } 784 } else { 785 compressed = "N" + orig; 786 } 787 } else { 788 compressed = orig; 789 } 790 791 return compressed; 792 } 793 794 rnb_err_t RNBRemote::SendPacket(const std::string &s) { 795 DNBLogThreadedIf(LOG_RNB_MAX, "%8d RNBRemote::%s (%s) called", 796 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 797 __FUNCTION__, s.c_str()); 798 799 std::string s_compressed = CompressString(s); 800 801 std::string sendpacket = "$" + s_compressed + "#"; 802 int cksum = 0; 803 char hexbuf[5]; 804 805 if (m_noack_mode) { 806 sendpacket += "00"; 807 } else { 808 for (size_t i = 0; i != s_compressed.size(); ++i) 809 cksum += s_compressed[i]; 810 snprintf(hexbuf, sizeof hexbuf, "%02x", cksum & 0xff); 811 sendpacket += hexbuf; 812 } 813 814 rnb_err_t err = m_comm.Write(sendpacket.c_str(), sendpacket.size()); 815 if (err != rnb_success) 816 return err; 817 818 if (m_noack_mode) 819 return rnb_success; 820 821 std::string reply; 822 RNBRemote::Packet packet; 823 err = GetPacket(reply, packet, true); 824 825 if (err != rnb_success) { 826 DNBLogThreadedIf(LOG_RNB_REMOTE, 827 "%8d RNBRemote::%s (%s) got error trying to get reply...", 828 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 829 __FUNCTION__, sendpacket.c_str()); 830 return err; 831 } 832 833 DNBLogThreadedIf(LOG_RNB_MAX, "%8d RNBRemote::%s (%s) got reply: '%s'", 834 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 835 __FUNCTION__, sendpacket.c_str(), reply.c_str()); 836 837 if (packet.type == ack) 838 return rnb_success; 839 840 // Should we try to resend the packet at this layer? 841 // if (packet.command == nack) 842 return rnb_err; 843 } 844 845 /* Get a packet via gdb remote protocol. 846 Strip off the prefix/suffix, verify the checksum to make sure 847 a valid packet was received, send an ACK if they match. */ 848 849 rnb_err_t RNBRemote::GetPacketPayload(std::string &return_packet) { 850 // DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s called", 851 // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 852 853 PThreadMutex::Locker locker(m_mutex); 854 if (m_rx_packets.empty()) { 855 // Only reset the remote command available event if we have no more packets 856 m_ctx.Events().ResetEvents(RNBContext::event_read_packet_available); 857 // DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s error: no packets 858 // available...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 859 // __FUNCTION__); 860 return rnb_err; 861 } 862 863 // DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s has %u queued packets", 864 // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, 865 // m_rx_packets.size()); 866 return_packet.swap(m_rx_packets.front()); 867 m_rx_packets.pop_front(); 868 locker.Reset(); // Release our lock on the mutex 869 870 if (m_rx_packets.empty()) { 871 // Reset the remote command available event if we have no more packets 872 m_ctx.Events().ResetEvents(RNBContext::event_read_packet_available); 873 } 874 875 // DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'", 876 // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, 877 // return_packet.c_str()); 878 879 switch (return_packet[0]) { 880 case '+': 881 case '-': 882 case '\x03': 883 break; 884 885 case '$': { 886 long packet_checksum = 0; 887 if (!m_noack_mode) { 888 for (size_t i = return_packet.size() - 2; i < return_packet.size(); ++i) { 889 char checksum_char = tolower(return_packet[i]); 890 if (!isxdigit(checksum_char)) { 891 m_comm.Write("-", 1); 892 DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s error: packet " 893 "with invalid checksum characters: " 894 "%s", 895 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 896 __FUNCTION__, return_packet.c_str()); 897 return rnb_err; 898 } 899 } 900 packet_checksum = 901 strtol(&return_packet[return_packet.size() - 2], NULL, 16); 902 } 903 904 return_packet.erase(0, 1); // Strip the leading '$' 905 return_packet.erase(return_packet.size() - 3); // Strip the #XX checksum 906 907 if (!m_noack_mode) { 908 // Compute the checksum 909 int computed_checksum = 0; 910 for (std::string::iterator it = return_packet.begin(); 911 it != return_packet.end(); ++it) { 912 computed_checksum += *it; 913 } 914 915 if (packet_checksum == (computed_checksum & 0xff)) { 916 // DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for 917 // '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 918 // __FUNCTION__, return_packet.c_str()); 919 m_comm.Write("+", 1); 920 } else { 921 DNBLogThreadedIf( 922 LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s' (error: " 923 "packet checksum mismatch (0x%2.2lx != 0x%2.2x))", 924 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, 925 return_packet.c_str(), packet_checksum, computed_checksum); 926 m_comm.Write("-", 1); 927 return rnb_err; 928 } 929 } 930 } break; 931 932 default: 933 DNBLogThreadedIf(LOG_RNB_REMOTE, 934 "%8u RNBRemote::%s tossing unexpected packet???? %s", 935 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 936 __FUNCTION__, return_packet.c_str()); 937 if (!m_noack_mode) 938 m_comm.Write("-", 1); 939 return rnb_err; 940 } 941 942 return rnb_success; 943 } 944 945 rnb_err_t RNBRemote::HandlePacket_UNIMPLEMENTED(const char *p) { 946 DNBLogThreadedIf(LOG_RNB_MAX, "%8u RNBRemote::%s(\"%s\")", 947 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 948 __FUNCTION__, p ? p : "NULL"); 949 return SendPacket(""); 950 } 951 952 rnb_err_t RNBRemote::HandlePacket_ILLFORMED(const char *file, int line, 953 const char *p, 954 const char *description) { 955 DNBLogThreadedIf(LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)", 956 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file, 957 line, __FUNCTION__, p); 958 return SendPacket("E03"); 959 } 960 961 rnb_err_t RNBRemote::GetPacket(std::string &packet_payload, 962 RNBRemote::Packet &packet_info, bool wait) { 963 std::string payload; 964 rnb_err_t err = GetPacketPayload(payload); 965 if (err != rnb_success) { 966 PThreadEvent &events = m_ctx.Events(); 967 nub_event_t set_events = events.GetEventBits(); 968 // TODO: add timeout version of GetPacket?? We would then need to pass 969 // that timeout value along to DNBProcessTimedWaitForEvent. 970 if (!wait || ((set_events & RNBContext::event_read_thread_running) == 0)) 971 return err; 972 973 const nub_event_t events_to_wait_for = 974 RNBContext::event_read_packet_available | 975 RNBContext::event_read_thread_exiting; 976 977 while ((set_events = events.WaitForSetEvents(events_to_wait_for)) != 0) { 978 if (set_events & RNBContext::event_read_packet_available) { 979 // Try the queue again now that we got an event 980 err = GetPacketPayload(payload); 981 if (err == rnb_success) 982 break; 983 } 984 985 if (set_events & RNBContext::event_read_thread_exiting) 986 err = rnb_not_connected; 987 988 if (err == rnb_not_connected) 989 return err; 990 } 991 while (err == rnb_err) 992 ; 993 994 if (set_events == 0) 995 err = rnb_not_connected; 996 } 997 998 if (err == rnb_success) { 999 Packet::iterator it; 1000 for (it = m_packets.begin(); it != m_packets.end(); ++it) { 1001 if (payload.compare(0, it->abbrev.size(), it->abbrev) == 0) 1002 break; 1003 } 1004 1005 // A packet we don't have an entry for. This can happen when we 1006 // get a packet that we don't know about or support. We just reply 1007 // accordingly and go on. 1008 if (it == m_packets.end()) { 1009 DNBLogThreadedIf(LOG_RNB_PACKETS, "unimplemented packet: '%s'", 1010 payload.c_str()); 1011 HandlePacket_UNIMPLEMENTED(payload.c_str()); 1012 return rnb_err; 1013 } else { 1014 packet_info = *it; 1015 packet_payload = payload; 1016 } 1017 } 1018 return err; 1019 } 1020 1021 rnb_err_t RNBRemote::HandleAsyncPacket(PacketEnum *type) { 1022 DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s", 1023 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 1024 __FUNCTION__); 1025 static DNBTimer g_packetTimer(true); 1026 rnb_err_t err = rnb_err; 1027 std::string packet_data; 1028 RNBRemote::Packet packet_info; 1029 err = GetPacket(packet_data, packet_info, false); 1030 1031 if (err == rnb_success) { 1032 if (!packet_data.empty() && isprint(packet_data[0])) 1033 DNBLogThreadedIf(LOG_RNB_REMOTE | LOG_RNB_PACKETS, 1034 "HandleAsyncPacket (\"%s\");", packet_data.c_str()); 1035 else 1036 DNBLogThreadedIf(LOG_RNB_REMOTE | LOG_RNB_PACKETS, 1037 "HandleAsyncPacket (%s);", 1038 packet_info.printable_name.c_str()); 1039 1040 HandlePacketCallback packet_callback = packet_info.async; 1041 if (packet_callback != NULL) { 1042 if (type != NULL) 1043 *type = packet_info.type; 1044 return (this->*packet_callback)(packet_data.c_str()); 1045 } 1046 } 1047 1048 return err; 1049 } 1050 1051 rnb_err_t RNBRemote::HandleReceivedPacket(PacketEnum *type) { 1052 static DNBTimer g_packetTimer(true); 1053 1054 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", 1055 // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 1056 rnb_err_t err = rnb_err; 1057 std::string packet_data; 1058 RNBRemote::Packet packet_info; 1059 err = GetPacket(packet_data, packet_info, false); 1060 1061 if (err == rnb_success) { 1062 DNBLogThreadedIf(LOG_RNB_REMOTE, "HandleReceivedPacket (\"%s\");", 1063 packet_data.c_str()); 1064 HandlePacketCallback packet_callback = packet_info.normal; 1065 if (packet_callback != NULL) { 1066 if (type != NULL) 1067 *type = packet_info.type; 1068 return (this->*packet_callback)(packet_data.c_str()); 1069 } else { 1070 // Do not fall through to end of this function, if we have valid 1071 // packet_info and it has a NULL callback, then we need to respect 1072 // that it may not want any response or anything to be done. 1073 return err; 1074 } 1075 } 1076 return rnb_err; 1077 } 1078 1079 void RNBRemote::CommDataReceived(const std::string &new_data) { 1080 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", 1081 // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 1082 { 1083 // Put the packet data into the buffer in a thread safe fashion 1084 PThreadMutex::Locker locker(m_mutex); 1085 1086 std::string data; 1087 // See if we have any left over data from a previous call to this 1088 // function? 1089 if (!m_rx_partial_data.empty()) { 1090 // We do, so lets start with that data 1091 data.swap(m_rx_partial_data); 1092 } 1093 // Append the new incoming data 1094 data += new_data; 1095 1096 // Parse up the packets into gdb remote packets 1097 size_t idx = 0; 1098 const size_t data_size = data.size(); 1099 1100 while (idx < data_size) { 1101 // end_idx must be one past the last valid packet byte. Start 1102 // it off with an invalid value that is the same as the current 1103 // index. 1104 size_t end_idx = idx; 1105 1106 switch (data[idx]) { 1107 case '+': // Look for ack 1108 case '-': // Look for cancel 1109 case '\x03': // ^C to halt target 1110 end_idx = idx + 1; // The command is one byte long... 1111 break; 1112 1113 case '$': 1114 // Look for a standard gdb packet? 1115 end_idx = data.find('#', idx + 1); 1116 if (end_idx == std::string::npos || end_idx + 3 > data_size) { 1117 end_idx = std::string::npos; 1118 } else { 1119 // Add two for the checksum bytes and 1 to point to the 1120 // byte just past the end of this packet 1121 end_idx += 3; 1122 } 1123 break; 1124 1125 default: 1126 break; 1127 } 1128 1129 if (end_idx == std::string::npos) { 1130 // Not all data may be here for the packet yet, save it for 1131 // next time through this function. 1132 m_rx_partial_data += data.substr(idx); 1133 // DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s saving data for 1134 // later[%u, npos): 1135 // '%s'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 1136 // __FUNCTION__, idx, m_rx_partial_data.c_str()); 1137 idx = end_idx; 1138 } else if (idx < end_idx) { 1139 m_packets_recvd++; 1140 // Hack to get rid of initial '+' ACK??? 1141 if (m_packets_recvd == 1 && (end_idx == idx + 1) && data[idx] == '+') { 1142 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s throwing first 1143 // ACK away....[%u, npos): 1144 // '+'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 1145 // __FUNCTION__, idx); 1146 } else { 1147 // We have a valid packet... 1148 m_rx_packets.push_back(data.substr(idx, end_idx - idx)); 1149 DNBLogThreadedIf(LOG_RNB_PACKETS, "getpkt: %s", 1150 m_rx_packets.back().c_str()); 1151 } 1152 idx = end_idx; 1153 } else { 1154 DNBLogThreadedIf(LOG_RNB_MAX, 1155 "%8d RNBRemote::%s tossing junk byte at %c", 1156 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 1157 __FUNCTION__, data[idx]); 1158 idx = idx + 1; 1159 } 1160 } 1161 } 1162 1163 if (!m_rx_packets.empty()) { 1164 // Let the main thread know we have received a packet 1165 1166 // DNBLogThreadedIf (LOG_RNB_EVENTS, "%8d RNBRemote::%s called 1167 // events.SetEvent(RNBContext::event_read_packet_available)", 1168 // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 1169 PThreadEvent &events = m_ctx.Events(); 1170 events.SetEvents(RNBContext::event_read_packet_available); 1171 } 1172 } 1173 1174 rnb_err_t RNBRemote::GetCommData() { 1175 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", 1176 // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 1177 std::string comm_data; 1178 rnb_err_t err = m_comm.Read(comm_data); 1179 if (err == rnb_success) { 1180 if (!comm_data.empty()) 1181 CommDataReceived(comm_data); 1182 } 1183 return err; 1184 } 1185 1186 void RNBRemote::StartReadRemoteDataThread() { 1187 DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s called", 1188 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 1189 __FUNCTION__); 1190 PThreadEvent &events = m_ctx.Events(); 1191 if ((events.GetEventBits() & RNBContext::event_read_thread_running) == 0) { 1192 events.ResetEvents(RNBContext::event_read_thread_exiting); 1193 int err = ::pthread_create(&m_rx_pthread, NULL, 1194 ThreadFunctionReadRemoteData, this); 1195 if (err == 0) { 1196 // Our thread was successfully kicked off, wait for it to 1197 // set the started event so we can safely continue 1198 events.WaitForSetEvents(RNBContext::event_read_thread_running); 1199 } else { 1200 events.ResetEvents(RNBContext::event_read_thread_running); 1201 events.SetEvents(RNBContext::event_read_thread_exiting); 1202 } 1203 } 1204 } 1205 1206 void RNBRemote::StopReadRemoteDataThread() { 1207 DNBLogThreadedIf(LOG_RNB_REMOTE, "%8u RNBRemote::%s called", 1208 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 1209 __FUNCTION__); 1210 PThreadEvent &events = m_ctx.Events(); 1211 if ((events.GetEventBits() & RNBContext::event_read_thread_running) == 1212 RNBContext::event_read_thread_running) { 1213 m_comm.Disconnect(true); 1214 struct timespec timeout_abstime; 1215 DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0); 1216 1217 // Wait for 2 seconds for the remote data thread to exit 1218 if (events.WaitForSetEvents(RNBContext::event_read_thread_exiting, 1219 &timeout_abstime) == 0) { 1220 // Kill the remote data thread??? 1221 } 1222 } 1223 } 1224 1225 void *RNBRemote::ThreadFunctionReadRemoteData(void *arg) { 1226 // Keep a shared pointer reference so this doesn't go away on us before the 1227 // thread is killed. 1228 DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread starting...", 1229 __FUNCTION__, arg); 1230 RNBRemoteSP remoteSP(g_remoteSP); 1231 if (remoteSP.get() != NULL) { 1232 1233 #if defined(__APPLE__) 1234 pthread_setname_np("read gdb-remote packets thread"); 1235 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 1236 struct sched_param thread_param; 1237 int thread_sched_policy; 1238 if (pthread_getschedparam(pthread_self(), &thread_sched_policy, 1239 &thread_param) == 0) { 1240 thread_param.sched_priority = 47; 1241 pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param); 1242 } 1243 #endif 1244 #endif 1245 1246 RNBRemote *remote = remoteSP.get(); 1247 PThreadEvent &events = remote->Context().Events(); 1248 events.SetEvents(RNBContext::event_read_thread_running); 1249 // START: main receive remote command thread loop 1250 bool done = false; 1251 while (!done) { 1252 rnb_err_t err = remote->GetCommData(); 1253 1254 switch (err) { 1255 case rnb_success: 1256 break; 1257 1258 case rnb_err: 1259 DNBLogThreadedIf(LOG_RNB_REMOTE, 1260 "RNBSocket::GetCommData returned error %u", err); 1261 done = true; 1262 break; 1263 1264 case rnb_not_connected: 1265 DNBLogThreadedIf(LOG_RNB_REMOTE, 1266 "RNBSocket::GetCommData returned not connected..."); 1267 done = true; 1268 break; 1269 } 1270 } 1271 // START: main receive remote command thread loop 1272 events.ResetEvents(RNBContext::event_read_thread_running); 1273 events.SetEvents(RNBContext::event_read_thread_exiting); 1274 } 1275 DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...", 1276 __FUNCTION__, arg); 1277 return NULL; 1278 } 1279 1280 // If we fail to get back a valid CPU type for the remote process, 1281 // make a best guess for the CPU type based on the currently running 1282 // debugserver binary -- the debugger may not handle the case of an 1283 // un-specified process CPU type correctly. 1284 1285 static cpu_type_t best_guess_cpu_type() { 1286 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 1287 if (sizeof(char *) == 8) { 1288 return CPU_TYPE_ARM64; 1289 } else { 1290 return CPU_TYPE_ARM; 1291 } 1292 #elif defined(__i386__) || defined(__x86_64__) 1293 if (sizeof(char *) == 8) { 1294 return CPU_TYPE_X86_64; 1295 } else { 1296 return CPU_TYPE_I386; 1297 } 1298 #endif 1299 return 0; 1300 } 1301 1302 /* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes 1303 (8-bit bytes). 1304 This encoding uses 0x7d ('}') as an escape character for 1305 0x7d ('}'), 0x23 ('#'), 0x24 ('$'), 0x2a ('*'). 1306 LEN is the number of bytes to be processed. If a character is escaped, 1307 it is 2 characters for LEN. A LEN of -1 means decode-until-nul-byte 1308 (end of string). */ 1309 1310 std::vector<uint8_t> decode_binary_data(const char *str, size_t len) { 1311 std::vector<uint8_t> bytes; 1312 if (len == 0) { 1313 return bytes; 1314 } 1315 if (len == (size_t)-1) 1316 len = strlen(str); 1317 1318 while (len--) { 1319 unsigned char c = *str++; 1320 if (c == 0x7d && len > 0) { 1321 len--; 1322 c = *str++ ^ 0x20; 1323 } 1324 bytes.push_back(c); 1325 } 1326 return bytes; 1327 } 1328 1329 // Quote any meta characters in a std::string as per the binary 1330 // packet convention in the gdb-remote protocol. 1331 1332 static std::string binary_encode_string(const std::string &s) { 1333 std::string output; 1334 const size_t s_size = s.size(); 1335 const char *s_chars = s.c_str(); 1336 1337 for (size_t i = 0; i < s_size; i++) { 1338 unsigned char ch = *(s_chars + i); 1339 if (ch == '#' || ch == '$' || ch == '}' || ch == '*') { 1340 output.push_back('}'); // 0x7d 1341 output.push_back(ch ^ 0x20); 1342 } else { 1343 output.push_back(ch); 1344 } 1345 } 1346 return output; 1347 } 1348 1349 // If the value side of a key-value pair in JSON is a string, 1350 // and that string has a " character in it, the " character must 1351 // be escaped. 1352 1353 std::string json_string_quote_metachars(const std::string &s) { 1354 if (s.find('"') == std::string::npos) 1355 return s; 1356 1357 std::string output; 1358 const size_t s_size = s.size(); 1359 const char *s_chars = s.c_str(); 1360 for (size_t i = 0; i < s_size; i++) { 1361 unsigned char ch = *(s_chars + i); 1362 if (ch == '"') { 1363 output.push_back('\\'); 1364 } 1365 output.push_back(ch); 1366 } 1367 return output; 1368 } 1369 1370 typedef struct register_map_entry { 1371 uint32_t debugserver_regnum; // debugserver register number 1372 uint32_t offset; // Offset in bytes into the register context data with no 1373 // padding between register values 1374 DNBRegisterInfo nub_info; // debugnub register info 1375 std::vector<uint32_t> value_regnums; 1376 std::vector<uint32_t> invalidate_regnums; 1377 } register_map_entry_t; 1378 1379 // If the notion of registers differs from what is handed out by the 1380 // architecture, then flavors can be defined here. 1381 1382 static std::vector<register_map_entry_t> g_dynamic_register_map; 1383 static register_map_entry_t *g_reg_entries = NULL; 1384 static size_t g_num_reg_entries = 0; 1385 1386 void RNBRemote::Initialize() { DNBInitialize(); } 1387 1388 bool RNBRemote::InitializeRegisters(bool force) { 1389 pid_t pid = m_ctx.ProcessID(); 1390 if (pid == INVALID_NUB_PROCESS) 1391 return false; 1392 1393 DNBLogThreadedIf( 1394 LOG_RNB_PROC, 1395 "RNBRemote::%s() getting native registers from DNB interface", 1396 __FUNCTION__); 1397 // Discover the registers by querying the DNB interface and letting it 1398 // state the registers that it would like to export. This allows the 1399 // registers to be discovered using multiple qRegisterInfo calls to get 1400 // all register information after the architecture for the process is 1401 // determined. 1402 if (force) { 1403 g_dynamic_register_map.clear(); 1404 g_reg_entries = NULL; 1405 g_num_reg_entries = 0; 1406 } 1407 1408 if (g_dynamic_register_map.empty()) { 1409 nub_size_t num_reg_sets = 0; 1410 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo(&num_reg_sets); 1411 1412 assert(num_reg_sets > 0 && reg_sets != NULL); 1413 1414 uint32_t regnum = 0; 1415 uint32_t reg_data_offset = 0; 1416 typedef std::map<std::string, uint32_t> NameToRegNum; 1417 NameToRegNum name_to_regnum; 1418 for (nub_size_t set = 0; set < num_reg_sets; ++set) { 1419 if (reg_sets[set].registers == NULL) 1420 continue; 1421 1422 for (uint32_t reg = 0; reg < reg_sets[set].num_registers; ++reg) { 1423 register_map_entry_t reg_entry = { 1424 regnum++, // register number starts at zero and goes up with no gaps 1425 reg_data_offset, // Offset into register context data, no gaps 1426 // between registers 1427 reg_sets[set].registers[reg], // DNBRegisterInfo 1428 {}, 1429 {}, 1430 }; 1431 1432 name_to_regnum[reg_entry.nub_info.name] = reg_entry.debugserver_regnum; 1433 1434 if (reg_entry.nub_info.value_regs == NULL) { 1435 reg_data_offset += reg_entry.nub_info.size; 1436 } 1437 1438 g_dynamic_register_map.push_back(reg_entry); 1439 } 1440 } 1441 1442 // Now we must find any registers whose values are in other registers and 1443 // fix up 1444 // the offsets since we removed all gaps... 1445 for (auto ®_entry : g_dynamic_register_map) { 1446 if (reg_entry.nub_info.value_regs) { 1447 uint32_t new_offset = UINT32_MAX; 1448 for (size_t i = 0; reg_entry.nub_info.value_regs[i] != NULL; ++i) { 1449 const char *name = reg_entry.nub_info.value_regs[i]; 1450 auto pos = name_to_regnum.find(name); 1451 if (pos != name_to_regnum.end()) { 1452 regnum = pos->second; 1453 reg_entry.value_regnums.push_back(regnum); 1454 if (regnum < g_dynamic_register_map.size()) { 1455 // The offset for value_regs registers is the offset within the 1456 // register with the lowest offset 1457 const uint32_t reg_offset = 1458 g_dynamic_register_map[regnum].offset + 1459 reg_entry.nub_info.offset; 1460 if (new_offset > reg_offset) 1461 new_offset = reg_offset; 1462 } 1463 } 1464 } 1465 1466 if (new_offset != UINT32_MAX) { 1467 reg_entry.offset = new_offset; 1468 } else { 1469 DNBLogThreaded("no offset was calculated entry for register %s", 1470 reg_entry.nub_info.name); 1471 reg_entry.offset = UINT32_MAX; 1472 } 1473 } 1474 1475 if (reg_entry.nub_info.update_regs) { 1476 for (size_t i = 0; reg_entry.nub_info.update_regs[i] != NULL; ++i) { 1477 const char *name = reg_entry.nub_info.update_regs[i]; 1478 auto pos = name_to_regnum.find(name); 1479 if (pos != name_to_regnum.end()) { 1480 regnum = pos->second; 1481 reg_entry.invalidate_regnums.push_back(regnum); 1482 } 1483 } 1484 } 1485 } 1486 1487 // for (auto ®_entry: g_dynamic_register_map) 1488 // { 1489 // DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s", 1490 // reg_entry.offset, 1491 // reg_entry.nub_info.size, 1492 // reg_entry.nub_info.value_regs != NULL, 1493 // reg_entry.nub_info.name); 1494 // } 1495 1496 g_reg_entries = g_dynamic_register_map.data(); 1497 g_num_reg_entries = g_dynamic_register_map.size(); 1498 } 1499 return true; 1500 } 1501 1502 /* The inferior has stopped executing; send a packet 1503 to gdb to let it know. */ 1504 1505 void RNBRemote::NotifyThatProcessStopped(void) { 1506 RNBRemote::HandlePacket_last_signal(NULL); 1507 return; 1508 } 1509 1510 /* 'A arglen,argnum,arg,...' 1511 Update the inferior context CTX with the program name and arg 1512 list. 1513 The documentation for this packet is underwhelming but my best reading 1514 of this is that it is a series of (len, position #, arg)'s, one for 1515 each argument with "arg" hex encoded (two 0-9a-f chars?). 1516 Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either 1517 is sufficient to get around the "," position separator escape issue. 1518 1519 e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is 1520 1521 6,0,676462,4,1,2d71,10,2,612e6f7574 1522 1523 Note that "argnum" and "arglen" are numbers in base 10. Again, that's 1524 not documented either way but I'm assuming it's so. */ 1525 1526 rnb_err_t RNBRemote::HandlePacket_A(const char *p) { 1527 if (p == NULL || *p == '\0') { 1528 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1529 "Null packet for 'A' pkt"); 1530 } 1531 p++; 1532 if (*p == '\0' || !isdigit(*p)) { 1533 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1534 "arglen not specified on 'A' pkt"); 1535 } 1536 1537 /* I promise I don't modify it anywhere in this function. strtoul()'s 1538 2nd arg has to be non-const which makes it problematic to step 1539 through the string easily. */ 1540 char *buf = const_cast<char *>(p); 1541 1542 RNBContext &ctx = Context(); 1543 1544 while (*buf != '\0') { 1545 unsigned long arglen, argnum; 1546 std::string arg; 1547 char *c; 1548 1549 errno = 0; 1550 arglen = strtoul(buf, &c, 10); 1551 if (errno != 0 && arglen == 0) { 1552 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1553 "arglen not a number on 'A' pkt"); 1554 } 1555 if (*c != ',') { 1556 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1557 "arglen not followed by comma on 'A' pkt"); 1558 } 1559 buf = c + 1; 1560 1561 errno = 0; 1562 argnum = strtoul(buf, &c, 10); 1563 if (errno != 0 && argnum == 0) { 1564 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1565 "argnum not a number on 'A' pkt"); 1566 } 1567 if (*c != ',') { 1568 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1569 "arglen not followed by comma on 'A' pkt"); 1570 } 1571 buf = c + 1; 1572 1573 c = buf; 1574 buf = buf + arglen; 1575 while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0') { 1576 char smallbuf[3]; 1577 smallbuf[0] = *c; 1578 smallbuf[1] = *(c + 1); 1579 smallbuf[2] = '\0'; 1580 1581 errno = 0; 1582 int ch = static_cast<int>(strtoul(smallbuf, NULL, 16)); 1583 if (errno != 0 && ch == 0) { 1584 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1585 "non-hex char in arg on 'A' pkt"); 1586 } 1587 1588 arg.push_back(ch); 1589 c += 2; 1590 } 1591 1592 ctx.PushArgument(arg.c_str()); 1593 if (*buf == ',') 1594 buf++; 1595 } 1596 SendPacket("OK"); 1597 1598 return rnb_success; 1599 } 1600 1601 /* 'H c t' 1602 Set the thread for subsequent actions; 'c' for step/continue ops, 1603 'g' for other ops. -1 means all threads, 0 means any thread. */ 1604 1605 rnb_err_t RNBRemote::HandlePacket_H(const char *p) { 1606 p++; // skip 'H' 1607 if (*p != 'c' && *p != 'g') { 1608 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1609 "Missing 'c' or 'g' type in H packet"); 1610 } 1611 1612 if (!m_ctx.HasValidProcessID()) { 1613 // We allow gdb to connect to a server that hasn't started running 1614 // the target yet. gdb still wants to ask questions about it and 1615 // freaks out if it gets an error. So just return OK here. 1616 } 1617 1618 errno = 0; 1619 nub_thread_t tid = strtoul(p + 1, NULL, 16); 1620 if (errno != 0 && tid == 0) { 1621 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1622 "Invalid thread number in H packet"); 1623 } 1624 if (*p == 'c') 1625 SetContinueThread(tid); 1626 if (*p == 'g') 1627 SetCurrentThread(tid); 1628 1629 return SendPacket("OK"); 1630 } 1631 1632 rnb_err_t RNBRemote::HandlePacket_qLaunchSuccess(const char *p) { 1633 if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Status() == 0) 1634 return SendPacket("OK"); 1635 std::ostringstream ret_str; 1636 std::string status_str; 1637 ret_str << "E" << m_ctx.LaunchStatusAsString(status_str); 1638 1639 return SendPacket(ret_str.str()); 1640 } 1641 1642 rnb_err_t RNBRemote::HandlePacket_qShlibInfoAddr(const char *p) { 1643 if (m_ctx.HasValidProcessID()) { 1644 nub_addr_t shlib_info_addr = 1645 DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID()); 1646 if (shlib_info_addr != INVALID_NUB_ADDRESS) { 1647 std::ostringstream ostrm; 1648 ostrm << RAW_HEXBASE << shlib_info_addr; 1649 return SendPacket(ostrm.str()); 1650 } 1651 } 1652 return SendPacket("E44"); 1653 } 1654 1655 rnb_err_t RNBRemote::HandlePacket_qStepPacketSupported(const char *p) { 1656 // Normally the "s" packet is mandatory, yet in gdb when using ARM, they 1657 // get around the need for this packet by implementing software single 1658 // stepping from gdb. Current versions of debugserver do support the "s" 1659 // packet, yet some older versions do not. We need a way to tell if this 1660 // packet is supported so we can disable software single stepping in gdb 1661 // for remote targets (so the "s" packet will get used). 1662 return SendPacket("OK"); 1663 } 1664 1665 rnb_err_t RNBRemote::HandlePacket_qSyncThreadStateSupported(const char *p) { 1666 // We support attachOrWait meaning attach if the process exists, otherwise 1667 // wait to attach. 1668 return SendPacket("OK"); 1669 } 1670 1671 rnb_err_t RNBRemote::HandlePacket_qVAttachOrWaitSupported(const char *p) { 1672 // We support attachOrWait meaning attach if the process exists, otherwise 1673 // wait to attach. 1674 return SendPacket("OK"); 1675 } 1676 1677 rnb_err_t RNBRemote::HandlePacket_qThreadStopInfo(const char *p) { 1678 p += strlen("qThreadStopInfo"); 1679 nub_thread_t tid = strtoul(p, 0, 16); 1680 return SendStopReplyPacketForThread(tid); 1681 } 1682 1683 rnb_err_t RNBRemote::HandlePacket_qThreadInfo(const char *p) { 1684 // We allow gdb to connect to a server that hasn't started running 1685 // the target yet. gdb still wants to ask questions about it and 1686 // freaks out if it gets an error. So just return OK here. 1687 nub_process_t pid = m_ctx.ProcessID(); 1688 if (pid == INVALID_NUB_PROCESS) 1689 return SendPacket("OK"); 1690 1691 // Only "qfThreadInfo" and "qsThreadInfo" get into this function so 1692 // we only need to check the second byte to tell which is which 1693 if (p[1] == 'f') { 1694 nub_size_t numthreads = DNBProcessGetNumThreads(pid); 1695 std::ostringstream ostrm; 1696 ostrm << "m"; 1697 bool first = true; 1698 for (nub_size_t i = 0; i < numthreads; ++i) { 1699 if (first) 1700 first = false; 1701 else 1702 ostrm << ","; 1703 nub_thread_t th = DNBProcessGetThreadAtIndex(pid, i); 1704 ostrm << std::hex << th; 1705 } 1706 return SendPacket(ostrm.str()); 1707 } else { 1708 return SendPacket("l"); 1709 } 1710 } 1711 1712 rnb_err_t RNBRemote::HandlePacket_qThreadExtraInfo(const char *p) { 1713 // We allow gdb to connect to a server that hasn't started running 1714 // the target yet. gdb still wants to ask questions about it and 1715 // freaks out if it gets an error. So just return OK here. 1716 nub_process_t pid = m_ctx.ProcessID(); 1717 if (pid == INVALID_NUB_PROCESS) 1718 return SendPacket("OK"); 1719 1720 /* This is supposed to return a string like 'Runnable' or 1721 'Blocked on Mutex'. 1722 The returned string is formatted like the "A" packet - a 1723 sequence of letters encoded in as 2-hex-chars-per-letter. */ 1724 p += strlen("qThreadExtraInfo"); 1725 if (*p++ != ',') 1726 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1727 "Illformed qThreadExtraInfo packet"); 1728 errno = 0; 1729 nub_thread_t tid = strtoul(p, NULL, 16); 1730 if (errno != 0 && tid == 0) { 1731 return HandlePacket_ILLFORMED( 1732 __FILE__, __LINE__, p, 1733 "Invalid thread number in qThreadExtraInfo packet"); 1734 } 1735 1736 const char *threadInfo = DNBThreadGetInfo(pid, tid); 1737 if (threadInfo != NULL && threadInfo[0]) { 1738 return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL); 1739 } else { 1740 // "OK" == 4f6b 1741 // Return "OK" as a ASCII hex byte stream if things go wrong 1742 return SendPacket("4f6b"); 1743 } 1744 1745 return SendPacket(""); 1746 } 1747 1748 const char *k_space_delimiters = " \t"; 1749 static void skip_spaces(std::string &line) { 1750 if (!line.empty()) { 1751 size_t space_pos = line.find_first_not_of(k_space_delimiters); 1752 if (space_pos > 0) 1753 line.erase(0, space_pos); 1754 } 1755 } 1756 1757 static std::string get_identifier(std::string &line) { 1758 std::string word; 1759 skip_spaces(line); 1760 const size_t line_size = line.size(); 1761 size_t end_pos; 1762 for (end_pos = 0; end_pos < line_size; ++end_pos) { 1763 if (end_pos == 0) { 1764 if (isalpha(line[end_pos]) || line[end_pos] == '_') 1765 continue; 1766 } else if (isalnum(line[end_pos]) || line[end_pos] == '_') 1767 continue; 1768 break; 1769 } 1770 word.assign(line, 0, end_pos); 1771 line.erase(0, end_pos); 1772 return word; 1773 } 1774 1775 static std::string get_operator(std::string &line) { 1776 std::string op; 1777 skip_spaces(line); 1778 if (!line.empty()) { 1779 if (line[0] == '=') { 1780 op = '='; 1781 line.erase(0, 1); 1782 } 1783 } 1784 return op; 1785 } 1786 1787 static std::string get_value(std::string &line) { 1788 std::string value; 1789 skip_spaces(line); 1790 if (!line.empty()) { 1791 value.swap(line); 1792 } 1793 return value; 1794 } 1795 1796 extern void FileLogCallback(void *baton, uint32_t flags, const char *format, 1797 va_list args); 1798 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, 1799 va_list args); 1800 1801 rnb_err_t RNBRemote::HandlePacket_qRcmd(const char *p) { 1802 const char *c = p + strlen("qRcmd,"); 1803 std::string line; 1804 while (c[0] && c[1]) { 1805 char smallbuf[3] = {c[0], c[1], '\0'}; 1806 errno = 0; 1807 int ch = static_cast<int>(strtoul(smallbuf, NULL, 16)); 1808 if (errno != 0 && ch == 0) 1809 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 1810 "non-hex char in payload of qRcmd packet"); 1811 line.push_back(ch); 1812 c += 2; 1813 } 1814 if (*c == '\0') { 1815 std::string command = get_identifier(line); 1816 if (command == "set") { 1817 std::string variable = get_identifier(line); 1818 std::string op = get_operator(line); 1819 std::string value = get_value(line); 1820 if (variable == "logfile") { 1821 FILE *log_file = fopen(value.c_str(), "w"); 1822 if (log_file) { 1823 DNBLogSetLogCallback(FileLogCallback, log_file); 1824 return SendPacket("OK"); 1825 } 1826 return SendPacket("E71"); 1827 } else if (variable == "logmask") { 1828 char *end; 1829 errno = 0; 1830 uint32_t logmask = 1831 static_cast<uint32_t>(strtoul(value.c_str(), &end, 0)); 1832 if (errno == 0 && end && *end == '\0') { 1833 DNBLogSetLogMask(logmask); 1834 if (!DNBLogGetLogCallback()) 1835 DNBLogSetLogCallback(ASLLogCallback, NULL); 1836 return SendPacket("OK"); 1837 } 1838 errno = 0; 1839 logmask = static_cast<uint32_t>(strtoul(value.c_str(), &end, 16)); 1840 if (errno == 0 && end && *end == '\0') { 1841 DNBLogSetLogMask(logmask); 1842 return SendPacket("OK"); 1843 } 1844 return SendPacket("E72"); 1845 } 1846 return SendPacket("E70"); 1847 } 1848 return SendPacket("E69"); 1849 } 1850 return SendPacket("E73"); 1851 } 1852 1853 rnb_err_t RNBRemote::HandlePacket_qC(const char *p) { 1854 nub_thread_t tid; 1855 std::ostringstream rep; 1856 // If we haven't run the process yet, we tell the debugger the 1857 // pid is 0. That way it can know to tell use to run later on. 1858 if (!m_ctx.HasValidProcessID()) 1859 tid = 0; 1860 else { 1861 // Grab the current thread. 1862 tid = DNBProcessGetCurrentThread(m_ctx.ProcessID()); 1863 // Make sure we set the current thread so g and p packets return 1864 // the data the gdb will expect. 1865 SetCurrentThread(tid); 1866 } 1867 rep << "QC" << std::hex << tid; 1868 return SendPacket(rep.str()); 1869 } 1870 1871 rnb_err_t RNBRemote::HandlePacket_qEcho(const char *p) { 1872 // Just send the exact same packet back that we received to 1873 // synchronize the response packets after a previous packet 1874 // timed out. This allows the debugger to get back on track 1875 // with responses after a packet timeout. 1876 return SendPacket(p); 1877 } 1878 1879 rnb_err_t RNBRemote::HandlePacket_qGetPid(const char *p) { 1880 nub_process_t pid; 1881 std::ostringstream rep; 1882 // If we haven't run the process yet, we tell the debugger the 1883 // pid is 0. That way it can know to tell use to run later on. 1884 if (m_ctx.HasValidProcessID()) 1885 pid = m_ctx.ProcessID(); 1886 else 1887 pid = 0; 1888 rep << std::hex << pid; 1889 return SendPacket(rep.str()); 1890 } 1891 1892 rnb_err_t RNBRemote::HandlePacket_qRegisterInfo(const char *p) { 1893 if (g_num_reg_entries == 0) 1894 InitializeRegisters(); 1895 1896 p += strlen("qRegisterInfo"); 1897 1898 nub_size_t num_reg_sets = 0; 1899 const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo(&num_reg_sets); 1900 uint32_t reg_num = static_cast<uint32_t>(strtoul(p, 0, 16)); 1901 1902 if (reg_num < g_num_reg_entries) { 1903 const register_map_entry_t *reg_entry = &g_reg_entries[reg_num]; 1904 std::ostringstream ostrm; 1905 if (reg_entry->nub_info.name) 1906 ostrm << "name:" << reg_entry->nub_info.name << ';'; 1907 if (reg_entry->nub_info.alt) 1908 ostrm << "alt-name:" << reg_entry->nub_info.alt << ';'; 1909 1910 ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';'; 1911 ostrm << "offset:" << std::dec << reg_entry->offset << ';'; 1912 1913 switch (reg_entry->nub_info.type) { 1914 case Uint: 1915 ostrm << "encoding:uint;"; 1916 break; 1917 case Sint: 1918 ostrm << "encoding:sint;"; 1919 break; 1920 case IEEE754: 1921 ostrm << "encoding:ieee754;"; 1922 break; 1923 case Vector: 1924 ostrm << "encoding:vector;"; 1925 break; 1926 } 1927 1928 switch (reg_entry->nub_info.format) { 1929 case Binary: 1930 ostrm << "format:binary;"; 1931 break; 1932 case Decimal: 1933 ostrm << "format:decimal;"; 1934 break; 1935 case Hex: 1936 ostrm << "format:hex;"; 1937 break; 1938 case Float: 1939 ostrm << "format:float;"; 1940 break; 1941 case VectorOfSInt8: 1942 ostrm << "format:vector-sint8;"; 1943 break; 1944 case VectorOfUInt8: 1945 ostrm << "format:vector-uint8;"; 1946 break; 1947 case VectorOfSInt16: 1948 ostrm << "format:vector-sint16;"; 1949 break; 1950 case VectorOfUInt16: 1951 ostrm << "format:vector-uint16;"; 1952 break; 1953 case VectorOfSInt32: 1954 ostrm << "format:vector-sint32;"; 1955 break; 1956 case VectorOfUInt32: 1957 ostrm << "format:vector-uint32;"; 1958 break; 1959 case VectorOfFloat32: 1960 ostrm << "format:vector-float32;"; 1961 break; 1962 case VectorOfUInt128: 1963 ostrm << "format:vector-uint128;"; 1964 break; 1965 }; 1966 1967 if (reg_set_info && reg_entry->nub_info.set < num_reg_sets) 1968 ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';'; 1969 1970 if (reg_entry->nub_info.reg_ehframe != INVALID_NUB_REGNUM) 1971 ostrm << "ehframe:" << std::dec << reg_entry->nub_info.reg_ehframe << ';'; 1972 1973 if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM) 1974 ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';'; 1975 1976 switch (reg_entry->nub_info.reg_generic) { 1977 case GENERIC_REGNUM_FP: 1978 ostrm << "generic:fp;"; 1979 break; 1980 case GENERIC_REGNUM_PC: 1981 ostrm << "generic:pc;"; 1982 break; 1983 case GENERIC_REGNUM_SP: 1984 ostrm << "generic:sp;"; 1985 break; 1986 case GENERIC_REGNUM_RA: 1987 ostrm << "generic:ra;"; 1988 break; 1989 case GENERIC_REGNUM_FLAGS: 1990 ostrm << "generic:flags;"; 1991 break; 1992 case GENERIC_REGNUM_ARG1: 1993 ostrm << "generic:arg1;"; 1994 break; 1995 case GENERIC_REGNUM_ARG2: 1996 ostrm << "generic:arg2;"; 1997 break; 1998 case GENERIC_REGNUM_ARG3: 1999 ostrm << "generic:arg3;"; 2000 break; 2001 case GENERIC_REGNUM_ARG4: 2002 ostrm << "generic:arg4;"; 2003 break; 2004 case GENERIC_REGNUM_ARG5: 2005 ostrm << "generic:arg5;"; 2006 break; 2007 case GENERIC_REGNUM_ARG6: 2008 ostrm << "generic:arg6;"; 2009 break; 2010 case GENERIC_REGNUM_ARG7: 2011 ostrm << "generic:arg7;"; 2012 break; 2013 case GENERIC_REGNUM_ARG8: 2014 ostrm << "generic:arg8;"; 2015 break; 2016 default: 2017 break; 2018 } 2019 2020 if (!reg_entry->value_regnums.empty()) { 2021 ostrm << "container-regs:"; 2022 for (size_t i = 0, n = reg_entry->value_regnums.size(); i < n; ++i) { 2023 if (i > 0) 2024 ostrm << ','; 2025 ostrm << RAW_HEXBASE << reg_entry->value_regnums[i]; 2026 } 2027 ostrm << ';'; 2028 } 2029 2030 if (!reg_entry->invalidate_regnums.empty()) { 2031 ostrm << "invalidate-regs:"; 2032 for (size_t i = 0, n = reg_entry->invalidate_regnums.size(); i < n; ++i) { 2033 if (i > 0) 2034 ostrm << ','; 2035 ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i]; 2036 } 2037 ostrm << ';'; 2038 } 2039 2040 return SendPacket(ostrm.str()); 2041 } 2042 return SendPacket("E45"); 2043 } 2044 2045 /* This expects a packet formatted like 2046 2047 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE; 2048 2049 with the "QSetLogging:" already removed from the start. Maybe in the 2050 future this packet will include other keyvalue pairs like 2051 2052 QSetLogging:bitmask=LOG_ALL;mode=asl; 2053 */ 2054 2055 rnb_err_t set_logging(const char *p) { 2056 int bitmask = 0; 2057 while (p && *p != '\0') { 2058 if (strncmp(p, "bitmask=", sizeof("bitmask=") - 1) == 0) { 2059 p += sizeof("bitmask=") - 1; 2060 while (p && *p != '\0' && *p != ';') { 2061 if (*p == '|') 2062 p++; 2063 2064 // to regenerate the LOG_ entries (not including the LOG_RNB entries) 2065 // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 2066 // 'LOG_HI|LOG_LO' | awk '{print $2}'` 2067 // do 2068 // echo " else if (strncmp (p, \"$logname\", sizeof 2069 // (\"$logname\") - 1) == 0)" 2070 // echo " {" 2071 // echo " p += sizeof (\"$logname\") - 1;" 2072 // echo " bitmask |= $logname;" 2073 // echo " }" 2074 // done 2075 if (strncmp(p, "LOG_VERBOSE", sizeof("LOG_VERBOSE") - 1) == 0) { 2076 p += sizeof("LOG_VERBOSE") - 1; 2077 bitmask |= LOG_VERBOSE; 2078 } else if (strncmp(p, "LOG_PROCESS", sizeof("LOG_PROCESS") - 1) == 0) { 2079 p += sizeof("LOG_PROCESS") - 1; 2080 bitmask |= LOG_PROCESS; 2081 } else if (strncmp(p, "LOG_THREAD", sizeof("LOG_THREAD") - 1) == 0) { 2082 p += sizeof("LOG_THREAD") - 1; 2083 bitmask |= LOG_THREAD; 2084 } else if (strncmp(p, "LOG_EXCEPTIONS", sizeof("LOG_EXCEPTIONS") - 1) == 2085 0) { 2086 p += sizeof("LOG_EXCEPTIONS") - 1; 2087 bitmask |= LOG_EXCEPTIONS; 2088 } else if (strncmp(p, "LOG_SHLIB", sizeof("LOG_SHLIB") - 1) == 0) { 2089 p += sizeof("LOG_SHLIB") - 1; 2090 bitmask |= LOG_SHLIB; 2091 } else if (strncmp(p, "LOG_MEMORY", sizeof("LOG_MEMORY") - 1) == 0) { 2092 p += sizeof("LOG_MEMORY") - 1; 2093 bitmask |= LOG_MEMORY; 2094 } else if (strncmp(p, "LOG_MEMORY_DATA_SHORT", 2095 sizeof("LOG_MEMORY_DATA_SHORT") - 1) == 0) { 2096 p += sizeof("LOG_MEMORY_DATA_SHORT") - 1; 2097 bitmask |= LOG_MEMORY_DATA_SHORT; 2098 } else if (strncmp(p, "LOG_MEMORY_DATA_LONG", 2099 sizeof("LOG_MEMORY_DATA_LONG") - 1) == 0) { 2100 p += sizeof("LOG_MEMORY_DATA_LONG") - 1; 2101 bitmask |= LOG_MEMORY_DATA_LONG; 2102 } else if (strncmp(p, "LOG_MEMORY_PROTECTIONS", 2103 sizeof("LOG_MEMORY_PROTECTIONS") - 1) == 0) { 2104 p += sizeof("LOG_MEMORY_PROTECTIONS") - 1; 2105 bitmask |= LOG_MEMORY_PROTECTIONS; 2106 } else if (strncmp(p, "LOG_BREAKPOINTS", 2107 sizeof("LOG_BREAKPOINTS") - 1) == 0) { 2108 p += sizeof("LOG_BREAKPOINTS") - 1; 2109 bitmask |= LOG_BREAKPOINTS; 2110 } else if (strncmp(p, "LOG_EVENTS", sizeof("LOG_EVENTS") - 1) == 0) { 2111 p += sizeof("LOG_EVENTS") - 1; 2112 bitmask |= LOG_EVENTS; 2113 } else if (strncmp(p, "LOG_WATCHPOINTS", 2114 sizeof("LOG_WATCHPOINTS") - 1) == 0) { 2115 p += sizeof("LOG_WATCHPOINTS") - 1; 2116 bitmask |= LOG_WATCHPOINTS; 2117 } else if (strncmp(p, "LOG_STEP", sizeof("LOG_STEP") - 1) == 0) { 2118 p += sizeof("LOG_STEP") - 1; 2119 bitmask |= LOG_STEP; 2120 } else if (strncmp(p, "LOG_TASK", sizeof("LOG_TASK") - 1) == 0) { 2121 p += sizeof("LOG_TASK") - 1; 2122 bitmask |= LOG_TASK; 2123 } else if (strncmp(p, "LOG_ALL", sizeof("LOG_ALL") - 1) == 0) { 2124 p += sizeof("LOG_ALL") - 1; 2125 bitmask |= LOG_ALL; 2126 } else if (strncmp(p, "LOG_DEFAULT", sizeof("LOG_DEFAULT") - 1) == 0) { 2127 p += sizeof("LOG_DEFAULT") - 1; 2128 bitmask |= LOG_DEFAULT; 2129 } 2130 // end of auto-generated entries 2131 2132 else if (strncmp(p, "LOG_NONE", sizeof("LOG_NONE") - 1) == 0) { 2133 p += sizeof("LOG_NONE") - 1; 2134 bitmask = 0; 2135 } else if (strncmp(p, "LOG_RNB_MINIMAL", 2136 sizeof("LOG_RNB_MINIMAL") - 1) == 0) { 2137 p += sizeof("LOG_RNB_MINIMAL") - 1; 2138 bitmask |= LOG_RNB_MINIMAL; 2139 } else if (strncmp(p, "LOG_RNB_MEDIUM", sizeof("LOG_RNB_MEDIUM") - 1) == 2140 0) { 2141 p += sizeof("LOG_RNB_MEDIUM") - 1; 2142 bitmask |= LOG_RNB_MEDIUM; 2143 } else if (strncmp(p, "LOG_RNB_MAX", sizeof("LOG_RNB_MAX") - 1) == 0) { 2144 p += sizeof("LOG_RNB_MAX") - 1; 2145 bitmask |= LOG_RNB_MAX; 2146 } else if (strncmp(p, "LOG_RNB_COMM", sizeof("LOG_RNB_COMM") - 1) == 2147 0) { 2148 p += sizeof("LOG_RNB_COMM") - 1; 2149 bitmask |= LOG_RNB_COMM; 2150 } else if (strncmp(p, "LOG_RNB_REMOTE", sizeof("LOG_RNB_REMOTE") - 1) == 2151 0) { 2152 p += sizeof("LOG_RNB_REMOTE") - 1; 2153 bitmask |= LOG_RNB_REMOTE; 2154 } else if (strncmp(p, "LOG_RNB_EVENTS", sizeof("LOG_RNB_EVENTS") - 1) == 2155 0) { 2156 p += sizeof("LOG_RNB_EVENTS") - 1; 2157 bitmask |= LOG_RNB_EVENTS; 2158 } else if (strncmp(p, "LOG_RNB_PROC", sizeof("LOG_RNB_PROC") - 1) == 2159 0) { 2160 p += sizeof("LOG_RNB_PROC") - 1; 2161 bitmask |= LOG_RNB_PROC; 2162 } else if (strncmp(p, "LOG_RNB_PACKETS", 2163 sizeof("LOG_RNB_PACKETS") - 1) == 0) { 2164 p += sizeof("LOG_RNB_PACKETS") - 1; 2165 bitmask |= LOG_RNB_PACKETS; 2166 } else if (strncmp(p, "LOG_RNB_ALL", sizeof("LOG_RNB_ALL") - 1) == 0) { 2167 p += sizeof("LOG_RNB_ALL") - 1; 2168 bitmask |= LOG_RNB_ALL; 2169 } else if (strncmp(p, "LOG_RNB_DEFAULT", 2170 sizeof("LOG_RNB_DEFAULT") - 1) == 0) { 2171 p += sizeof("LOG_RNB_DEFAULT") - 1; 2172 bitmask |= LOG_RNB_DEFAULT; 2173 } else if (strncmp(p, "LOG_DARWIN_LOG", sizeof("LOG_DARWIN_LOG") - 1) == 2174 0) { 2175 p += sizeof("LOG_DARWIN_LOG") - 1; 2176 bitmask |= LOG_DARWIN_LOG; 2177 } else if (strncmp(p, "LOG_RNB_NONE", sizeof("LOG_RNB_NONE") - 1) == 2178 0) { 2179 p += sizeof("LOG_RNB_NONE") - 1; 2180 bitmask = 0; 2181 } else { 2182 /* Unrecognized logging bit; ignore it. */ 2183 const char *c = strchr(p, '|'); 2184 if (c) { 2185 p = c; 2186 } else { 2187 c = strchr(p, ';'); 2188 if (c) { 2189 p = c; 2190 } else { 2191 // Improperly terminated word; just go to end of str 2192 p = strchr(p, '\0'); 2193 } 2194 } 2195 } 2196 } 2197 // Did we get a properly formatted logging bitmask? 2198 if (p && *p == ';') { 2199 // Enable DNB logging. 2200 // Use the existing log callback if one was already configured. 2201 if (!DNBLogGetLogCallback()) { 2202 // Use the os_log()-based logger if available; otherwise, 2203 // fallback to ASL. 2204 auto log_callback = OsLogger::GetLogFunction(); 2205 if (log_callback) 2206 DNBLogSetLogCallback(log_callback, nullptr); 2207 else 2208 DNBLogSetLogCallback(ASLLogCallback, nullptr); 2209 } 2210 2211 // Update logging to use the configured log channel bitmask. 2212 DNBLogSetLogMask(bitmask); 2213 p++; 2214 } 2215 } 2216 // We're not going to support logging to a file for now. All logging 2217 // goes through ASL or the previously arranged log callback. 2218 #if 0 2219 else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0) 2220 { 2221 p += sizeof ("mode=") - 1; 2222 if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0) 2223 { 2224 DNBLogToASL (); 2225 p += sizeof ("asl;") - 1; 2226 } 2227 else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0) 2228 { 2229 DNBLogToFile (); 2230 p += sizeof ("file;") - 1; 2231 } 2232 else 2233 { 2234 // Ignore unknown argument 2235 const char *c = strchr (p, ';'); 2236 if (c) 2237 p = c + 1; 2238 else 2239 p = strchr (p, '\0'); 2240 } 2241 } 2242 else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0) 2243 { 2244 p += sizeof ("filename=") - 1; 2245 const char *c = strchr (p, ';'); 2246 if (c == NULL) 2247 { 2248 c = strchr (p, '\0'); 2249 continue; 2250 } 2251 char *fn = (char *) alloca (c - p + 1); 2252 strlcpy (fn, p, c - p); 2253 fn[c - p] = '\0'; 2254 2255 // A file name of "asl" is special and is another way to indicate 2256 // that logging should be done via ASL, not by file. 2257 if (strcmp (fn, "asl") == 0) 2258 { 2259 DNBLogToASL (); 2260 } 2261 else 2262 { 2263 FILE *f = fopen (fn, "w"); 2264 if (f) 2265 { 2266 DNBLogSetLogFile (f); 2267 DNBEnableLogging (f, DNBLogGetLogMask ()); 2268 DNBLogToFile (); 2269 } 2270 } 2271 p = c + 1; 2272 } 2273 #endif /* #if 0 to enforce ASL logging only. */ 2274 else { 2275 // Ignore unknown argument 2276 const char *c = strchr(p, ';'); 2277 if (c) 2278 p = c + 1; 2279 else 2280 p = strchr(p, '\0'); 2281 } 2282 } 2283 2284 return rnb_success; 2285 } 2286 2287 rnb_err_t RNBRemote::HandlePacket_QThreadSuffixSupported(const char *p) { 2288 m_thread_suffix_supported = true; 2289 return SendPacket("OK"); 2290 } 2291 2292 rnb_err_t RNBRemote::HandlePacket_QStartNoAckMode(const char *p) { 2293 // Send the OK packet first so the correct checksum is appended... 2294 rnb_err_t result = SendPacket("OK"); 2295 m_noack_mode = true; 2296 return result; 2297 } 2298 2299 rnb_err_t RNBRemote::HandlePacket_QSetLogging(const char *p) { 2300 p += sizeof("QSetLogging:") - 1; 2301 rnb_err_t result = set_logging(p); 2302 if (result == rnb_success) 2303 return SendPacket("OK"); 2304 else 2305 return SendPacket("E35"); 2306 } 2307 2308 rnb_err_t RNBRemote::HandlePacket_QSetDisableASLR(const char *p) { 2309 extern int g_disable_aslr; 2310 p += sizeof("QSetDisableASLR:") - 1; 2311 switch (*p) { 2312 case '0': 2313 g_disable_aslr = 0; 2314 break; 2315 case '1': 2316 g_disable_aslr = 1; 2317 break; 2318 default: 2319 return SendPacket("E56"); 2320 } 2321 return SendPacket("OK"); 2322 } 2323 2324 rnb_err_t RNBRemote::HandlePacket_QSetSTDIO(const char *p) { 2325 // Only set stdin/out/err if we don't already have a process 2326 if (!m_ctx.HasValidProcessID()) { 2327 bool success = false; 2328 // Check the seventh character since the packet will be one of: 2329 // QSetSTDIN 2330 // QSetSTDOUT 2331 // QSetSTDERR 2332 StdStringExtractor packet(p); 2333 packet.SetFilePos(7); 2334 char ch = packet.GetChar(); 2335 while (packet.GetChar() != ':') 2336 /* Do nothing. */; 2337 2338 switch (ch) { 2339 case 'I': // STDIN 2340 packet.GetHexByteString(m_ctx.GetSTDIN()); 2341 success = !m_ctx.GetSTDIN().empty(); 2342 break; 2343 2344 case 'O': // STDOUT 2345 packet.GetHexByteString(m_ctx.GetSTDOUT()); 2346 success = !m_ctx.GetSTDOUT().empty(); 2347 break; 2348 2349 case 'E': // STDERR 2350 packet.GetHexByteString(m_ctx.GetSTDERR()); 2351 success = !m_ctx.GetSTDERR().empty(); 2352 break; 2353 2354 default: 2355 break; 2356 } 2357 if (success) 2358 return SendPacket("OK"); 2359 return SendPacket("E57"); 2360 } 2361 return SendPacket("E58"); 2362 } 2363 2364 rnb_err_t RNBRemote::HandlePacket_QSetWorkingDir(const char *p) { 2365 // Only set the working directory if we don't already have a process 2366 if (!m_ctx.HasValidProcessID()) { 2367 StdStringExtractor packet(p += sizeof("QSetWorkingDir:") - 1); 2368 if (packet.GetHexByteString(m_ctx.GetWorkingDir())) { 2369 struct stat working_dir_stat; 2370 if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) { 2371 m_ctx.GetWorkingDir().clear(); 2372 return SendPacket("E61"); // Working directory doesn't exist... 2373 } else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) { 2374 return SendPacket("OK"); 2375 } else { 2376 m_ctx.GetWorkingDir().clear(); 2377 return SendPacket("E62"); // Working directory isn't a directory... 2378 } 2379 } 2380 return SendPacket("E59"); // Invalid path 2381 } 2382 return SendPacket( 2383 "E60"); // Already had a process, too late to set working dir 2384 } 2385 2386 rnb_err_t RNBRemote::HandlePacket_QSyncThreadState(const char *p) { 2387 if (!m_ctx.HasValidProcessID()) { 2388 // We allow gdb to connect to a server that hasn't started running 2389 // the target yet. gdb still wants to ask questions about it and 2390 // freaks out if it gets an error. So just return OK here. 2391 return SendPacket("OK"); 2392 } 2393 2394 errno = 0; 2395 p += strlen("QSyncThreadState:"); 2396 nub_thread_t tid = strtoul(p, NULL, 16); 2397 if (errno != 0 && tid == 0) { 2398 return HandlePacket_ILLFORMED( 2399 __FILE__, __LINE__, p, 2400 "Invalid thread number in QSyncThreadState packet"); 2401 } 2402 if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid)) 2403 return SendPacket("OK"); 2404 else 2405 return SendPacket("E61"); 2406 } 2407 2408 rnb_err_t RNBRemote::HandlePacket_QSetDetachOnError(const char *p) { 2409 p += sizeof("QSetDetachOnError:") - 1; 2410 bool should_detach = true; 2411 switch (*p) { 2412 case '0': 2413 should_detach = false; 2414 break; 2415 case '1': 2416 should_detach = true; 2417 break; 2418 default: 2419 return HandlePacket_ILLFORMED( 2420 __FILE__, __LINE__, p, 2421 "Invalid value for QSetDetachOnError - should be 0 or 1"); 2422 break; 2423 } 2424 2425 m_ctx.SetDetachOnError(should_detach); 2426 return SendPacket("OK"); 2427 } 2428 2429 rnb_err_t RNBRemote::HandlePacket_qStructuredDataPlugins(const char *p) { 2430 // We'll return a JSON array of supported packet types. 2431 // The type is significant. For each of the supported 2432 // packet types that have been enabled, there will be a 2433 // 'J' async packet sent to the client with payload data. 2434 // This payload data will be a JSON dictionary, and the 2435 // top level dictionary will contain a string field with 2436 // its value set to the relevant packet type from this list. 2437 JSONGenerator::Array supported_json_packets; 2438 2439 // Check for DarwinLog (libtrace os_log/activity support). 2440 if (DarwinLogCollector::IsSupported()) 2441 supported_json_packets.AddItem( 2442 JSONGenerator::StringSP(new JSONGenerator::String("DarwinLog"))); 2443 2444 // Send back the array. 2445 std::ostringstream stream; 2446 supported_json_packets.Dump(stream); 2447 return SendPacket(stream.str()); 2448 } 2449 2450 rnb_err_t RNBRemote::HandlePacket_QConfigureDarwinLog(const char *p) { 2451 if (!DarwinLogCollector::IsSupported()) { 2452 // We should never have been given this request. 2453 return SendPacket("E89"); 2454 } 2455 2456 // Ensure we have a process. We expect a separate configure request for 2457 // each process launched/attached. 2458 const nub_process_t pid = m_ctx.ProcessID(); 2459 if (pid == INVALID_NUB_PROCESS) 2460 return SendPacket("E94"); 2461 2462 // Get the configuration dictionary. 2463 p += strlen("QConfigureDarwinLog:"); 2464 2465 // The configuration dictionary is binary encoded. 2466 std::vector<uint8_t> unescaped_config_data = decode_binary_data(p, -1); 2467 std::string unescaped_config_string((const char *)&unescaped_config_data[0], 2468 unescaped_config_data.size()); 2469 DNBLogThreadedIf(LOG_DARWIN_LOG, "DarwinLog: received config data: \"%s\"", 2470 unescaped_config_string.c_str()); 2471 auto configuration_sp = 2472 JSONParser(unescaped_config_string.c_str()).ParseJSONValue(); 2473 if (!configuration_sp) { 2474 // Malformed request - we require configuration data 2475 // indicating whether we're enabling or disabling. 2476 return SendPacket("E90"); 2477 } 2478 2479 if (!JSONObject::classof(configuration_sp.get())) { 2480 // Configuration data is not of the right type. 2481 return SendPacket("E91"); 2482 } 2483 JSONObject &config_dict = *static_cast<JSONObject *>(configuration_sp.get()); 2484 2485 // Check if we're enabling or disabling. 2486 auto enabled_sp = config_dict.GetObject("enabled"); 2487 if (!enabled_sp) { 2488 // Missing required "enabled" field. 2489 return SendPacket("E92"); 2490 } 2491 if (!JSONTrue::classof(enabled_sp.get()) && 2492 !JSONFalse::classof(enabled_sp.get())) { 2493 // Should be a boolean type, but wasn't. 2494 return SendPacket("E93"); 2495 } 2496 const bool enabling = JSONTrue::classof(enabled_sp.get()); 2497 2498 // TODO - handle other configuration parameters here. 2499 2500 // Shut down any active activity stream for the process. 2501 DarwinLogCollector::CancelStreamForProcess(pid); 2502 2503 if (enabling) { 2504 // Look up the procecess. 2505 if (!DarwinLogCollector::StartCollectingForProcess(pid, config_dict)) 2506 return SendPacket("E95"); 2507 } 2508 2509 return SendPacket("OK"); 2510 } 2511 2512 rnb_err_t RNBRemote::HandlePacket_QListThreadsInStopReply(const char *p) { 2513 // If this packet is received, it allows us to send an extra key/value 2514 // pair in the stop reply packets where we will list all of the thread IDs 2515 // separated by commas: 2516 // 2517 // "threads:10a,10b,10c;" 2518 // 2519 // This will get included in the stop reply packet as something like: 2520 // 2521 // "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;" 2522 // 2523 // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and 2524 // speed things up a bit. 2525 // 2526 // Send the OK packet first so the correct checksum is appended... 2527 rnb_err_t result = SendPacket("OK"); 2528 m_list_threads_in_stop_reply = true; 2529 2530 return result; 2531 } 2532 2533 rnb_err_t RNBRemote::HandlePacket_QSetMaxPayloadSize(const char *p) { 2534 /* The number of characters in a packet payload that gdb is 2535 prepared to accept. The packet-start char, packet-end char, 2536 2 checksum chars and terminating null character are not included 2537 in this size. */ 2538 p += sizeof("QSetMaxPayloadSize:") - 1; 2539 errno = 0; 2540 uint32_t size = static_cast<uint32_t>(strtoul(p, NULL, 16)); 2541 if (errno != 0 && size == 0) { 2542 return HandlePacket_ILLFORMED( 2543 __FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet"); 2544 } 2545 m_max_payload_size = size; 2546 return SendPacket("OK"); 2547 } 2548 2549 rnb_err_t RNBRemote::HandlePacket_QSetMaxPacketSize(const char *p) { 2550 /* This tells us the largest packet that gdb can handle. 2551 i.e. the size of gdb's packet-reading buffer. 2552 QSetMaxPayloadSize is preferred because it is less ambiguous. */ 2553 p += sizeof("QSetMaxPacketSize:") - 1; 2554 errno = 0; 2555 uint32_t size = static_cast<uint32_t>(strtoul(p, NULL, 16)); 2556 if (errno != 0 && size == 0) { 2557 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 2558 "Invalid length in QSetMaxPacketSize packet"); 2559 } 2560 m_max_payload_size = size - 5; 2561 return SendPacket("OK"); 2562 } 2563 2564 rnb_err_t RNBRemote::HandlePacket_QEnvironment(const char *p) { 2565 /* This sets the environment for the target program. The packet is of the 2566 form: 2567 2568 QEnvironment:VARIABLE=VALUE 2569 2570 */ 2571 2572 DNBLogThreadedIf( 2573 LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"", 2574 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2575 2576 p += sizeof("QEnvironment:") - 1; 2577 RNBContext &ctx = Context(); 2578 2579 ctx.PushEnvironment(p); 2580 return SendPacket("OK"); 2581 } 2582 2583 rnb_err_t RNBRemote::HandlePacket_QEnvironmentHexEncoded(const char *p) { 2584 /* This sets the environment for the target program. The packet is of the 2585 form: 2586 2587 QEnvironmentHexEncoded:VARIABLE=VALUE 2588 2589 The VARIABLE=VALUE part is sent hex-encoded so characters like '#' with 2590 special 2591 meaning in the remote protocol won't break it. 2592 */ 2593 2594 DNBLogThreadedIf(LOG_RNB_REMOTE, 2595 "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"", 2596 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 2597 __FUNCTION__, p); 2598 2599 p += sizeof("QEnvironmentHexEncoded:") - 1; 2600 2601 std::string arg; 2602 const char *c; 2603 c = p; 2604 while (*c != '\0') { 2605 if (*(c + 1) == '\0') { 2606 return HandlePacket_ILLFORMED( 2607 __FILE__, __LINE__, p, 2608 "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2609 } 2610 char smallbuf[3]; 2611 smallbuf[0] = *c; 2612 smallbuf[1] = *(c + 1); 2613 smallbuf[2] = '\0'; 2614 errno = 0; 2615 int ch = static_cast<int>(strtoul(smallbuf, NULL, 16)); 2616 if (errno != 0 && ch == 0) { 2617 return HandlePacket_ILLFORMED( 2618 __FILE__, __LINE__, p, 2619 "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2620 } 2621 arg.push_back(ch); 2622 c += 2; 2623 } 2624 2625 RNBContext &ctx = Context(); 2626 if (arg.length() > 0) 2627 ctx.PushEnvironment(arg.c_str()); 2628 2629 return SendPacket("OK"); 2630 } 2631 2632 rnb_err_t RNBRemote::HandlePacket_QLaunchArch(const char *p) { 2633 p += sizeof("QLaunchArch:") - 1; 2634 if (DNBSetArchitecture(p)) 2635 return SendPacket("OK"); 2636 return SendPacket("E63"); 2637 } 2638 2639 rnb_err_t RNBRemote::HandlePacket_QSetProcessEvent(const char *p) { 2640 p += sizeof("QSetProcessEvent:") - 1; 2641 // If the process is running, then send the event to the process, otherwise 2642 // store it in the context. 2643 if (Context().HasValidProcessID()) { 2644 if (DNBProcessSendEvent(Context().ProcessID(), p)) 2645 return SendPacket("OK"); 2646 else 2647 return SendPacket("E80"); 2648 } else { 2649 Context().PushProcessEvent(p); 2650 } 2651 return SendPacket("OK"); 2652 } 2653 2654 void append_hex_value(std::ostream &ostrm, const void *buf, size_t buf_size, 2655 bool swap) { 2656 int i; 2657 const uint8_t *p = (const uint8_t *)buf; 2658 if (swap) { 2659 for (i = static_cast<int>(buf_size) - 1; i >= 0; i--) 2660 ostrm << RAWHEX8(p[i]); 2661 } else { 2662 for (size_t i = 0; i < buf_size; i++) 2663 ostrm << RAWHEX8(p[i]); 2664 } 2665 } 2666 2667 void append_hexified_string(std::ostream &ostrm, const std::string &string) { 2668 size_t string_size = string.size(); 2669 const char *string_buf = string.c_str(); 2670 for (size_t i = 0; i < string_size; i++) { 2671 ostrm << RAWHEX8(*(string_buf + i)); 2672 } 2673 } 2674 2675 void register_value_in_hex_fixed_width(std::ostream &ostrm, nub_process_t pid, 2676 nub_thread_t tid, 2677 const register_map_entry_t *reg, 2678 const DNBRegisterValue *reg_value_ptr) { 2679 if (reg != NULL) { 2680 DNBRegisterValue reg_value; 2681 if (reg_value_ptr == NULL) { 2682 if (DNBThreadGetRegisterValueByID(pid, tid, reg->nub_info.set, 2683 reg->nub_info.reg, ®_value)) 2684 reg_value_ptr = ®_value; 2685 } 2686 2687 if (reg_value_ptr) { 2688 append_hex_value(ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, 2689 false); 2690 } else { 2691 // If we fail to read a register value, check if it has a default 2692 // fail value. If it does, return this instead in case some of 2693 // the registers are not available on the current system. 2694 if (reg->nub_info.size > 0) { 2695 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0'); 2696 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 2697 } 2698 } 2699 } 2700 } 2701 2702 void debugserver_regnum_with_fixed_width_hex_register_value( 2703 std::ostream &ostrm, nub_process_t pid, nub_thread_t tid, 2704 const register_map_entry_t *reg, const DNBRegisterValue *reg_value_ptr) { 2705 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX 2706 // gdb register number, and VVVVVVVV is the correct number of hex bytes 2707 // as ASCII for the register value. 2708 if (reg != NULL) { 2709 ostrm << RAWHEX8(reg->debugserver_regnum) << ':'; 2710 register_value_in_hex_fixed_width(ostrm, pid, tid, reg, reg_value_ptr); 2711 ostrm << ';'; 2712 } 2713 } 2714 2715 void RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo( 2716 nub_process_t pid, nub_addr_t dispatch_qaddr, nub_addr_t &dispatch_queue_t, 2717 std::string &queue_name, uint64_t &queue_width, 2718 uint64_t &queue_serialnum) const { 2719 queue_name.clear(); 2720 queue_width = 0; 2721 queue_serialnum = 0; 2722 2723 if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS && 2724 dispatch_qaddr != 0) { 2725 dispatch_queue_t = DNBProcessMemoryReadPointer(pid, dispatch_qaddr); 2726 if (dispatch_queue_t) { 2727 queue_width = DNBProcessMemoryReadInteger( 2728 pid, dispatch_queue_t + dqo_width, dqo_width_size, 0); 2729 queue_serialnum = DNBProcessMemoryReadInteger( 2730 pid, dispatch_queue_t + dqo_serialnum, dqo_serialnum_size, 0); 2731 2732 if (dqo_version >= 4) { 2733 // libdispatch versions 4+, pointer to dispatch name is in the 2734 // queue structure. 2735 nub_addr_t pointer_to_label_address = dispatch_queue_t + dqo_label; 2736 nub_addr_t label_addr = 2737 DNBProcessMemoryReadPointer(pid, pointer_to_label_address); 2738 if (label_addr) 2739 queue_name = DNBProcessMemoryReadCString(pid, label_addr); 2740 } else { 2741 // libdispatch versions 1-3, dispatch name is a fixed width char array 2742 // in the queue structure. 2743 queue_name = DNBProcessMemoryReadCStringFixed( 2744 pid, dispatch_queue_t + dqo_label, dqo_label_size); 2745 } 2746 } 2747 } 2748 } 2749 2750 struct StackMemory { 2751 uint8_t bytes[2 * sizeof(nub_addr_t)]; 2752 nub_size_t length; 2753 }; 2754 typedef std::map<nub_addr_t, StackMemory> StackMemoryMap; 2755 2756 static void ReadStackMemory(nub_process_t pid, nub_thread_t tid, 2757 StackMemoryMap &stack_mmap, 2758 uint32_t backtrace_limit = 256) { 2759 DNBRegisterValue reg_value; 2760 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, 2761 GENERIC_REGNUM_FP, ®_value)) { 2762 uint32_t frame_count = 0; 2763 uint64_t fp = 0; 2764 if (reg_value.info.size == 4) 2765 fp = reg_value.value.uint32; 2766 else 2767 fp = reg_value.value.uint64; 2768 while (fp != 0) { 2769 // Make sure we never recurse more than 256 times so we don't recurse too 2770 // far or 2771 // store up too much memory in the expedited cache 2772 if (++frame_count > backtrace_limit) 2773 break; 2774 2775 const nub_size_t read_size = reg_value.info.size * 2; 2776 StackMemory stack_memory; 2777 stack_memory.length = read_size; 2778 if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != 2779 read_size) 2780 break; 2781 // Make sure we don't try to put the same stack memory in more than once 2782 if (stack_mmap.find(fp) != stack_mmap.end()) 2783 break; 2784 // Put the entry into the cache 2785 stack_mmap[fp] = stack_memory; 2786 // Dereference the frame pointer to get to the previous frame pointer 2787 if (reg_value.info.size == 4) 2788 fp = ((uint32_t *)stack_memory.bytes)[0]; 2789 else 2790 fp = ((uint64_t *)stack_memory.bytes)[0]; 2791 } 2792 } 2793 } 2794 2795 rnb_err_t RNBRemote::SendStopReplyPacketForThread(nub_thread_t tid) { 2796 const nub_process_t pid = m_ctx.ProcessID(); 2797 if (pid == INVALID_NUB_PROCESS) 2798 return SendPacket("E50"); 2799 2800 struct DNBThreadStopInfo tid_stop_info; 2801 2802 /* Fill the remaining space in this packet with as many registers 2803 as we can stuff in there. */ 2804 2805 if (DNBThreadGetStopReason(pid, tid, &tid_stop_info)) { 2806 const bool did_exec = tid_stop_info.reason == eStopTypeExec; 2807 if (did_exec) { 2808 RNBRemote::InitializeRegisters(true); 2809 2810 // Reset any symbols that need resetting when we exec 2811 m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS; 2812 m_dispatch_queue_offsets.Clear(); 2813 } 2814 2815 std::ostringstream ostrm; 2816 // Output the T packet with the thread 2817 ostrm << 'T'; 2818 int signum = tid_stop_info.details.signal.signo; 2819 DNBLogThreadedIf( 2820 LOG_RNB_PROC, "%8d %s got signal signo = %u, exc_type = %u", 2821 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, 2822 signum, tid_stop_info.details.exception.type); 2823 2824 // Translate any mach exceptions to gdb versions, unless they are 2825 // common exceptions like a breakpoint or a soft signal. 2826 switch (tid_stop_info.details.exception.type) { 2827 default: 2828 signum = 0; 2829 break; 2830 case EXC_BREAKPOINT: 2831 signum = SIGTRAP; 2832 break; 2833 case EXC_BAD_ACCESS: 2834 signum = TARGET_EXC_BAD_ACCESS; 2835 break; 2836 case EXC_BAD_INSTRUCTION: 2837 signum = TARGET_EXC_BAD_INSTRUCTION; 2838 break; 2839 case EXC_ARITHMETIC: 2840 signum = TARGET_EXC_ARITHMETIC; 2841 break; 2842 case EXC_EMULATION: 2843 signum = TARGET_EXC_EMULATION; 2844 break; 2845 case EXC_SOFTWARE: 2846 if (tid_stop_info.details.exception.data_count == 2 && 2847 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2848 signum = static_cast<int>(tid_stop_info.details.exception.data[1]); 2849 else 2850 signum = TARGET_EXC_SOFTWARE; 2851 break; 2852 } 2853 2854 ostrm << RAWHEX8(signum & 0xff); 2855 2856 ostrm << std::hex << "thread:" << tid << ';'; 2857 2858 const char *thread_name = DNBThreadGetName(pid, tid); 2859 if (thread_name && thread_name[0]) { 2860 size_t thread_name_len = strlen(thread_name); 2861 2862 if (::strcspn(thread_name, "$#+-;:") == thread_name_len) 2863 ostrm << std::hex << "name:" << thread_name << ';'; 2864 else { 2865 // the thread name contains special chars, send as hex bytes 2866 ostrm << std::hex << "hexname:"; 2867 const uint8_t *u_thread_name = (const uint8_t *)thread_name; 2868 for (size_t i = 0; i < thread_name_len; i++) 2869 ostrm << RAWHEX8(u_thread_name[i]); 2870 ostrm << ';'; 2871 } 2872 } 2873 2874 // If a 'QListThreadsInStopReply' was sent to enable this feature, we 2875 // will send all thread IDs back in the "threads" key whose value is 2876 // a list of hex thread IDs separated by commas: 2877 // "threads:10a,10b,10c;" 2878 // This will save the debugger from having to send a pair of qfThreadInfo 2879 // and qsThreadInfo packets, but it also might take a lot of room in the 2880 // stop reply packet, so it must be enabled only on systems where there 2881 // are no limits on packet lengths. 2882 if (m_list_threads_in_stop_reply) { 2883 const nub_size_t numthreads = DNBProcessGetNumThreads(pid); 2884 if (numthreads > 0) { 2885 std::vector<uint64_t> pc_values; 2886 ostrm << std::hex << "threads:"; 2887 for (nub_size_t i = 0; i < numthreads; ++i) { 2888 nub_thread_t th = DNBProcessGetThreadAtIndex(pid, i); 2889 if (i > 0) 2890 ostrm << ','; 2891 ostrm << std::hex << th; 2892 DNBRegisterValue pc_regval; 2893 if (DNBThreadGetRegisterValueByID(pid, th, REGISTER_SET_GENERIC, 2894 GENERIC_REGNUM_PC, &pc_regval)) { 2895 uint64_t pc = INVALID_NUB_ADDRESS; 2896 if (pc_regval.value.uint64 != INVALID_NUB_ADDRESS) { 2897 if (pc_regval.info.size == 4) { 2898 pc = pc_regval.value.uint32; 2899 } else if (pc_regval.info.size == 8) { 2900 pc = pc_regval.value.uint64; 2901 } 2902 if (pc != INVALID_NUB_ADDRESS) { 2903 pc_values.push_back(pc); 2904 } 2905 } 2906 } 2907 } 2908 ostrm << ';'; 2909 2910 // If we failed to get any of the thread pc values, the size of our 2911 // vector will not 2912 // be the same as the # of threads. Don't provide any expedited thread 2913 // pc values in 2914 // that case. This should not happen. 2915 if (pc_values.size() == numthreads) { 2916 ostrm << std::hex << "thread-pcs:"; 2917 for (nub_size_t i = 0; i < numthreads; ++i) { 2918 if (i > 0) 2919 ostrm << ','; 2920 ostrm << std::hex << pc_values[i]; 2921 } 2922 ostrm << ';'; 2923 } 2924 } 2925 2926 // Include JSON info that describes the stop reason for any threads 2927 // that actually have stop reasons. We use the new "jstopinfo" key 2928 // whose values is hex ascii JSON that contains the thread IDs 2929 // thread stop info only for threads that have stop reasons. Only send 2930 // this if we have more than one thread otherwise this packet has all 2931 // the info it needs. 2932 if (numthreads > 1) { 2933 const bool threads_with_valid_stop_info_only = true; 2934 JSONGenerator::ObjectSP threads_info_sp = 2935 GetJSONThreadsInfo(threads_with_valid_stop_info_only); 2936 if (threads_info_sp) { 2937 ostrm << std::hex << "jstopinfo:"; 2938 std::ostringstream json_strm; 2939 threads_info_sp->Dump(json_strm); 2940 append_hexified_string(ostrm, json_strm.str()); 2941 ostrm << ';'; 2942 } 2943 } 2944 } 2945 2946 if (g_num_reg_entries == 0) 2947 InitializeRegisters(); 2948 2949 if (g_reg_entries != NULL) { 2950 DNBRegisterValue reg_value; 2951 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) { 2952 // Expedite all registers in the first register set that aren't 2953 // contained in other registers 2954 if (g_reg_entries[reg].nub_info.set == 1 && 2955 g_reg_entries[reg].nub_info.value_regs == NULL) { 2956 if (!DNBThreadGetRegisterValueByID( 2957 pid, tid, g_reg_entries[reg].nub_info.set, 2958 g_reg_entries[reg].nub_info.reg, ®_value)) 2959 continue; 2960 2961 debugserver_regnum_with_fixed_width_hex_register_value( 2962 ostrm, pid, tid, &g_reg_entries[reg], ®_value); 2963 } 2964 } 2965 } 2966 2967 if (did_exec) { 2968 ostrm << "reason:exec;"; 2969 } else if (tid_stop_info.details.exception.type) { 2970 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type 2971 << ';'; 2972 ostrm << "mecount:" << std::hex 2973 << tid_stop_info.details.exception.data_count << ';'; 2974 for (nub_size_t i = 0; i < tid_stop_info.details.exception.data_count; 2975 ++i) 2976 ostrm << "medata:" << std::hex 2977 << tid_stop_info.details.exception.data[i] << ';'; 2978 } 2979 2980 // Add expedited stack memory so stack backtracing doesn't need to read 2981 // anything from the 2982 // frame pointer chain. 2983 StackMemoryMap stack_mmap; 2984 ReadStackMemory(pid, tid, stack_mmap, 2); 2985 if (!stack_mmap.empty()) { 2986 for (const auto &stack_memory : stack_mmap) { 2987 ostrm << "memory:" << HEXBASE << stack_memory.first << '='; 2988 append_hex_value(ostrm, stack_memory.second.bytes, 2989 stack_memory.second.length, false); 2990 ostrm << ';'; 2991 } 2992 } 2993 2994 return SendPacket(ostrm.str()); 2995 } 2996 return SendPacket("E51"); 2997 } 2998 2999 /* '?' 3000 The stop reply packet - tell gdb what the status of the inferior is. 3001 Often called the questionmark_packet. */ 3002 3003 rnb_err_t RNBRemote::HandlePacket_last_signal(const char *unused) { 3004 if (!m_ctx.HasValidProcessID()) { 3005 // Inferior is not yet specified/running 3006 return SendPacket("E02"); 3007 } 3008 3009 nub_process_t pid = m_ctx.ProcessID(); 3010 nub_state_t pid_state = DNBProcessGetState(pid); 3011 3012 switch (pid_state) { 3013 case eStateAttaching: 3014 case eStateLaunching: 3015 case eStateRunning: 3016 case eStateStepping: 3017 case eStateDetached: 3018 return rnb_success; // Ignore 3019 3020 case eStateSuspended: 3021 case eStateStopped: 3022 case eStateCrashed: { 3023 nub_thread_t tid = DNBProcessGetCurrentThread(pid); 3024 // Make sure we set the current thread so g and p packets return 3025 // the data the gdb will expect. 3026 SetCurrentThread(tid); 3027 3028 SendStopReplyPacketForThread(tid); 3029 } break; 3030 3031 case eStateInvalid: 3032 case eStateUnloaded: 3033 case eStateExited: { 3034 char pid_exited_packet[16] = ""; 3035 int pid_status = 0; 3036 // Process exited with exit status 3037 if (!DNBProcessGetExitStatus(pid, &pid_status)) 3038 pid_status = 0; 3039 3040 if (pid_status) { 3041 if (WIFEXITED(pid_status)) 3042 snprintf(pid_exited_packet, sizeof(pid_exited_packet), "W%02x", 3043 WEXITSTATUS(pid_status)); 3044 else if (WIFSIGNALED(pid_status)) 3045 snprintf(pid_exited_packet, sizeof(pid_exited_packet), "X%02x", 3046 WEXITSTATUS(pid_status)); 3047 else if (WIFSTOPPED(pid_status)) 3048 snprintf(pid_exited_packet, sizeof(pid_exited_packet), "S%02x", 3049 WSTOPSIG(pid_status)); 3050 } 3051 3052 // If we have an empty exit packet, lets fill one in to be safe. 3053 if (!pid_exited_packet[0]) { 3054 strlcpy(pid_exited_packet, "W00", sizeof(pid_exited_packet) - 1); 3055 pid_exited_packet[sizeof(pid_exited_packet) - 1] = '\0'; 3056 } 3057 3058 const char *exit_info = DNBProcessGetExitInfo(pid); 3059 if (exit_info != NULL && *exit_info != '\0') { 3060 std::ostringstream exit_packet; 3061 exit_packet << pid_exited_packet; 3062 exit_packet << ';'; 3063 exit_packet << RAW_HEXBASE << "description"; 3064 exit_packet << ':'; 3065 for (size_t i = 0; exit_info[i] != '\0'; i++) 3066 exit_packet << RAWHEX8(exit_info[i]); 3067 exit_packet << ';'; 3068 return SendPacket(exit_packet.str()); 3069 } else 3070 return SendPacket(pid_exited_packet); 3071 } break; 3072 } 3073 return rnb_success; 3074 } 3075 3076 rnb_err_t RNBRemote::HandlePacket_M(const char *p) { 3077 if (p == NULL || p[0] == '\0' || strlen(p) < 3) { 3078 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short M packet"); 3079 } 3080 3081 char *c; 3082 p++; 3083 errno = 0; 3084 nub_addr_t addr = strtoull(p, &c, 16); 3085 if (errno != 0 && addr == 0) { 3086 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3087 "Invalid address in M packet"); 3088 } 3089 if (*c != ',') { 3090 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3091 "Comma sep missing in M packet"); 3092 } 3093 3094 /* Advance 'p' to the length part of the packet. */ 3095 p += (c - p) + 1; 3096 3097 errno = 0; 3098 unsigned long length = strtoul(p, &c, 16); 3099 if (errno != 0 && length == 0) { 3100 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3101 "Invalid length in M packet"); 3102 } 3103 if (length == 0) { 3104 return SendPacket("OK"); 3105 } 3106 3107 if (*c != ':') { 3108 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3109 "Missing colon in M packet"); 3110 } 3111 /* Advance 'p' to the data part of the packet. */ 3112 p += (c - p) + 1; 3113 3114 size_t datalen = strlen(p); 3115 if (datalen & 0x1) { 3116 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3117 "Uneven # of hex chars for data in M packet"); 3118 } 3119 if (datalen == 0) { 3120 return SendPacket("OK"); 3121 } 3122 3123 uint8_t *buf = (uint8_t *)alloca(datalen / 2); 3124 uint8_t *i = buf; 3125 3126 while (*p != '\0' && *(p + 1) != '\0') { 3127 char hexbuf[3]; 3128 hexbuf[0] = *p; 3129 hexbuf[1] = *(p + 1); 3130 hexbuf[2] = '\0'; 3131 errno = 0; 3132 uint8_t byte = strtoul(hexbuf, NULL, 16); 3133 if (errno != 0 && byte == 0) { 3134 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3135 "Invalid hex byte in M packet"); 3136 } 3137 *i++ = byte; 3138 p += 2; 3139 } 3140 3141 nub_size_t wrote = 3142 DNBProcessMemoryWrite(m_ctx.ProcessID(), addr, length, buf); 3143 if (wrote != length) 3144 return SendPacket("E09"); 3145 else 3146 return SendPacket("OK"); 3147 } 3148 3149 rnb_err_t RNBRemote::HandlePacket_m(const char *p) { 3150 if (p == NULL || p[0] == '\0' || strlen(p) < 3) { 3151 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short m packet"); 3152 } 3153 3154 char *c; 3155 p++; 3156 errno = 0; 3157 nub_addr_t addr = strtoull(p, &c, 16); 3158 if (errno != 0 && addr == 0) { 3159 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3160 "Invalid address in m packet"); 3161 } 3162 if (*c != ',') { 3163 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3164 "Comma sep missing in m packet"); 3165 } 3166 3167 /* Advance 'p' to the length part of the packet. */ 3168 p += (c - p) + 1; 3169 3170 errno = 0; 3171 auto length = strtoul(p, NULL, 16); 3172 if (errno != 0 && length == 0) { 3173 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3174 "Invalid length in m packet"); 3175 } 3176 if (length == 0) { 3177 return SendPacket(""); 3178 } 3179 3180 std::string buf(length, '\0'); 3181 if (buf.empty()) { 3182 return SendPacket("E78"); 3183 } 3184 nub_size_t bytes_read = 3185 DNBProcessMemoryRead(m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3186 if (bytes_read == 0) { 3187 return SendPacket("E08"); 3188 } 3189 3190 // "The reply may contain fewer bytes than requested if the server was able 3191 // to read only part of the region of memory." 3192 length = bytes_read; 3193 3194 std::ostringstream ostrm; 3195 for (unsigned long i = 0; i < length; i++) 3196 ostrm << RAWHEX8(buf[i]); 3197 return SendPacket(ostrm.str()); 3198 } 3199 3200 // Read memory, sent it up as binary data. 3201 // Usage: xADDR,LEN 3202 // ADDR and LEN are both base 16. 3203 3204 // Responds with 'OK' for zero-length request 3205 // or 3206 // 3207 // DATA 3208 // 3209 // where DATA is the binary data payload. 3210 3211 rnb_err_t RNBRemote::HandlePacket_x(const char *p) { 3212 if (p == NULL || p[0] == '\0' || strlen(p) < 3) { 3213 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short X packet"); 3214 } 3215 3216 char *c; 3217 p++; 3218 errno = 0; 3219 nub_addr_t addr = strtoull(p, &c, 16); 3220 if (errno != 0) { 3221 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3222 "Invalid address in X packet"); 3223 } 3224 if (*c != ',') { 3225 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3226 "Comma sep missing in X packet"); 3227 } 3228 3229 /* Advance 'p' to the number of bytes to be read. */ 3230 p += (c - p) + 1; 3231 3232 errno = 0; 3233 auto length = strtoul(p, NULL, 16); 3234 if (errno != 0) { 3235 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3236 "Invalid length in x packet"); 3237 } 3238 3239 // zero length read means this is a test of whether that packet is implemented 3240 // or not. 3241 if (length == 0) { 3242 return SendPacket("OK"); 3243 } 3244 3245 std::vector<uint8_t> buf(length); 3246 3247 if (buf.capacity() != length) { 3248 return SendPacket("E79"); 3249 } 3250 nub_size_t bytes_read = 3251 DNBProcessMemoryRead(m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3252 if (bytes_read == 0) { 3253 return SendPacket("E80"); 3254 } 3255 3256 std::vector<uint8_t> buf_quoted; 3257 buf_quoted.reserve(bytes_read + 30); 3258 for (nub_size_t i = 0; i < bytes_read; i++) { 3259 if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*') { 3260 buf_quoted.push_back(0x7d); 3261 buf_quoted.push_back(buf[i] ^ 0x20); 3262 } else { 3263 buf_quoted.push_back(buf[i]); 3264 } 3265 } 3266 length = buf_quoted.size(); 3267 3268 std::ostringstream ostrm; 3269 for (unsigned long i = 0; i < length; i++) 3270 ostrm << buf_quoted[i]; 3271 3272 return SendPacket(ostrm.str()); 3273 } 3274 3275 rnb_err_t RNBRemote::HandlePacket_X(const char *p) { 3276 if (p == NULL || p[0] == '\0' || strlen(p) < 3) { 3277 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Too short X packet"); 3278 } 3279 3280 char *c; 3281 p++; 3282 errno = 0; 3283 nub_addr_t addr = strtoull(p, &c, 16); 3284 if (errno != 0 && addr == 0) { 3285 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3286 "Invalid address in X packet"); 3287 } 3288 if (*c != ',') { 3289 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3290 "Comma sep missing in X packet"); 3291 } 3292 3293 /* Advance 'p' to the length part of the packet. NB this is the length of the 3294 packet 3295 including any escaped chars. The data payload may be a little bit smaller 3296 after 3297 decoding. */ 3298 p += (c - p) + 1; 3299 3300 errno = 0; 3301 auto length = strtoul(p, NULL, 16); 3302 if (errno != 0 && length == 0) { 3303 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3304 "Invalid length in X packet"); 3305 } 3306 3307 // I think gdb sends a zero length write request to test whether this 3308 // packet is accepted. 3309 if (length == 0) { 3310 return SendPacket("OK"); 3311 } 3312 3313 std::vector<uint8_t> data = decode_binary_data(c, -1); 3314 std::vector<uint8_t>::const_iterator it; 3315 uint8_t *buf = (uint8_t *)alloca(data.size()); 3316 uint8_t *i = buf; 3317 for (it = data.begin(); it != data.end(); ++it) { 3318 *i++ = *it; 3319 } 3320 3321 nub_size_t wrote = 3322 DNBProcessMemoryWrite(m_ctx.ProcessID(), addr, data.size(), buf); 3323 if (wrote != data.size()) 3324 return SendPacket("E08"); 3325 return SendPacket("OK"); 3326 } 3327 3328 /* 'g' -- read registers 3329 Get the contents of the registers for the current thread, 3330 send them to gdb. 3331 Should the setting of the Hg packet determine which thread's registers 3332 are returned? */ 3333 3334 rnb_err_t RNBRemote::HandlePacket_g(const char *p) { 3335 std::ostringstream ostrm; 3336 if (!m_ctx.HasValidProcessID()) { 3337 return SendPacket("E11"); 3338 } 3339 3340 if (g_num_reg_entries == 0) 3341 InitializeRegisters(); 3342 3343 nub_process_t pid = m_ctx.ProcessID(); 3344 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p + 1); 3345 if (tid == INVALID_NUB_THREAD) 3346 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3347 "No thread specified in p packet"); 3348 3349 // Get the register context size first by calling with NULL buffer 3350 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3351 if (reg_ctx_size) { 3352 // Now allocate enough space for the entire register context 3353 std::vector<uint8_t> reg_ctx; 3354 reg_ctx.resize(reg_ctx_size); 3355 // Now read the register context 3356 reg_ctx_size = 3357 DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 3358 if (reg_ctx_size) { 3359 append_hex_value(ostrm, reg_ctx.data(), reg_ctx.size(), false); 3360 return SendPacket(ostrm.str()); 3361 } 3362 } 3363 return SendPacket("E74"); 3364 } 3365 3366 /* 'G XXX...' -- write registers 3367 How is the thread for these specified, beyond "the current thread"? 3368 Does gdb actually use the Hg packet to set this? */ 3369 3370 rnb_err_t RNBRemote::HandlePacket_G(const char *p) { 3371 if (!m_ctx.HasValidProcessID()) { 3372 return SendPacket("E11"); 3373 } 3374 3375 if (g_num_reg_entries == 0) 3376 InitializeRegisters(); 3377 3378 StdStringExtractor packet(p); 3379 packet.SetFilePos(1); // Skip the 'G' 3380 3381 nub_process_t pid = m_ctx.ProcessID(); 3382 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 3383 if (tid == INVALID_NUB_THREAD) 3384 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3385 "No thread specified in p packet"); 3386 3387 // Get the register context size first by calling with NULL buffer 3388 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3389 if (reg_ctx_size) { 3390 // Now allocate enough space for the entire register context 3391 std::vector<uint8_t> reg_ctx; 3392 reg_ctx.resize(reg_ctx_size); 3393 3394 const nub_size_t bytes_extracted = 3395 packet.GetHexBytes(®_ctx[0], reg_ctx.size(), 0xcc); 3396 if (bytes_extracted == reg_ctx.size()) { 3397 // Now write the register context 3398 reg_ctx_size = 3399 DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 3400 if (reg_ctx_size == reg_ctx.size()) 3401 return SendPacket("OK"); 3402 else 3403 return SendPacket("E55"); 3404 } else { 3405 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu " 3406 "bytes, size mismatch\n", 3407 p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); 3408 return SendPacket("E64"); 3409 } 3410 } 3411 return SendPacket("E65"); 3412 } 3413 3414 static bool RNBRemoteShouldCancelCallback(void *not_used) { 3415 RNBRemoteSP remoteSP(g_remoteSP); 3416 if (remoteSP.get() != NULL) { 3417 RNBRemote *remote = remoteSP.get(); 3418 return !remote->Comm().IsConnected(); 3419 } 3420 return true; 3421 } 3422 3423 // FORMAT: _MXXXXXX,PPP 3424 // XXXXXX: big endian hex chars 3425 // PPP: permissions can be any combo of r w x chars 3426 // 3427 // RESPONSE: XXXXXX 3428 // XXXXXX: hex address of the newly allocated memory 3429 // EXX: error code 3430 // 3431 // EXAMPLES: 3432 // _M123000,rw 3433 // _M123000,rwx 3434 // _M123000,xw 3435 3436 rnb_err_t RNBRemote::HandlePacket_AllocateMemory(const char *p) { 3437 StdStringExtractor packet(p); 3438 packet.SetFilePos(2); // Skip the "_M" 3439 3440 nub_addr_t size = packet.GetHexMaxU64(StdStringExtractor::BigEndian, 0); 3441 if (size != 0) { 3442 if (packet.GetChar() == ',') { 3443 uint32_t permissions = 0; 3444 char ch; 3445 bool success = true; 3446 while (success && (ch = packet.GetChar()) != '\0') { 3447 switch (ch) { 3448 case 'r': 3449 permissions |= eMemoryPermissionsReadable; 3450 break; 3451 case 'w': 3452 permissions |= eMemoryPermissionsWritable; 3453 break; 3454 case 'x': 3455 permissions |= eMemoryPermissionsExecutable; 3456 break; 3457 default: 3458 success = false; 3459 break; 3460 } 3461 } 3462 3463 if (success) { 3464 nub_addr_t addr = 3465 DNBProcessMemoryAllocate(m_ctx.ProcessID(), size, permissions); 3466 if (addr != INVALID_NUB_ADDRESS) { 3467 std::ostringstream ostrm; 3468 ostrm << RAW_HEXBASE << addr; 3469 return SendPacket(ostrm.str()); 3470 } 3471 } 3472 } 3473 } 3474 return SendPacket("E53"); 3475 } 3476 3477 // FORMAT: _mXXXXXX 3478 // XXXXXX: address that was previously allocated 3479 // 3480 // RESPONSE: XXXXXX 3481 // OK: address was deallocated 3482 // EXX: error code 3483 // 3484 // EXAMPLES: 3485 // _m123000 3486 3487 rnb_err_t RNBRemote::HandlePacket_DeallocateMemory(const char *p) { 3488 StdStringExtractor packet(p); 3489 packet.SetFilePos(2); // Skip the "_m" 3490 nub_addr_t addr = 3491 packet.GetHexMaxU64(StdStringExtractor::BigEndian, INVALID_NUB_ADDRESS); 3492 3493 if (addr != INVALID_NUB_ADDRESS) { 3494 if (DNBProcessMemoryDeallocate(m_ctx.ProcessID(), addr)) 3495 return SendPacket("OK"); 3496 } 3497 return SendPacket("E54"); 3498 } 3499 3500 // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) 3501 // FORMAT: QSaveRegisterState (when thread suffix is NOT 3502 // supported) 3503 // TTTT: thread ID in hex 3504 // 3505 // RESPONSE: 3506 // SAVEID: Where SAVEID is a decimal number that represents the save ID 3507 // that can be passed back into a "QRestoreRegisterState" packet 3508 // EXX: error code 3509 // 3510 // EXAMPLES: 3511 // QSaveRegisterState;thread:1E34; (when thread suffix is supported) 3512 // QSaveRegisterState (when thread suffix is NOT 3513 // supported) 3514 3515 rnb_err_t RNBRemote::HandlePacket_SaveRegisterState(const char *p) { 3516 nub_process_t pid = m_ctx.ProcessID(); 3517 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 3518 if (tid == INVALID_NUB_THREAD) { 3519 if (m_thread_suffix_supported) 3520 return HandlePacket_ILLFORMED( 3521 __FILE__, __LINE__, p, 3522 "No thread specified in QSaveRegisterState packet"); 3523 else 3524 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3525 "No thread was is set with the Hg packet"); 3526 } 3527 3528 // Get the register context size first by calling with NULL buffer 3529 const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid); 3530 if (save_id != 0) { 3531 char response[64]; 3532 snprintf(response, sizeof(response), "%u", save_id); 3533 return SendPacket(response); 3534 } else { 3535 return SendPacket("E75"); 3536 } 3537 } 3538 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is 3539 // supported) 3540 // FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT 3541 // supported) 3542 // TTTT: thread ID in hex 3543 // SAVEID: a decimal number that represents the save ID that was 3544 // returned from a call to "QSaveRegisterState" 3545 // 3546 // RESPONSE: 3547 // OK: successfully restored registers for the specified thread 3548 // EXX: error code 3549 // 3550 // EXAMPLES: 3551 // QRestoreRegisterState:1;thread:1E34; (when thread suffix is 3552 // supported) 3553 // QRestoreRegisterState:1 (when thread suffix is NOT 3554 // supported) 3555 3556 rnb_err_t RNBRemote::HandlePacket_RestoreRegisterState(const char *p) { 3557 nub_process_t pid = m_ctx.ProcessID(); 3558 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 3559 if (tid == INVALID_NUB_THREAD) { 3560 if (m_thread_suffix_supported) 3561 return HandlePacket_ILLFORMED( 3562 __FILE__, __LINE__, p, 3563 "No thread specified in QSaveRegisterState packet"); 3564 else 3565 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3566 "No thread was is set with the Hg packet"); 3567 } 3568 3569 StdStringExtractor packet(p); 3570 packet.SetFilePos( 3571 strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:" 3572 const uint32_t save_id = packet.GetU32(0); 3573 3574 if (save_id != 0) { 3575 // Get the register context size first by calling with NULL buffer 3576 if (DNBThreadRestoreRegisterState(pid, tid, save_id)) 3577 return SendPacket("OK"); 3578 else 3579 return SendPacket("E77"); 3580 } 3581 return SendPacket("E76"); 3582 } 3583 3584 static bool GetProcessNameFrom_vAttach(const char *&p, 3585 std::string &attach_name) { 3586 bool return_val = true; 3587 while (*p != '\0') { 3588 char smallbuf[3]; 3589 smallbuf[0] = *p; 3590 smallbuf[1] = *(p + 1); 3591 smallbuf[2] = '\0'; 3592 3593 errno = 0; 3594 int ch = static_cast<int>(strtoul(smallbuf, NULL, 16)); 3595 if (errno != 0 && ch == 0) { 3596 return_val = false; 3597 break; 3598 } 3599 3600 attach_name.push_back(ch); 3601 p += 2; 3602 } 3603 return return_val; 3604 } 3605 3606 rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) { 3607 uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet 3608 // size--debugger can always use less 3609 char buf[256]; 3610 snprintf(buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", 3611 max_packet_size); 3612 3613 bool enable_compression = false; 3614 (void)enable_compression; 3615 3616 #if (defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1) \ 3617 || (defined (TARGET_OS_IOS) && TARGET_OS_IOS == 1) \ 3618 || (defined (TARGET_OS_TV) && TARGET_OS_TV == 1) \ 3619 || (defined (TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1) 3620 enable_compression = true; 3621 #endif 3622 3623 if (enable_compression) { 3624 strcat(buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;" 3625 "DefaultCompressionMinSize="); 3626 char numbuf[16]; 3627 snprintf(numbuf, sizeof(numbuf), "%zu", m_compression_minsize); 3628 numbuf[sizeof(numbuf) - 1] = '\0'; 3629 strcat(buf, numbuf); 3630 } 3631 3632 return SendPacket(buf); 3633 } 3634 3635 /* 3636 vAttach;pid 3637 3638 Attach to a new process with the specified process ID. pid is a hexadecimal 3639 integer 3640 identifying the process. If the stub is currently controlling a process, it is 3641 killed. The attached process is stopped.This packet is only available in 3642 extended 3643 mode (see extended mode). 3644 3645 Reply: 3646 "ENN" for an error 3647 "Any Stop Reply Packet" for success 3648 */ 3649 3650 rnb_err_t RNBRemote::HandlePacket_v(const char *p) { 3651 if (strcmp(p, "vCont;c") == 0) { 3652 // Simple continue 3653 return RNBRemote::HandlePacket_c("c"); 3654 } else if (strcmp(p, "vCont;s") == 0) { 3655 // Simple step 3656 return RNBRemote::HandlePacket_s("s"); 3657 } else if (strstr(p, "vCont") == p) { 3658 DNBThreadResumeActions thread_actions; 3659 char *c = const_cast<char *>(p += strlen("vCont")); 3660 char *c_end = c + strlen(c); 3661 if (*c == '?') 3662 return SendPacket("vCont;c;C;s;S"); 3663 3664 while (c < c_end && *c == ';') { 3665 ++c; // Skip the semi-colon 3666 DNBThreadResumeAction thread_action; 3667 thread_action.tid = INVALID_NUB_THREAD; 3668 thread_action.state = eStateInvalid; 3669 thread_action.signal = 0; 3670 thread_action.addr = INVALID_NUB_ADDRESS; 3671 3672 char action = *c++; 3673 3674 switch (action) { 3675 case 'C': 3676 errno = 0; 3677 thread_action.signal = static_cast<int>(strtoul(c, &c, 16)); 3678 if (errno != 0) 3679 return HandlePacket_ILLFORMED( 3680 __FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3681 // Fall through to next case... 3682 [[clang::fallthrough]]; 3683 case 'c': 3684 // Continue 3685 thread_action.state = eStateRunning; 3686 break; 3687 3688 case 'S': 3689 errno = 0; 3690 thread_action.signal = static_cast<int>(strtoul(c, &c, 16)); 3691 if (errno != 0) 3692 return HandlePacket_ILLFORMED( 3693 __FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3694 // Fall through to next case... 3695 [[clang::fallthrough]]; 3696 case 's': 3697 // Step 3698 thread_action.state = eStateStepping; 3699 break; 3700 3701 default: 3702 HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3703 "Unsupported action in vCont packet"); 3704 break; 3705 } 3706 if (*c == ':') { 3707 errno = 0; 3708 thread_action.tid = strtoul(++c, &c, 16); 3709 if (errno != 0) 3710 return HandlePacket_ILLFORMED( 3711 __FILE__, __LINE__, p, 3712 "Could not parse thread number in vCont packet"); 3713 } 3714 3715 thread_actions.Append(thread_action); 3716 } 3717 3718 // If a default action for all other threads wasn't mentioned 3719 // then we should stop the threads 3720 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3721 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst(), 3722 thread_actions.GetSize()); 3723 return rnb_success; 3724 } else if (strstr(p, "vAttach") == p) { 3725 nub_process_t attach_pid = 3726 INVALID_NUB_PROCESS; // attach_pid will be set to 0 if the attach fails 3727 nub_process_t pid_attaching_to = 3728 INVALID_NUB_PROCESS; // pid_attaching_to is the original pid specified 3729 char err_str[1024] = {'\0'}; 3730 std::string attach_name; 3731 3732 if (strstr(p, "vAttachWait;") == p) { 3733 p += strlen("vAttachWait;"); 3734 if (!GetProcessNameFrom_vAttach(p, attach_name)) { 3735 return HandlePacket_ILLFORMED( 3736 __FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 3737 } 3738 const bool ignore_existing = true; 3739 attach_pid = DNBProcessAttachWait( 3740 attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL, 3741 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3742 3743 } else if (strstr(p, "vAttachOrWait;") == p) { 3744 p += strlen("vAttachOrWait;"); 3745 if (!GetProcessNameFrom_vAttach(p, attach_name)) { 3746 return HandlePacket_ILLFORMED( 3747 __FILE__, __LINE__, p, 3748 "non-hex char in arg on 'vAttachOrWait' pkt"); 3749 } 3750 const bool ignore_existing = false; 3751 attach_pid = DNBProcessAttachWait( 3752 attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL, 3753 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3754 } else if (strstr(p, "vAttachName;") == p) { 3755 p += strlen("vAttachName;"); 3756 if (!GetProcessNameFrom_vAttach(p, attach_name)) { 3757 return HandlePacket_ILLFORMED( 3758 __FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 3759 } 3760 3761 attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL, err_str, 3762 sizeof(err_str)); 3763 3764 } else if (strstr(p, "vAttach;") == p) { 3765 p += strlen("vAttach;"); 3766 char *end = NULL; 3767 pid_attaching_to = static_cast<int>( 3768 strtoul(p, &end, 16)); // PID will be in hex, so use base 16 to decode 3769 if (p != end && *end == '\0') { 3770 // Wait at most 30 second for attach 3771 struct timespec attach_timeout_abstime; 3772 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 3773 attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime, 3774 err_str, sizeof(err_str)); 3775 } 3776 } else { 3777 return HandlePacket_UNIMPLEMENTED(p); 3778 } 3779 3780 if (attach_pid != INVALID_NUB_PROCESS) { 3781 if (m_ctx.ProcessID() != attach_pid) 3782 m_ctx.SetProcessID(attach_pid); 3783 // Send a stop reply packet to indicate we successfully attached! 3784 NotifyThatProcessStopped(); 3785 return rnb_success; 3786 } else { 3787 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3788 if (err_str[0]) 3789 m_ctx.LaunchStatus().SetErrorString(err_str); 3790 else 3791 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3792 3793 #if defined(__APPLE__) && \ 3794 (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000) 3795 if (pid_attaching_to == INVALID_NUB_PROCESS && !attach_name.empty()) { 3796 pid_attaching_to = DNBProcessGetPIDByName(attach_name.c_str()); 3797 } 3798 if (pid_attaching_to != INVALID_NUB_PROCESS && 3799 strcmp(err_str, "No such process") != 0) { 3800 // csr_check(CSR_ALLOW_TASK_FOR_PID) will be nonzero if System Integrity 3801 // Protection is in effect. 3802 if (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0) { 3803 bool attach_failed_due_to_sip = false; 3804 3805 if (rootless_allows_task_for_pid(pid_attaching_to) == 0) { 3806 attach_failed_due_to_sip = true; 3807 } 3808 3809 if (!attach_failed_due_to_sip) { 3810 int csops_flags = 0; 3811 int retval = ::csops(pid_attaching_to, CS_OPS_STATUS, &csops_flags, 3812 sizeof(csops_flags)); 3813 if (retval != -1 && (csops_flags & CS_RESTRICT)) { 3814 attach_failed_due_to_sip = true; 3815 } 3816 } 3817 if (attach_failed_due_to_sip) { 3818 SendPacket("E87"); // E87 is the magic value which says that we are 3819 // not allowed to attach 3820 DNBLogError("Attach failed because process does not allow " 3821 "attaching: \"%s\".", 3822 err_str); 3823 return rnb_err; 3824 } 3825 } 3826 } 3827 3828 #endif 3829 3830 SendPacket("E01"); // E01 is our magic error value for attach failed. 3831 DNBLogError("Attach failed: \"%s\".", err_str); 3832 return rnb_err; 3833 } 3834 } 3835 3836 // All other failures come through here 3837 return HandlePacket_UNIMPLEMENTED(p); 3838 } 3839 3840 /* 'T XX' -- status of thread 3841 Check if the specified thread is alive. 3842 The thread number is in hex? */ 3843 3844 rnb_err_t RNBRemote::HandlePacket_T(const char *p) { 3845 p++; 3846 if (p == NULL || *p == '\0') { 3847 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3848 "No thread specified in T packet"); 3849 } 3850 if (!m_ctx.HasValidProcessID()) { 3851 return SendPacket("E15"); 3852 } 3853 errno = 0; 3854 nub_thread_t tid = strtoul(p, NULL, 16); 3855 if (errno != 0 && tid == 0) { 3856 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3857 "Could not parse thread number in T packet"); 3858 } 3859 3860 nub_state_t state = DNBThreadGetState(m_ctx.ProcessID(), tid); 3861 if (state == eStateInvalid || state == eStateExited || 3862 state == eStateCrashed) { 3863 return SendPacket("E16"); 3864 } 3865 3866 return SendPacket("OK"); 3867 } 3868 3869 rnb_err_t RNBRemote::HandlePacket_z(const char *p) { 3870 if (p == NULL || *p == '\0') 3871 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3872 "No thread specified in z packet"); 3873 3874 if (!m_ctx.HasValidProcessID()) 3875 return SendPacket("E15"); 3876 3877 char packet_cmd = *p++; 3878 char break_type = *p++; 3879 3880 if (*p++ != ',') 3881 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3882 "Comma separator missing in z packet"); 3883 3884 char *c = NULL; 3885 nub_process_t pid = m_ctx.ProcessID(); 3886 errno = 0; 3887 nub_addr_t addr = strtoull(p, &c, 16); 3888 if (errno != 0 && addr == 0) 3889 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3890 "Invalid address in z packet"); 3891 p = c; 3892 if (*p++ != ',') 3893 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3894 "Comma separator missing in z packet"); 3895 3896 errno = 0; 3897 auto byte_size = strtoul(p, &c, 16); 3898 if (errno != 0 && byte_size == 0) 3899 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3900 "Invalid length in z packet"); 3901 3902 if (packet_cmd == 'Z') { 3903 // set 3904 switch (break_type) { 3905 case '0': // set software breakpoint 3906 case '1': // set hardware breakpoint 3907 { 3908 // gdb can send multiple Z packets for the same address and 3909 // these calls must be ref counted. 3910 bool hardware = (break_type == '1'); 3911 3912 if (DNBBreakpointSet(pid, addr, byte_size, hardware)) { 3913 // We successfully created a breakpoint, now lets full out 3914 // a ref count structure with the breakID and add it to our 3915 // map. 3916 return SendPacket("OK"); 3917 } else { 3918 // We failed to set the software breakpoint 3919 return SendPacket("E09"); 3920 } 3921 } break; 3922 3923 case '2': // set write watchpoint 3924 case '3': // set read watchpoint 3925 case '4': // set access watchpoint 3926 { 3927 bool hardware = true; 3928 uint32_t watch_flags = 0; 3929 if (break_type == '2') 3930 watch_flags = WATCH_TYPE_WRITE; 3931 else if (break_type == '3') 3932 watch_flags = WATCH_TYPE_READ; 3933 else 3934 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3935 3936 if (DNBWatchpointSet(pid, addr, byte_size, watch_flags, hardware)) { 3937 return SendPacket("OK"); 3938 } else { 3939 // We failed to set the watchpoint 3940 return SendPacket("E09"); 3941 } 3942 } break; 3943 3944 default: 3945 break; 3946 } 3947 } else if (packet_cmd == 'z') { 3948 // remove 3949 switch (break_type) { 3950 case '0': // remove software breakpoint 3951 case '1': // remove hardware breakpoint 3952 if (DNBBreakpointClear(pid, addr)) { 3953 return SendPacket("OK"); 3954 } else { 3955 return SendPacket("E08"); 3956 } 3957 break; 3958 3959 case '2': // remove write watchpoint 3960 case '3': // remove read watchpoint 3961 case '4': // remove access watchpoint 3962 if (DNBWatchpointClear(pid, addr)) { 3963 return SendPacket("OK"); 3964 } else { 3965 return SendPacket("E08"); 3966 } 3967 break; 3968 3969 default: 3970 break; 3971 } 3972 } 3973 return HandlePacket_UNIMPLEMENTED(p); 3974 } 3975 3976 // Extract the thread number from the thread suffix that might be appended to 3977 // thread specific packets. This will only be enabled if 3978 // m_thread_suffix_supported 3979 // is true. 3980 nub_thread_t RNBRemote::ExtractThreadIDFromThreadSuffix(const char *p) { 3981 if (m_thread_suffix_supported) { 3982 nub_thread_t tid = INVALID_NUB_THREAD; 3983 if (p) { 3984 const char *tid_cstr = strstr(p, "thread:"); 3985 if (tid_cstr) { 3986 tid_cstr += strlen("thread:"); 3987 tid = strtoul(tid_cstr, NULL, 16); 3988 } 3989 } 3990 return tid; 3991 } 3992 return GetCurrentThread(); 3993 } 3994 3995 /* 'p XX' 3996 print the contents of register X */ 3997 3998 rnb_err_t RNBRemote::HandlePacket_p(const char *p) { 3999 if (g_num_reg_entries == 0) 4000 InitializeRegisters(); 4001 4002 if (p == NULL || *p == '\0') { 4003 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4004 "No thread specified in p packet"); 4005 } 4006 if (!m_ctx.HasValidProcessID()) { 4007 return SendPacket("E15"); 4008 } 4009 nub_process_t pid = m_ctx.ProcessID(); 4010 errno = 0; 4011 char *tid_cstr = NULL; 4012 uint32_t reg = static_cast<uint32_t>(strtoul(p + 1, &tid_cstr, 16)); 4013 if (errno != 0 && reg == 0) { 4014 return HandlePacket_ILLFORMED( 4015 __FILE__, __LINE__, p, "Could not parse register number in p packet"); 4016 } 4017 4018 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(tid_cstr); 4019 if (tid == INVALID_NUB_THREAD) 4020 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4021 "No thread specified in p packet"); 4022 4023 const register_map_entry_t *reg_entry; 4024 4025 if (reg < g_num_reg_entries) 4026 reg_entry = &g_reg_entries[reg]; 4027 else 4028 reg_entry = NULL; 4029 4030 std::ostringstream ostrm; 4031 if (reg_entry == NULL) { 4032 DNBLogError( 4033 "RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", 4034 p, reg); 4035 ostrm << "00000000"; 4036 } else if (reg_entry->nub_info.reg == (uint32_t)-1) { 4037 if (reg_entry->nub_info.size > 0) { 4038 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 4039 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 4040 } 4041 } else { 4042 register_value_in_hex_fixed_width(ostrm, pid, tid, reg_entry, NULL); 4043 } 4044 return SendPacket(ostrm.str()); 4045 } 4046 4047 /* 'Pnn=rrrrr' 4048 Set register number n to value r. 4049 n and r are hex strings. */ 4050 4051 rnb_err_t RNBRemote::HandlePacket_P(const char *p) { 4052 if (g_num_reg_entries == 0) 4053 InitializeRegisters(); 4054 4055 if (p == NULL || *p == '\0') { 4056 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Empty P packet"); 4057 } 4058 if (!m_ctx.HasValidProcessID()) { 4059 return SendPacket("E28"); 4060 } 4061 4062 nub_process_t pid = m_ctx.ProcessID(); 4063 4064 StdStringExtractor packet(p); 4065 4066 const char cmd_char = packet.GetChar(); 4067 // Register ID is always in big endian 4068 const uint32_t reg = packet.GetHexMaxU32(false, UINT32_MAX); 4069 const char equal_char = packet.GetChar(); 4070 4071 if (cmd_char != 'P') 4072 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4073 "Improperly formed P packet"); 4074 4075 if (reg == UINT32_MAX) 4076 return SendPacket("E29"); 4077 4078 if (equal_char != '=') 4079 return SendPacket("E30"); 4080 4081 const register_map_entry_t *reg_entry; 4082 4083 if (reg >= g_num_reg_entries) 4084 return SendPacket("E47"); 4085 4086 reg_entry = &g_reg_entries[reg]; 4087 4088 if (reg_entry->nub_info.set == (uint32_t)-1 && 4089 reg_entry->nub_info.reg == (uint32_t)-1) { 4090 DNBLogError( 4091 "RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", 4092 p, reg); 4093 return SendPacket("E48"); 4094 } 4095 4096 DNBRegisterValue reg_value; 4097 reg_value.info = reg_entry->nub_info; 4098 packet.GetHexBytes(reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 4099 4100 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 4101 if (tid == INVALID_NUB_THREAD) 4102 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4103 "No thread specified in p packet"); 4104 4105 if (!DNBThreadSetRegisterValueByID(pid, tid, reg_entry->nub_info.set, 4106 reg_entry->nub_info.reg, ®_value)) { 4107 return SendPacket("E32"); 4108 } 4109 return SendPacket("OK"); 4110 } 4111 4112 /* 'c [addr]' 4113 Continue, optionally from a specified address. */ 4114 4115 rnb_err_t RNBRemote::HandlePacket_c(const char *p) { 4116 const nub_process_t pid = m_ctx.ProcessID(); 4117 4118 if (pid == INVALID_NUB_PROCESS) 4119 return SendPacket("E23"); 4120 4121 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, 4122 INVALID_NUB_ADDRESS}; 4123 4124 if (*(p + 1) != '\0') { 4125 action.tid = GetContinueThread(); 4126 errno = 0; 4127 action.addr = strtoull(p + 1, NULL, 16); 4128 if (errno != 0 && action.addr == 0) 4129 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4130 "Could not parse address in c packet"); 4131 } 4132 4133 DNBThreadResumeActions thread_actions; 4134 thread_actions.Append(action); 4135 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 4136 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4137 thread_actions.GetSize())) 4138 return SendPacket("E25"); 4139 // Don't send an "OK" packet; response is the stopped/exited message. 4140 return rnb_success; 4141 } 4142 4143 rnb_err_t RNBRemote::HandlePacket_MemoryRegionInfo(const char *p) { 4144 /* This packet will find memory attributes (e.g. readable, writable, 4145 executable, stack, jitted code) 4146 for the memory region containing a given address and return that 4147 information. 4148 4149 Users of this packet must be prepared for three results: 4150 4151 Region information is returned 4152 Region information is unavailable for this address because the address 4153 is in unmapped memory 4154 Region lookup cannot be performed on this platform or process is not 4155 yet launched 4156 This packet isn't implemented 4157 4158 Examples of use: 4159 qMemoryRegionInfo:3a55140 4160 start:3a50000,size:100000,permissions:rwx 4161 4162 qMemoryRegionInfo:0 4163 error:address in unmapped region 4164 4165 qMemoryRegionInfo:3a551140 (on a different platform) 4166 error:region lookup cannot be performed 4167 4168 qMemoryRegionInfo 4169 OK // this packet is implemented by the remote nub 4170 */ 4171 4172 p += sizeof("qMemoryRegionInfo") - 1; 4173 if (*p == '\0') 4174 return SendPacket("OK"); 4175 if (*p++ != ':') 4176 return SendPacket("E67"); 4177 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 4178 p += 2; 4179 4180 errno = 0; 4181 uint64_t address = strtoul(p, NULL, 16); 4182 if (errno != 0 && address == 0) { 4183 return HandlePacket_ILLFORMED( 4184 __FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 4185 } 4186 4187 DNBRegionInfo region_info = {0, 0, 0}; 4188 DNBProcessMemoryRegionInfo(m_ctx.ProcessID(), address, ®ion_info); 4189 std::ostringstream ostrm; 4190 4191 // start:3a50000,size:100000,permissions:rwx 4192 ostrm << "start:" << std::hex << region_info.addr << ';'; 4193 4194 if (region_info.size > 0) 4195 ostrm << "size:" << std::hex << region_info.size << ';'; 4196 4197 if (region_info.permissions) { 4198 ostrm << "permissions:"; 4199 4200 if (region_info.permissions & eMemoryPermissionsReadable) 4201 ostrm << 'r'; 4202 if (region_info.permissions & eMemoryPermissionsWritable) 4203 ostrm << 'w'; 4204 if (region_info.permissions & eMemoryPermissionsExecutable) 4205 ostrm << 'x'; 4206 ostrm << ';'; 4207 } 4208 return SendPacket(ostrm.str()); 4209 } 4210 4211 // qGetProfileData;scan_type:0xYYYYYYY 4212 rnb_err_t RNBRemote::HandlePacket_GetProfileData(const char *p) { 4213 nub_process_t pid = m_ctx.ProcessID(); 4214 if (pid == INVALID_NUB_PROCESS) 4215 return SendPacket("OK"); 4216 4217 StdStringExtractor packet(p += sizeof("qGetProfileData")); 4218 DNBProfileDataScanType scan_type = eProfileAll; 4219 std::string name; 4220 std::string value; 4221 while (packet.GetNameColonValue(name, value)) { 4222 if (name == "scan_type") { 4223 std::istringstream iss(value); 4224 uint32_t int_value = 0; 4225 if (iss >> std::hex >> int_value) { 4226 scan_type = (DNBProfileDataScanType)int_value; 4227 } 4228 } 4229 } 4230 4231 std::string data = DNBProcessGetProfileData(pid, scan_type); 4232 if (!data.empty()) { 4233 return SendPacket(data.c_str()); 4234 } else { 4235 return SendPacket("OK"); 4236 } 4237 } 4238 4239 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 4240 rnb_err_t RNBRemote::HandlePacket_SetEnableAsyncProfiling(const char *p) { 4241 nub_process_t pid = m_ctx.ProcessID(); 4242 if (pid == INVALID_NUB_PROCESS) 4243 return SendPacket("OK"); 4244 4245 StdStringExtractor packet(p += sizeof("QSetEnableAsyncProfiling")); 4246 bool enable = false; 4247 uint64_t interval_usec = 0; 4248 DNBProfileDataScanType scan_type = eProfileAll; 4249 std::string name; 4250 std::string value; 4251 while (packet.GetNameColonValue(name, value)) { 4252 if (name == "enable") { 4253 enable = strtoul(value.c_str(), NULL, 10) > 0; 4254 } else if (name == "interval_usec") { 4255 interval_usec = strtoul(value.c_str(), NULL, 10); 4256 } else if (name == "scan_type") { 4257 std::istringstream iss(value); 4258 uint32_t int_value = 0; 4259 if (iss >> std::hex >> int_value) { 4260 scan_type = (DNBProfileDataScanType)int_value; 4261 } 4262 } 4263 } 4264 4265 if (interval_usec == 0) { 4266 enable = false; 4267 } 4268 4269 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 4270 return SendPacket("OK"); 4271 } 4272 4273 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO 4274 // COMPRESS>; 4275 // 4276 // type: must be a type previously reported by the qXfer:features: 4277 // SupportedCompressions list 4278 // 4279 // minsize: is optional; by default the qXfer:features: 4280 // DefaultCompressionMinSize value is used 4281 // debugserver may have a better idea of what a good minimum packet size to 4282 // compress is than lldb. 4283 4284 rnb_err_t RNBRemote::HandlePacket_QEnableCompression(const char *p) { 4285 p += sizeof("QEnableCompression:") - 1; 4286 4287 size_t new_compression_minsize = m_compression_minsize; 4288 const char *new_compression_minsize_str = strstr(p, "minsize:"); 4289 if (new_compression_minsize_str) { 4290 new_compression_minsize_str += strlen("minsize:"); 4291 errno = 0; 4292 new_compression_minsize = strtoul(new_compression_minsize_str, NULL, 10); 4293 if (errno != 0 || new_compression_minsize == ULONG_MAX) { 4294 new_compression_minsize = m_compression_minsize; 4295 } 4296 } 4297 4298 if (strstr(p, "type:zlib-deflate;") != nullptr) { 4299 EnableCompressionNextSendPacket(compression_types::zlib_deflate); 4300 m_compression_minsize = new_compression_minsize; 4301 return SendPacket("OK"); 4302 } else if (strstr(p, "type:lz4;") != nullptr) { 4303 EnableCompressionNextSendPacket(compression_types::lz4); 4304 m_compression_minsize = new_compression_minsize; 4305 return SendPacket("OK"); 4306 } else if (strstr(p, "type:lzma;") != nullptr) { 4307 EnableCompressionNextSendPacket(compression_types::lzma); 4308 m_compression_minsize = new_compression_minsize; 4309 return SendPacket("OK"); 4310 } else if (strstr(p, "type:lzfse;") != nullptr) { 4311 EnableCompressionNextSendPacket(compression_types::lzfse); 4312 m_compression_minsize = new_compression_minsize; 4313 return SendPacket("OK"); 4314 } 4315 4316 return SendPacket("E88"); 4317 } 4318 4319 rnb_err_t RNBRemote::HandlePacket_qSpeedTest(const char *p) { 4320 p += strlen("qSpeedTest:response_size:"); 4321 char *end = NULL; 4322 errno = 0; 4323 uint64_t response_size = ::strtoul(p, &end, 16); 4324 if (errno != 0) 4325 return HandlePacket_ILLFORMED( 4326 __FILE__, __LINE__, p, 4327 "Didn't find response_size value at right offset"); 4328 else if (*end == ';') { 4329 static char g_data[4 * 1024 * 1024 + 16] = "data:"; 4330 memset(g_data + 5, 'a', response_size); 4331 g_data[response_size + 5] = '\0'; 4332 return SendPacket(g_data); 4333 } else { 4334 return SendPacket("E79"); 4335 } 4336 } 4337 4338 rnb_err_t RNBRemote::HandlePacket_WatchpointSupportInfo(const char *p) { 4339 /* This packet simply returns the number of supported hardware watchpoints. 4340 4341 Examples of use: 4342 qWatchpointSupportInfo: 4343 num:4 4344 4345 qWatchpointSupportInfo 4346 OK // this packet is implemented by the remote nub 4347 */ 4348 4349 p += sizeof("qWatchpointSupportInfo") - 1; 4350 if (*p == '\0') 4351 return SendPacket("OK"); 4352 if (*p++ != ':') 4353 return SendPacket("E67"); 4354 4355 errno = 0; 4356 uint32_t num = DNBWatchpointGetNumSupportedHWP(m_ctx.ProcessID()); 4357 std::ostringstream ostrm; 4358 4359 // size:4 4360 ostrm << "num:" << std::dec << num << ';'; 4361 return SendPacket(ostrm.str()); 4362 } 4363 4364 /* 'C sig [;addr]' 4365 Resume with signal sig, optionally at address addr. */ 4366 4367 rnb_err_t RNBRemote::HandlePacket_C(const char *p) { 4368 const nub_process_t pid = m_ctx.ProcessID(); 4369 4370 if (pid == INVALID_NUB_PROCESS) 4371 return SendPacket("E36"); 4372 4373 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, 4374 INVALID_NUB_ADDRESS}; 4375 int process_signo = -1; 4376 if (*(p + 1) != '\0') { 4377 action.tid = GetContinueThread(); 4378 char *end = NULL; 4379 errno = 0; 4380 process_signo = static_cast<int>(strtoul(p + 1, &end, 16)); 4381 if (errno != 0) 4382 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4383 "Could not parse signal in C packet"); 4384 else if (*end == ';') { 4385 errno = 0; 4386 action.addr = strtoull(end + 1, NULL, 16); 4387 if (errno != 0 && action.addr == 0) 4388 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4389 "Could not parse address in C packet"); 4390 } 4391 } 4392 4393 DNBThreadResumeActions thread_actions; 4394 thread_actions.Append(action); 4395 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, action.signal); 4396 if (!DNBProcessSignal(pid, process_signo)) 4397 return SendPacket("E52"); 4398 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4399 thread_actions.GetSize())) 4400 return SendPacket("E38"); 4401 /* Don't send an "OK" packet; response is the stopped/exited message. */ 4402 return rnb_success; 4403 } 4404 4405 // 'D' packet 4406 // Detach from gdb. 4407 rnb_err_t RNBRemote::HandlePacket_D(const char *p) { 4408 if (m_ctx.HasValidProcessID()) { 4409 if (DNBProcessDetach(m_ctx.ProcessID())) 4410 SendPacket("OK"); 4411 else 4412 SendPacket("E"); 4413 } else { 4414 SendPacket("E"); 4415 } 4416 return rnb_success; 4417 } 4418 4419 /* 'k' 4420 Kill the inferior process. */ 4421 4422 rnb_err_t RNBRemote::HandlePacket_k(const char *p) { 4423 DNBLog("Got a 'k' packet, killing the inferior process."); 4424 // No response to should be sent to the kill packet 4425 if (m_ctx.HasValidProcessID()) 4426 DNBProcessKill(m_ctx.ProcessID()); 4427 SendPacket("X09"); 4428 return rnb_success; 4429 } 4430 4431 rnb_err_t RNBRemote::HandlePacket_stop_process(const char *p) { 4432 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test 4433 //exiting on interrupt 4434 #if defined(TEST_EXIT_ON_INTERRUPT) 4435 rnb_err_t err = HandlePacket_k(p); 4436 m_comm.Disconnect(true); 4437 return err; 4438 #else 4439 if (!DNBProcessInterrupt(m_ctx.ProcessID())) { 4440 // If we failed to interrupt the process, then send a stop 4441 // reply packet as the process was probably already stopped 4442 DNBLogThreaded("RNBRemote::HandlePacket_stop_process() sending extra stop " 4443 "reply because DNBProcessInterrupt returned false"); 4444 HandlePacket_last_signal(NULL); 4445 } 4446 return rnb_success; 4447 #endif 4448 } 4449 4450 /* 's' 4451 Step the inferior process. */ 4452 4453 rnb_err_t RNBRemote::HandlePacket_s(const char *p) { 4454 const nub_process_t pid = m_ctx.ProcessID(); 4455 if (pid == INVALID_NUB_PROCESS) 4456 return SendPacket("E32"); 4457 4458 // Hardware supported stepping not supported on arm 4459 nub_thread_t tid = GetContinueThread(); 4460 if (tid == 0 || tid == (nub_thread_t)-1) 4461 tid = GetCurrentThread(); 4462 4463 if (tid == INVALID_NUB_THREAD) 4464 return SendPacket("E33"); 4465 4466 DNBThreadResumeActions thread_actions; 4467 thread_actions.AppendAction(tid, eStateStepping); 4468 4469 // Make all other threads stop when we are stepping 4470 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4471 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4472 thread_actions.GetSize())) 4473 return SendPacket("E49"); 4474 // Don't send an "OK" packet; response is the stopped/exited message. 4475 return rnb_success; 4476 } 4477 4478 /* 'S sig [;addr]' 4479 Step with signal sig, optionally at address addr. */ 4480 4481 rnb_err_t RNBRemote::HandlePacket_S(const char *p) { 4482 const nub_process_t pid = m_ctx.ProcessID(); 4483 if (pid == INVALID_NUB_PROCESS) 4484 return SendPacket("E36"); 4485 4486 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateStepping, 0, 4487 INVALID_NUB_ADDRESS}; 4488 4489 if (*(p + 1) != '\0') { 4490 char *end = NULL; 4491 errno = 0; 4492 action.signal = static_cast<int>(strtoul(p + 1, &end, 16)); 4493 if (errno != 0) 4494 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4495 "Could not parse signal in S packet"); 4496 else if (*end == ';') { 4497 errno = 0; 4498 action.addr = strtoull(end + 1, NULL, 16); 4499 if (errno != 0 && action.addr == 0) { 4500 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4501 "Could not parse address in S packet"); 4502 } 4503 } 4504 } 4505 4506 action.tid = GetContinueThread(); 4507 if (action.tid == 0 || action.tid == (nub_thread_t)-1) 4508 return SendPacket("E40"); 4509 4510 nub_state_t tstate = DNBThreadGetState(pid, action.tid); 4511 if (tstate == eStateInvalid || tstate == eStateExited) 4512 return SendPacket("E37"); 4513 4514 DNBThreadResumeActions thread_actions; 4515 thread_actions.Append(action); 4516 4517 // Make all other threads stop when we are stepping 4518 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4519 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4520 thread_actions.GetSize())) 4521 return SendPacket("E39"); 4522 4523 // Don't send an "OK" packet; response is the stopped/exited message. 4524 return rnb_success; 4525 } 4526 4527 static const char *GetArchName(const uint32_t cputype, 4528 const uint32_t cpusubtype) { 4529 switch (cputype) { 4530 case CPU_TYPE_ARM: 4531 switch (cpusubtype) { 4532 case 5: 4533 return "armv4"; 4534 case 6: 4535 return "armv6"; 4536 case 7: 4537 return "armv5t"; 4538 case 8: 4539 return "xscale"; 4540 case 9: 4541 return "armv7"; 4542 case 10: 4543 return "armv7f"; 4544 case 11: 4545 return "armv7s"; 4546 case 12: 4547 return "armv7k"; 4548 case 14: 4549 return "armv6m"; 4550 case 15: 4551 return "armv7m"; 4552 case 16: 4553 return "armv7em"; 4554 default: 4555 return "arm"; 4556 } 4557 break; 4558 case CPU_TYPE_ARM64: 4559 return "arm64"; 4560 case CPU_TYPE_I386: 4561 return "i386"; 4562 case CPU_TYPE_X86_64: 4563 switch (cpusubtype) { 4564 default: 4565 return "x86_64"; 4566 case 8: 4567 return "x86_64h"; 4568 } 4569 break; 4570 } 4571 return NULL; 4572 } 4573 4574 static bool GetHostCPUType(uint32_t &cputype, uint32_t &cpusubtype, 4575 uint32_t &is_64_bit_capable, bool &promoted_to_64) { 4576 static uint32_t g_host_cputype = 0; 4577 static uint32_t g_host_cpusubtype = 0; 4578 static uint32_t g_is_64_bit_capable = 0; 4579 static bool g_promoted_to_64 = false; 4580 4581 if (g_host_cputype == 0) { 4582 g_promoted_to_64 = false; 4583 size_t len = sizeof(uint32_t); 4584 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) { 4585 len = sizeof(uint32_t); 4586 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, 4587 NULL, 0) == 0) { 4588 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) { 4589 g_promoted_to_64 = true; 4590 g_host_cputype |= CPU_ARCH_ABI64; 4591 } 4592 } 4593 } 4594 4595 len = sizeof(uint32_t); 4596 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 4597 0) { 4598 if (g_promoted_to_64 && g_host_cputype == CPU_TYPE_X86_64 && 4599 g_host_cpusubtype == CPU_SUBTYPE_486) 4600 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4601 } 4602 } 4603 4604 cputype = g_host_cputype; 4605 cpusubtype = g_host_cpusubtype; 4606 is_64_bit_capable = g_is_64_bit_capable; 4607 promoted_to_64 = g_promoted_to_64; 4608 return g_host_cputype != 0; 4609 } 4610 4611 rnb_err_t RNBRemote::HandlePacket_qHostInfo(const char *p) { 4612 std::ostringstream strm; 4613 4614 uint32_t cputype = 0; 4615 uint32_t cpusubtype = 0; 4616 uint32_t is_64_bit_capable = 0; 4617 bool promoted_to_64 = false; 4618 if (GetHostCPUType(cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) { 4619 strm << "cputype:" << std::dec << cputype << ';'; 4620 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4621 } 4622 4623 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4624 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4625 // this for now. 4626 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) { 4627 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 4628 strm << "ostype:tvos;"; 4629 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4630 strm << "ostype:watchos;"; 4631 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 4632 strm << "ostype:bridgeos;"; 4633 #else 4634 strm << "ostype:ios;"; 4635 #endif 4636 4637 // On armv7 we use "synchronous" watchpoints which means the exception is 4638 // delivered before the instruction executes. 4639 strm << "watchpoint_exceptions_received:before;"; 4640 } else { 4641 strm << "ostype:macosx;"; 4642 strm << "watchpoint_exceptions_received:after;"; 4643 } 4644 // char ostype[64]; 4645 // len = sizeof(ostype); 4646 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4647 // { 4648 // len = strlen(ostype); 4649 // std::transform (ostype, ostype + len, ostype, tolower); 4650 // strm << "ostype:" << std::dec << ostype << ';'; 4651 // } 4652 4653 strm << "vendor:apple;"; 4654 4655 uint64_t major, minor, patch; 4656 if (DNBGetOSVersionNumbers(&major, &minor, &patch)) { 4657 strm << "os_version:" << major << "." << minor; 4658 if (patch != UINT64_MAX) 4659 strm << "." << patch; 4660 strm << ";"; 4661 } 4662 4663 #if defined(__LITTLE_ENDIAN__) 4664 strm << "endian:little;"; 4665 #elif defined(__BIG_ENDIAN__) 4666 strm << "endian:big;"; 4667 #elif defined(__PDP_ENDIAN__) 4668 strm << "endian:pdp;"; 4669 #endif 4670 4671 if (promoted_to_64) 4672 strm << "ptrsize:8;"; 4673 else 4674 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4675 4676 #if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4677 strm << "default_packet_timeout:10;"; 4678 #endif 4679 4680 return SendPacket(strm.str()); 4681 } 4682 4683 void XMLElementStart(std::ostringstream &s, uint32_t indent, const char *name, 4684 bool has_attributes) { 4685 if (indent) 4686 s << INDENT_WITH_SPACES(indent); 4687 s << '<' << name; 4688 if (!has_attributes) 4689 s << '>' << std::endl; 4690 } 4691 4692 void XMLElementStartEndAttributes(std::ostringstream &s, bool empty) { 4693 if (empty) 4694 s << '/'; 4695 s << '>' << std::endl; 4696 } 4697 4698 void XMLElementEnd(std::ostringstream &s, uint32_t indent, const char *name) { 4699 if (indent) 4700 s << INDENT_WITH_SPACES(indent); 4701 s << '<' << '/' << name << '>' << std::endl; 4702 } 4703 4704 void XMLElementWithStringValue(std::ostringstream &s, uint32_t indent, 4705 const char *name, const char *value, 4706 bool close = true) { 4707 if (value) { 4708 if (indent) 4709 s << INDENT_WITH_SPACES(indent); 4710 s << '<' << name << '>' << value; 4711 if (close) 4712 XMLElementEnd(s, 0, name); 4713 } 4714 } 4715 4716 void XMLElementWithUnsignedValue(std::ostringstream &s, uint32_t indent, 4717 const char *name, uint64_t value, 4718 bool close = true) { 4719 if (indent) 4720 s << INDENT_WITH_SPACES(indent); 4721 4722 s << '<' << name << '>' << DECIMAL << value; 4723 if (close) 4724 XMLElementEnd(s, 0, name); 4725 } 4726 4727 void XMLAttributeString(std::ostringstream &s, const char *name, 4728 const char *value, const char *default_value = NULL) { 4729 if (value) { 4730 if (default_value && strcmp(value, default_value) == 0) 4731 return; // No need to emit the attribute because it matches the default 4732 // value 4733 s << ' ' << name << "=\"" << value << "\""; 4734 } 4735 } 4736 4737 void XMLAttributeUnsignedDecimal(std::ostringstream &s, const char *name, 4738 uint64_t value) { 4739 s << ' ' << name << "=\"" << DECIMAL << value << "\""; 4740 } 4741 4742 void GenerateTargetXMLRegister(std::ostringstream &s, const uint32_t reg_num, 4743 nub_size_t num_reg_sets, 4744 const DNBRegisterSetInfo *reg_set_info, 4745 const register_map_entry_t ®) { 4746 const char *default_lldb_encoding = "uint"; 4747 const char *lldb_encoding = default_lldb_encoding; 4748 const char *gdb_group = "general"; 4749 const char *default_gdb_type = "int"; 4750 const char *gdb_type = default_gdb_type; 4751 const char *default_lldb_format = "hex"; 4752 const char *lldb_format = default_lldb_format; 4753 const char *lldb_set = NULL; 4754 4755 switch (reg.nub_info.type) { 4756 case Uint: 4757 lldb_encoding = "uint"; 4758 break; 4759 case Sint: 4760 lldb_encoding = "sint"; 4761 break; 4762 case IEEE754: 4763 lldb_encoding = "ieee754"; 4764 if (reg.nub_info.set > 0) 4765 gdb_group = "float"; 4766 break; 4767 case Vector: 4768 lldb_encoding = "vector"; 4769 if (reg.nub_info.set > 0) 4770 gdb_group = "vector"; 4771 break; 4772 } 4773 4774 switch (reg.nub_info.format) { 4775 case Binary: 4776 lldb_format = "binary"; 4777 break; 4778 case Decimal: 4779 lldb_format = "decimal"; 4780 break; 4781 case Hex: 4782 lldb_format = "hex"; 4783 break; 4784 case Float: 4785 gdb_type = "float"; 4786 lldb_format = "float"; 4787 break; 4788 case VectorOfSInt8: 4789 gdb_type = "float"; 4790 lldb_format = "vector-sint8"; 4791 break; 4792 case VectorOfUInt8: 4793 gdb_type = "float"; 4794 lldb_format = "vector-uint8"; 4795 break; 4796 case VectorOfSInt16: 4797 gdb_type = "float"; 4798 lldb_format = "vector-sint16"; 4799 break; 4800 case VectorOfUInt16: 4801 gdb_type = "float"; 4802 lldb_format = "vector-uint16"; 4803 break; 4804 case VectorOfSInt32: 4805 gdb_type = "float"; 4806 lldb_format = "vector-sint32"; 4807 break; 4808 case VectorOfUInt32: 4809 gdb_type = "float"; 4810 lldb_format = "vector-uint32"; 4811 break; 4812 case VectorOfFloat32: 4813 gdb_type = "float"; 4814 lldb_format = "vector-float32"; 4815 break; 4816 case VectorOfUInt128: 4817 gdb_type = "float"; 4818 lldb_format = "vector-uint128"; 4819 break; 4820 }; 4821 if (reg_set_info && reg.nub_info.set < num_reg_sets) 4822 lldb_set = reg_set_info[reg.nub_info.set].name; 4823 4824 uint32_t indent = 2; 4825 4826 XMLElementStart(s, indent, "reg", true); 4827 XMLAttributeString(s, "name", reg.nub_info.name); 4828 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 4829 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 4830 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 4831 XMLAttributeString(s, "group", gdb_group); 4832 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 4833 XMLAttributeString(s, "altname", reg.nub_info.alt); 4834 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 4835 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 4836 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 4837 if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM) 4838 XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe); 4839 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 4840 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 4841 4842 const char *lldb_generic = NULL; 4843 switch (reg.nub_info.reg_generic) { 4844 case GENERIC_REGNUM_FP: 4845 lldb_generic = "fp"; 4846 break; 4847 case GENERIC_REGNUM_PC: 4848 lldb_generic = "pc"; 4849 break; 4850 case GENERIC_REGNUM_SP: 4851 lldb_generic = "sp"; 4852 break; 4853 case GENERIC_REGNUM_RA: 4854 lldb_generic = "ra"; 4855 break; 4856 case GENERIC_REGNUM_FLAGS: 4857 lldb_generic = "flags"; 4858 break; 4859 case GENERIC_REGNUM_ARG1: 4860 lldb_generic = "arg1"; 4861 break; 4862 case GENERIC_REGNUM_ARG2: 4863 lldb_generic = "arg2"; 4864 break; 4865 case GENERIC_REGNUM_ARG3: 4866 lldb_generic = "arg3"; 4867 break; 4868 case GENERIC_REGNUM_ARG4: 4869 lldb_generic = "arg4"; 4870 break; 4871 case GENERIC_REGNUM_ARG5: 4872 lldb_generic = "arg5"; 4873 break; 4874 case GENERIC_REGNUM_ARG6: 4875 lldb_generic = "arg6"; 4876 break; 4877 case GENERIC_REGNUM_ARG7: 4878 lldb_generic = "arg7"; 4879 break; 4880 case GENERIC_REGNUM_ARG8: 4881 lldb_generic = "arg8"; 4882 break; 4883 default: 4884 break; 4885 } 4886 XMLAttributeString(s, "generic", lldb_generic); 4887 4888 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 4889 if (!empty) { 4890 if (!reg.value_regnums.empty()) { 4891 std::ostringstream regnums; 4892 bool first = true; 4893 regnums << DECIMAL; 4894 for (auto regnum : reg.value_regnums) { 4895 if (!first) 4896 regnums << ','; 4897 regnums << regnum; 4898 first = false; 4899 } 4900 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 4901 } 4902 4903 if (!reg.invalidate_regnums.empty()) { 4904 std::ostringstream regnums; 4905 bool first = true; 4906 regnums << DECIMAL; 4907 for (auto regnum : reg.invalidate_regnums) { 4908 if (!first) 4909 regnums << ','; 4910 regnums << regnum; 4911 first = false; 4912 } 4913 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 4914 } 4915 } 4916 XMLElementStartEndAttributes(s, true); 4917 } 4918 4919 void GenerateTargetXMLRegisters(std::ostringstream &s) { 4920 nub_size_t num_reg_sets = 0; 4921 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo(&num_reg_sets); 4922 4923 uint32_t cputype = DNBGetRegisterCPUType(); 4924 if (cputype) { 4925 XMLElementStart(s, 0, "feature", true); 4926 std::ostringstream name_strm; 4927 name_strm << "com.apple.debugserver." << GetArchName(cputype, 0); 4928 XMLAttributeString(s, "name", name_strm.str().c_str()); 4929 XMLElementStartEndAttributes(s, false); 4930 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 4931 // for (const auto ®: g_dynamic_register_map) 4932 { 4933 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, 4934 g_reg_entries[reg_num]); 4935 } 4936 XMLElementEnd(s, 0, "feature"); 4937 4938 if (num_reg_sets > 0) { 4939 XMLElementStart(s, 0, "groups", false); 4940 for (uint32_t set = 1; set < num_reg_sets; ++set) { 4941 XMLElementStart(s, 2, "group", true); 4942 XMLAttributeUnsignedDecimal(s, "id", set); 4943 XMLAttributeString(s, "name", reg_sets[set].name); 4944 XMLElementStartEndAttributes(s, true); 4945 } 4946 XMLElementEnd(s, 0, "groups"); 4947 } 4948 } 4949 } 4950 4951 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 4952 <target version="1.0">)"; 4953 4954 static const char *g_target_xml_footer = "</target>"; 4955 4956 static std::string g_target_xml; 4957 4958 void UpdateTargetXML() { 4959 std::ostringstream s; 4960 s << g_target_xml_header << std::endl; 4961 4962 // Set the architecture 4963 // 4964 // On raw targets (no OS, vendor info), I've seen replies like 4965 // <architecture>i386:x86-64</architecture> (for x86_64 systems - from vmware) 4966 // <architecture>arm</architecture> (for an unspecified arm device - from a Segger JLink) 4967 // For good interop, I'm not sure what's expected here. e.g. will anyone understand 4968 // <architecture>x86_64</architecture> ? Or is i386:x86_64 the expected phrasing? 4969 // 4970 // s << "<architecture>" << arch "</architecture>" << std::endl; 4971 4972 // Set the OSABI 4973 // s << "<osabi>abi-name</osabi>" 4974 4975 GenerateTargetXMLRegisters(s); 4976 4977 s << g_target_xml_footer << std::endl; 4978 4979 // Save the XML output in case it gets retrieved in chunks 4980 g_target_xml = s.str(); 4981 } 4982 4983 rnb_err_t RNBRemote::HandlePacket_qXfer(const char *command) { 4984 const char *p = command; 4985 p += strlen("qXfer:"); 4986 const char *sep = strchr(p, ':'); 4987 if (sep) { 4988 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 4989 p = sep + 1; 4990 sep = strchr(p, ':'); 4991 if (sep) { 4992 std::string rw(p, sep - p); // "read" or "write" 4993 p = sep + 1; 4994 sep = strchr(p, ':'); 4995 if (sep) { 4996 std::string annex(p, sep - p); // "read" or "write" 4997 4998 p = sep + 1; 4999 sep = strchr(p, ','); 5000 if (sep) { 5001 std::string offset_str(p, sep - p); // read the length as a string 5002 p = sep + 1; 5003 std::string length_str(p); // read the offset as a string 5004 char *end = nullptr; 5005 const uint64_t offset = strtoul(offset_str.c_str(), &end, 5006 16); // convert offset_str to a offset 5007 if (*end == '\0') { 5008 const uint64_t length = strtoul( 5009 length_str.c_str(), &end, 16); // convert length_str to a length 5010 if (*end == '\0') { 5011 if (object == "features" && rw == "read" && 5012 annex == "target.xml") { 5013 std::ostringstream xml_out; 5014 5015 if (offset == 0) { 5016 InitializeRegisters(true); 5017 5018 UpdateTargetXML(); 5019 if (g_target_xml.empty()) 5020 return SendPacket("E83"); 5021 5022 if (length > g_target_xml.size()) { 5023 xml_out << 'l'; // No more data 5024 xml_out << binary_encode_string(g_target_xml); 5025 } else { 5026 xml_out << 'm'; // More data needs to be read with a 5027 // subsequent call 5028 xml_out << binary_encode_string( 5029 std::string(g_target_xml, offset, length)); 5030 } 5031 } else { 5032 // Retrieving target XML in chunks 5033 if (offset < g_target_xml.size()) { 5034 std::string chunk(g_target_xml, offset, length); 5035 if (chunk.size() < length) 5036 xml_out << 'l'; // No more data 5037 else 5038 xml_out << 'm'; // More data needs to be read with a 5039 // subsequent call 5040 xml_out << binary_encode_string(chunk.data()); 5041 } 5042 } 5043 return SendPacket(xml_out.str()); 5044 } 5045 // Well formed, put not supported 5046 return HandlePacket_UNIMPLEMENTED(command); 5047 } 5048 } 5049 } 5050 } else { 5051 SendPacket("E85"); 5052 } 5053 } else { 5054 SendPacket("E86"); 5055 } 5056 } 5057 return SendPacket("E82"); 5058 } 5059 5060 rnb_err_t RNBRemote::HandlePacket_qGDBServerVersion(const char *p) { 5061 std::ostringstream strm; 5062 5063 #if defined(DEBUGSERVER_PROGRAM_NAME) 5064 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 5065 #else 5066 strm << "name:debugserver;"; 5067 #endif 5068 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 5069 5070 return SendPacket(strm.str()); 5071 } 5072 5073 // A helper function that retrieves a single integer value from 5074 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5075 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 5076 // 5077 uint64_t get_integer_value_for_key_name_from_json(const char *key, 5078 const char *json_string) { 5079 uint64_t retval = INVALID_NUB_ADDRESS; 5080 std::string key_with_quotes = "\""; 5081 key_with_quotes += key; 5082 key_with_quotes += "\""; 5083 const char *c = strstr(json_string, key_with_quotes.c_str()); 5084 if (c) { 5085 c += key_with_quotes.size(); 5086 5087 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5088 c++; 5089 5090 if (*c == ':') { 5091 c++; 5092 5093 while (*c != '\0' && 5094 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5095 c++; 5096 5097 errno = 0; 5098 retval = strtoul(c, NULL, 10); 5099 if (errno != 0) { 5100 retval = INVALID_NUB_ADDRESS; 5101 } 5102 } 5103 } 5104 return retval; 5105 } 5106 5107 // A helper function that retrieves a boolean value from 5108 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5109 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}] 5110 5111 // Returns true if it was able to find the key name, and sets the 'value' 5112 // argument to the value found. 5113 5114 bool get_boolean_value_for_key_name_from_json(const char *key, 5115 const char *json_string, 5116 bool &value) { 5117 std::string key_with_quotes = "\""; 5118 key_with_quotes += key; 5119 key_with_quotes += "\""; 5120 const char *c = strstr(json_string, key_with_quotes.c_str()); 5121 if (c) { 5122 c += key_with_quotes.size(); 5123 5124 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5125 c++; 5126 5127 if (*c == ':') { 5128 c++; 5129 5130 while (*c != '\0' && 5131 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5132 c++; 5133 5134 if (strncmp(c, "true", 4) == 0) { 5135 value = true; 5136 return true; 5137 } else if (strncmp(c, "false", 5) == 0) { 5138 value = false; 5139 return true; 5140 } 5141 } 5142 } 5143 return false; 5144 } 5145 5146 // A helper function that reads an array of uint64_t's from 5147 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5148 // jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}] 5149 5150 // Returns true if it was able to find the key name, false if it did not. 5151 // "ints" will have all integers found in the array appended to it. 5152 5153 bool get_array_of_ints_value_for_key_name_from_json( 5154 const char *key, const char *json_string, std::vector<uint64_t> &ints) { 5155 std::string key_with_quotes = "\""; 5156 key_with_quotes += key; 5157 key_with_quotes += "\""; 5158 const char *c = strstr(json_string, key_with_quotes.c_str()); 5159 if (c) { 5160 c += key_with_quotes.size(); 5161 5162 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5163 c++; 5164 5165 if (*c == ':') { 5166 c++; 5167 5168 while (*c != '\0' && 5169 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5170 c++; 5171 5172 if (*c == '[') { 5173 c++; 5174 while (*c != '\0' && 5175 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5176 c++; 5177 while (true) { 5178 if (!isdigit(*c)) { 5179 return true; 5180 } 5181 5182 errno = 0; 5183 char *endptr; 5184 uint64_t value = strtoul(c, &endptr, 10); 5185 if (errno == 0) { 5186 ints.push_back(value); 5187 } else { 5188 break; 5189 } 5190 if (endptr == c || endptr == nullptr || *endptr == '\0') { 5191 break; 5192 } 5193 c = endptr; 5194 5195 while (*c != '\0' && 5196 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5197 c++; 5198 if (*c == ',') 5199 c++; 5200 while (*c != '\0' && 5201 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5202 c++; 5203 if (*c == ']') { 5204 return true; 5205 } 5206 } 5207 } 5208 } 5209 } 5210 return false; 5211 } 5212 5213 JSONGenerator::ObjectSP 5214 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) { 5215 JSONGenerator::ArraySP threads_array_sp; 5216 if (m_ctx.HasValidProcessID()) { 5217 threads_array_sp = std::make_shared<JSONGenerator::Array>(); 5218 5219 nub_process_t pid = m_ctx.ProcessID(); 5220 5221 nub_size_t numthreads = DNBProcessGetNumThreads(pid); 5222 for (nub_size_t i = 0; i < numthreads; ++i) { 5223 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, i); 5224 5225 struct DNBThreadStopInfo tid_stop_info; 5226 5227 const bool stop_info_valid = 5228 DNBThreadGetStopReason(pid, tid, &tid_stop_info); 5229 5230 // If we are doing stop info only, then we only show threads that have a 5231 // valid stop reason 5232 if (threads_with_valid_stop_info_only) { 5233 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5234 continue; 5235 } 5236 5237 JSONGenerator::DictionarySP thread_dict_sp( 5238 new JSONGenerator::Dictionary()); 5239 thread_dict_sp->AddIntegerItem("tid", tid); 5240 5241 std::string reason_value("none"); 5242 5243 if (stop_info_valid) { 5244 switch (tid_stop_info.reason) { 5245 case eStopTypeInvalid: 5246 break; 5247 5248 case eStopTypeSignal: 5249 if (tid_stop_info.details.signal.signo != 0) { 5250 thread_dict_sp->AddIntegerItem("signal", 5251 tid_stop_info.details.signal.signo); 5252 reason_value = "signal"; 5253 } 5254 break; 5255 5256 case eStopTypeException: 5257 if (tid_stop_info.details.exception.type != 0) { 5258 reason_value = "exception"; 5259 thread_dict_sp->AddIntegerItem( 5260 "metype", tid_stop_info.details.exception.type); 5261 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5262 for (nub_size_t i = 0; 5263 i < tid_stop_info.details.exception.data_count; ++i) { 5264 medata_array_sp->AddItem( 5265 JSONGenerator::IntegerSP(new JSONGenerator::Integer( 5266 tid_stop_info.details.exception.data[i]))); 5267 } 5268 thread_dict_sp->AddItem("medata", medata_array_sp); 5269 } 5270 break; 5271 5272 case eStopTypeExec: 5273 reason_value = "exec"; 5274 break; 5275 } 5276 } 5277 5278 thread_dict_sp->AddStringItem("reason", reason_value); 5279 5280 if (!threads_with_valid_stop_info_only) { 5281 const char *thread_name = DNBThreadGetName(pid, tid); 5282 if (thread_name && thread_name[0]) 5283 thread_dict_sp->AddStringItem("name", thread_name); 5284 5285 thread_identifier_info_data_t thread_ident_info; 5286 if (DNBThreadGetIdentifierInfo(pid, tid, &thread_ident_info)) { 5287 if (thread_ident_info.dispatch_qaddr != 0) { 5288 thread_dict_sp->AddIntegerItem("qaddr", 5289 thread_ident_info.dispatch_qaddr); 5290 5291 const DispatchQueueOffsets *dispatch_queue_offsets = 5292 GetDispatchQueueOffsets(); 5293 if (dispatch_queue_offsets) { 5294 std::string queue_name; 5295 uint64_t queue_width = 0; 5296 uint64_t queue_serialnum = 0; 5297 nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS; 5298 dispatch_queue_offsets->GetThreadQueueInfo( 5299 pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, 5300 queue_name, queue_width, queue_serialnum); 5301 if (dispatch_queue_t == 0 && queue_name.empty() && 5302 queue_serialnum == 0) { 5303 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5304 false); 5305 } else { 5306 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5307 true); 5308 } 5309 if (dispatch_queue_t != INVALID_NUB_ADDRESS && 5310 dispatch_queue_t != 0) 5311 thread_dict_sp->AddIntegerItem("dispatch_queue_t", 5312 dispatch_queue_t); 5313 if (!queue_name.empty()) 5314 thread_dict_sp->AddStringItem("qname", queue_name); 5315 if (queue_width == 1) 5316 thread_dict_sp->AddStringItem("qkind", "serial"); 5317 else if (queue_width > 1) 5318 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5319 if (queue_serialnum > 0) 5320 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum); 5321 } 5322 } 5323 } 5324 5325 DNBRegisterValue reg_value; 5326 5327 if (g_reg_entries != NULL) { 5328 JSONGenerator::DictionarySP registers_dict_sp( 5329 new JSONGenerator::Dictionary()); 5330 5331 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) { 5332 // Expedite all registers in the first register set that aren't 5333 // contained in other registers 5334 if (g_reg_entries[reg].nub_info.set == 1 && 5335 g_reg_entries[reg].nub_info.value_regs == NULL) { 5336 if (!DNBThreadGetRegisterValueByID( 5337 pid, tid, g_reg_entries[reg].nub_info.set, 5338 g_reg_entries[reg].nub_info.reg, ®_value)) 5339 continue; 5340 5341 std::ostringstream reg_num; 5342 reg_num << std::dec << g_reg_entries[reg].debugserver_regnum; 5343 // Encode native byte ordered bytes as hex ascii 5344 registers_dict_sp->AddBytesAsHexASCIIString( 5345 reg_num.str(), reg_value.value.v_uint8, 5346 g_reg_entries[reg].nub_info.size); 5347 } 5348 } 5349 thread_dict_sp->AddItem("registers", registers_dict_sp); 5350 } 5351 5352 // Add expedited stack memory so stack backtracing doesn't need to read 5353 // anything from the 5354 // frame pointer chain. 5355 StackMemoryMap stack_mmap; 5356 ReadStackMemory(pid, tid, stack_mmap); 5357 if (!stack_mmap.empty()) { 5358 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5359 5360 for (const auto &stack_memory : stack_mmap) { 5361 JSONGenerator::DictionarySP stack_memory_sp( 5362 new JSONGenerator::Dictionary()); 5363 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5364 stack_memory_sp->AddBytesAsHexASCIIString( 5365 "bytes", stack_memory.second.bytes, stack_memory.second.length); 5366 memory_array_sp->AddItem(stack_memory_sp); 5367 } 5368 thread_dict_sp->AddItem("memory", memory_array_sp); 5369 } 5370 } 5371 5372 threads_array_sp->AddItem(thread_dict_sp); 5373 } 5374 } 5375 return threads_array_sp; 5376 } 5377 5378 rnb_err_t RNBRemote::HandlePacket_jThreadsInfo(const char *p) { 5379 JSONGenerator::ObjectSP threads_info_sp; 5380 std::ostringstream json; 5381 std::ostringstream reply_strm; 5382 // If we haven't run the process yet, return an error. 5383 if (m_ctx.HasValidProcessID()) { 5384 const bool threads_with_valid_stop_info_only = false; 5385 JSONGenerator::ObjectSP threads_info_sp = 5386 GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5387 5388 if (threads_info_sp) { 5389 std::ostringstream strm; 5390 threads_info_sp->Dump(strm); 5391 std::string binary_packet = binary_encode_string(strm.str()); 5392 if (!binary_packet.empty()) 5393 return SendPacket(binary_packet.c_str()); 5394 } 5395 } 5396 return SendPacket("E85"); 5397 } 5398 5399 rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) { 5400 nub_process_t pid; 5401 std::ostringstream json; 5402 // If we haven't run the process yet, return an error. 5403 if (!m_ctx.HasValidProcessID()) { 5404 return SendPacket("E81"); 5405 } 5406 5407 pid = m_ctx.ProcessID(); 5408 5409 const char thread_extended_info_str[] = {"jThreadExtendedInfo:{"}; 5410 if (strncmp(p, thread_extended_info_str, 5411 sizeof(thread_extended_info_str) - 1) == 0) { 5412 p += strlen(thread_extended_info_str); 5413 5414 uint64_t tid = get_integer_value_for_key_name_from_json("thread", p); 5415 uint64_t plo_pthread_tsd_base_address_offset = 5416 get_integer_value_for_key_name_from_json( 5417 "plo_pthread_tsd_base_address_offset", p); 5418 uint64_t plo_pthread_tsd_base_offset = 5419 get_integer_value_for_key_name_from_json("plo_pthread_tsd_base_offset", 5420 p); 5421 uint64_t plo_pthread_tsd_entry_size = 5422 get_integer_value_for_key_name_from_json("plo_pthread_tsd_entry_size", 5423 p); 5424 uint64_t dti_qos_class_index = 5425 get_integer_value_for_key_name_from_json("dti_qos_class_index", p); 5426 5427 if (tid != INVALID_NUB_ADDRESS) { 5428 nub_addr_t pthread_t_value = DNBGetPThreadT(pid, tid); 5429 5430 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5431 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS && 5432 plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS && 5433 plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) { 5434 tsd_address = DNBGetTSDAddressForThread( 5435 pid, tid, plo_pthread_tsd_base_address_offset, 5436 plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5437 } 5438 5439 bool timed_out = false; 5440 Genealogy::ThreadActivitySP thread_activity_sp; 5441 5442 // If the pthread_t value is invalid, or if we were able to fetch the 5443 // thread's TSD base 5444 // and got an invalid value back, then we have a thread in early startup 5445 // or shutdown and 5446 // it's possible that gathering the genealogy information for this thread 5447 // go badly. 5448 // Ideally fetching this info for a thread in these odd states shouldn't 5449 // matter - but 5450 // we've seen some problems with these new SPI and threads in edge-casey 5451 // states. 5452 5453 double genealogy_fetch_time = 0; 5454 if (pthread_t_value != INVALID_NUB_ADDRESS && 5455 tsd_address != INVALID_NUB_ADDRESS) { 5456 DNBTimer timer(false); 5457 thread_activity_sp = DNBGetGenealogyInfoForThread(pid, tid, timed_out); 5458 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5459 } 5460 5461 std::unordered_set<uint32_t> 5462 process_info_indexes; // an array of the process info #'s seen 5463 5464 json << "{"; 5465 5466 bool need_to_print_comma = false; 5467 5468 if (thread_activity_sp && !timed_out) { 5469 const Genealogy::Activity *activity = 5470 &thread_activity_sp->current_activity; 5471 bool need_vouchers_comma_sep = false; 5472 json << "\"activity_query_timed_out\":false,"; 5473 if (genealogy_fetch_time != 0) { 5474 // If we append the floating point value with << we'll get it in 5475 // scientific 5476 // notation. 5477 char floating_point_ascii_buffer[64]; 5478 floating_point_ascii_buffer[0] = '\0'; 5479 snprintf(floating_point_ascii_buffer, 5480 sizeof(floating_point_ascii_buffer), "%f", 5481 genealogy_fetch_time); 5482 if (strlen(floating_point_ascii_buffer) > 0) { 5483 if (need_to_print_comma) 5484 json << ","; 5485 need_to_print_comma = true; 5486 json << "\"activity_query_duration\":" 5487 << floating_point_ascii_buffer; 5488 } 5489 } 5490 if (activity->activity_id != 0) { 5491 if (need_to_print_comma) 5492 json << ","; 5493 need_to_print_comma = true; 5494 need_vouchers_comma_sep = true; 5495 json << "\"activity\":{"; 5496 json << "\"start\":" << activity->activity_start << ","; 5497 json << "\"id\":" << activity->activity_id << ","; 5498 json << "\"parent_id\":" << activity->parent_id << ","; 5499 json << "\"name\":\"" 5500 << json_string_quote_metachars(activity->activity_name) << "\","; 5501 json << "\"reason\":\"" 5502 << json_string_quote_metachars(activity->reason) << "\""; 5503 json << "}"; 5504 } 5505 if (thread_activity_sp->messages.size() > 0) { 5506 need_to_print_comma = true; 5507 if (need_vouchers_comma_sep) 5508 json << ","; 5509 need_vouchers_comma_sep = true; 5510 json << "\"trace_messages\":["; 5511 bool printed_one_message = false; 5512 for (auto iter = thread_activity_sp->messages.begin(); 5513 iter != thread_activity_sp->messages.end(); ++iter) { 5514 if (printed_one_message) 5515 json << ","; 5516 else 5517 printed_one_message = true; 5518 json << "{"; 5519 json << "\"timestamp\":" << iter->timestamp << ","; 5520 json << "\"activity_id\":" << iter->activity_id << ","; 5521 json << "\"trace_id\":" << iter->trace_id << ","; 5522 json << "\"thread\":" << iter->thread << ","; 5523 json << "\"type\":" << (int)iter->type << ","; 5524 json << "\"process_info_index\":" << iter->process_info_index 5525 << ","; 5526 process_info_indexes.insert(iter->process_info_index); 5527 json << "\"message\":\"" 5528 << json_string_quote_metachars(iter->message) << "\""; 5529 json << "}"; 5530 } 5531 json << "]"; 5532 } 5533 if (thread_activity_sp->breadcrumbs.size() == 1) { 5534 need_to_print_comma = true; 5535 if (need_vouchers_comma_sep) 5536 json << ","; 5537 need_vouchers_comma_sep = true; 5538 json << "\"breadcrumb\":{"; 5539 for (auto iter = thread_activity_sp->breadcrumbs.begin(); 5540 iter != thread_activity_sp->breadcrumbs.end(); ++iter) { 5541 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5542 json << "\"activity_id\":" << iter->activity_id << ","; 5543 json << "\"timestamp\":" << iter->timestamp << ","; 5544 json << "\"name\":\"" << json_string_quote_metachars(iter->name) 5545 << "\""; 5546 } 5547 json << "}"; 5548 } 5549 if (process_info_indexes.size() > 0) { 5550 need_to_print_comma = true; 5551 if (need_vouchers_comma_sep) 5552 json << ","; 5553 need_vouchers_comma_sep = true; 5554 bool printed_one_process_info = false; 5555 for (auto iter = process_info_indexes.begin(); 5556 iter != process_info_indexes.end(); ++iter) { 5557 if (printed_one_process_info) 5558 json << ","; 5559 Genealogy::ProcessExecutableInfoSP image_info_sp; 5560 uint32_t idx = *iter; 5561 image_info_sp = DNBGetGenealogyImageInfo(pid, idx); 5562 if (image_info_sp) { 5563 if (!printed_one_process_info) { 5564 json << "\"process_infos\":["; 5565 printed_one_process_info = true; 5566 } 5567 5568 json << "{"; 5569 char uuid_buf[37]; 5570 uuid_unparse_upper(image_info_sp->image_uuid, uuid_buf); 5571 json << "\"process_info_index\":" << idx << ","; 5572 json << "\"image_path\":\"" 5573 << json_string_quote_metachars(image_info_sp->image_path) 5574 << "\","; 5575 json << "\"image_uuid\":\"" << uuid_buf << "\""; 5576 json << "}"; 5577 } 5578 } 5579 if (printed_one_process_info) 5580 json << "]"; 5581 } 5582 } else { 5583 if (timed_out) { 5584 if (need_to_print_comma) 5585 json << ","; 5586 need_to_print_comma = true; 5587 json << "\"activity_query_timed_out\":true"; 5588 if (genealogy_fetch_time != 0) { 5589 // If we append the floating point value with << we'll get it in 5590 // scientific 5591 // notation. 5592 char floating_point_ascii_buffer[64]; 5593 floating_point_ascii_buffer[0] = '\0'; 5594 snprintf(floating_point_ascii_buffer, 5595 sizeof(floating_point_ascii_buffer), "%f", 5596 genealogy_fetch_time); 5597 if (strlen(floating_point_ascii_buffer) > 0) { 5598 json << ","; 5599 json << "\"activity_query_duration\":" 5600 << floating_point_ascii_buffer; 5601 } 5602 } 5603 } 5604 } 5605 5606 if (tsd_address != INVALID_NUB_ADDRESS) { 5607 if (need_to_print_comma) 5608 json << ","; 5609 need_to_print_comma = true; 5610 json << "\"tsd_address\":" << tsd_address; 5611 5612 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) { 5613 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread( 5614 pid, tid, tsd_address, dti_qos_class_index); 5615 if (requested_qos.IsValid()) { 5616 if (need_to_print_comma) 5617 json << ","; 5618 need_to_print_comma = true; 5619 json << "\"requested_qos\":{"; 5620 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5621 json << "\"constant_name\":\"" 5622 << json_string_quote_metachars(requested_qos.constant_name) 5623 << "\","; 5624 json << "\"printable_name\":\"" 5625 << json_string_quote_metachars(requested_qos.printable_name) 5626 << "\""; 5627 json << "}"; 5628 } 5629 } 5630 } 5631 5632 if (pthread_t_value != INVALID_NUB_ADDRESS) { 5633 if (need_to_print_comma) 5634 json << ","; 5635 need_to_print_comma = true; 5636 json << "\"pthread_t\":" << pthread_t_value; 5637 } 5638 5639 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT(pid, tid); 5640 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) { 5641 if (need_to_print_comma) 5642 json << ","; 5643 need_to_print_comma = true; 5644 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5645 } 5646 5647 json << "}"; 5648 std::string json_quoted = binary_encode_string(json.str()); 5649 return SendPacket(json_quoted); 5650 } 5651 } 5652 return SendPacket("OK"); 5653 } 5654 5655 // This packet may be called in one of three ways: 5656 // 5657 // jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704} 5658 // Look for an array of the old dyld_all_image_infos style of binary infos 5659 // at the image_list_address. 5660 // This an array of {void* load_addr, void* mod_date, void* pathname} 5661 // 5662 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} 5663 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5664 // get a list of all the 5665 // libraries loaded 5666 // 5667 // jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} 5668 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5669 // get the information 5670 // about the libraries loaded at these addresses. 5671 // 5672 rnb_err_t 5673 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) { 5674 nub_process_t pid; 5675 // If we haven't run the process yet, return an error. 5676 if (!m_ctx.HasValidProcessID()) { 5677 return SendPacket("E83"); 5678 } 5679 5680 pid = m_ctx.ProcessID(); 5681 5682 const char get_loaded_dynamic_libraries_infos_str[] = { 5683 "jGetLoadedDynamicLibrariesInfos:{"}; 5684 if (strncmp(p, get_loaded_dynamic_libraries_infos_str, 5685 sizeof(get_loaded_dynamic_libraries_infos_str) - 1) == 0) { 5686 p += strlen(get_loaded_dynamic_libraries_infos_str); 5687 5688 JSONGenerator::ObjectSP json_sp; 5689 5690 std::vector<uint64_t> macho_addresses; 5691 bool fetch_all_solibs = false; 5692 if (get_boolean_value_for_key_name_from_json("fetch_all_solibs", p, 5693 fetch_all_solibs) && 5694 fetch_all_solibs) { 5695 json_sp = DNBGetAllLoadedLibrariesInfos(pid); 5696 } else if (get_array_of_ints_value_for_key_name_from_json( 5697 "solib_addresses", p, macho_addresses)) { 5698 json_sp = DNBGetLibrariesInfoForAddresses(pid, macho_addresses); 5699 } else { 5700 nub_addr_t image_list_address = 5701 get_integer_value_for_key_name_from_json("image_list_address", p); 5702 nub_addr_t image_count = 5703 get_integer_value_for_key_name_from_json("image_count", p); 5704 5705 if (image_list_address != INVALID_NUB_ADDRESS && 5706 image_count != INVALID_NUB_ADDRESS) { 5707 json_sp = DNBGetLoadedDynamicLibrariesInfos(pid, image_list_address, 5708 image_count); 5709 } 5710 } 5711 5712 if (json_sp.get()) { 5713 std::ostringstream json_str; 5714 json_sp->Dump(json_str); 5715 if (json_str.str().size() > 0) { 5716 std::string json_str_quoted = binary_encode_string(json_str.str()); 5717 return SendPacket(json_str_quoted.c_str()); 5718 } else { 5719 SendPacket("E84"); 5720 } 5721 } 5722 } 5723 return SendPacket("OK"); 5724 } 5725 5726 // This packet does not currently take any arguments. So the behavior is 5727 // jGetSharedCacheInfo:{} 5728 // send information about the inferior's shared cache 5729 // jGetSharedCacheInfo: 5730 // send "OK" to indicate that this packet is supported 5731 rnb_err_t RNBRemote::HandlePacket_jGetSharedCacheInfo(const char *p) { 5732 nub_process_t pid; 5733 // If we haven't run the process yet, return an error. 5734 if (!m_ctx.HasValidProcessID()) { 5735 return SendPacket("E85"); 5736 } 5737 5738 pid = m_ctx.ProcessID(); 5739 5740 const char get_shared_cache_info_str[] = {"jGetSharedCacheInfo:{"}; 5741 if (strncmp(p, get_shared_cache_info_str, 5742 sizeof(get_shared_cache_info_str) - 1) == 0) { 5743 JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo(pid); 5744 5745 if (json_sp.get()) { 5746 std::ostringstream json_str; 5747 json_sp->Dump(json_str); 5748 if (json_str.str().size() > 0) { 5749 std::string json_str_quoted = binary_encode_string(json_str.str()); 5750 return SendPacket(json_str_quoted.c_str()); 5751 } else { 5752 SendPacket("E86"); 5753 } 5754 } 5755 } 5756 return SendPacket("OK"); 5757 } 5758 5759 static bool MachHeaderIsMainExecutable(nub_process_t pid, uint32_t addr_size, 5760 nub_addr_t mach_header_addr, 5761 mach_header &mh) { 5762 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, " 5763 "addr_size = %u, mach_header_addr = " 5764 "0x%16.16llx)", 5765 pid, addr_size, mach_header_addr); 5766 const nub_size_t bytes_read = 5767 DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh); 5768 if (bytes_read == sizeof(mh)) { 5769 DNBLogThreadedIf( 5770 LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = " 5771 "%u, mach_header_addr = 0x%16.16llx): mh = {\n magic = " 5772 "0x%8.8x\n cpu = 0x%8.8x\n sub = 0x%8.8x\n filetype = " 5773 "%u\n ncmds = %u\n sizeofcmds = 0x%8.8x\n flags = " 5774 "0x%8.8x }", 5775 pid, addr_size, mach_header_addr, mh.magic, mh.cputype, mh.cpusubtype, 5776 mh.filetype, mh.ncmds, mh.sizeofcmds, mh.flags); 5777 if ((addr_size == 4 && mh.magic == MH_MAGIC) || 5778 (addr_size == 8 && mh.magic == MH_MAGIC_64)) { 5779 if (mh.filetype == MH_EXECUTE) { 5780 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = " 5781 "%u, addr_size = %u, mach_header_addr = " 5782 "0x%16.16llx) -> this is the " 5783 "executable!!!", 5784 pid, addr_size, mach_header_addr); 5785 return true; 5786 } 5787 } 5788 } 5789 return false; 5790 } 5791 5792 static nub_addr_t GetMachHeaderForMainExecutable(const nub_process_t pid, 5793 const uint32_t addr_size, 5794 mach_header &mh) { 5795 struct AllImageInfos { 5796 uint32_t version; 5797 uint32_t dylib_info_count; 5798 uint64_t dylib_info_addr; 5799 }; 5800 5801 uint64_t mach_header_addr = 0; 5802 5803 const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress(pid); 5804 uint8_t bytes[256]; 5805 nub_size_t bytes_read = 0; 5806 DNBDataRef data(bytes, sizeof(bytes), false); 5807 DNBDataRef::offset_t offset = 0; 5808 data.SetPointerSize(addr_size); 5809 5810 // When we are sitting at __dyld_start, the kernel has placed the 5811 // address of the mach header of the main executable on the stack. If we 5812 // read the SP and dereference a pointer, we might find the mach header 5813 // for the executable. We also just make sure there is only 1 thread 5814 // since if we are at __dyld_start we shouldn't have multiple threads. 5815 if (DNBProcessGetNumThreads(pid) == 1) { 5816 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0); 5817 if (tid != INVALID_NUB_THREAD) { 5818 DNBRegisterValue sp_value; 5819 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, 5820 GENERIC_REGNUM_SP, &sp_value)) { 5821 uint64_t sp = 5822 addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32; 5823 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes); 5824 if (bytes_read == addr_size) { 5825 offset = 0; 5826 mach_header_addr = data.GetPointer(&offset); 5827 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5828 return mach_header_addr; 5829 } 5830 } 5831 } 5832 } 5833 5834 // Check the dyld_all_image_info structure for a list of mach header 5835 // since it is a very easy thing to check 5836 if (shlib_addr != INVALID_NUB_ADDRESS) { 5837 bytes_read = 5838 DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes); 5839 if (bytes_read > 0) { 5840 AllImageInfos aii; 5841 offset = 0; 5842 aii.version = data.Get32(&offset); 5843 aii.dylib_info_count = data.Get32(&offset); 5844 if (aii.dylib_info_count > 0) { 5845 aii.dylib_info_addr = data.GetPointer(&offset); 5846 if (aii.dylib_info_addr != 0) { 5847 const size_t image_info_byte_size = 3 * addr_size; 5848 for (uint32_t i = 0; i < aii.dylib_info_count; ++i) { 5849 bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + 5850 i * image_info_byte_size, 5851 image_info_byte_size, bytes); 5852 if (bytes_read != image_info_byte_size) 5853 break; 5854 offset = 0; 5855 mach_header_addr = data.GetPointer(&offset); 5856 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, 5857 mh)) 5858 return mach_header_addr; 5859 } 5860 } 5861 } 5862 } 5863 } 5864 5865 // We failed to find the executable's mach header from the all image 5866 // infos and by dereferencing the stack pointer. Now we fall back to 5867 // enumerating the memory regions and looking for regions that are 5868 // executable. 5869 DNBRegionInfo region_info; 5870 mach_header_addr = 0; 5871 while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, ®ion_info)) { 5872 if (region_info.size == 0) 5873 break; 5874 5875 if (region_info.permissions & eMemoryPermissionsExecutable) { 5876 DNBLogThreadedIf( 5877 LOG_RNB_PROC, "[0x%16.16llx - 0x%16.16llx) permissions = %c%c%c: " 5878 "checking region for executable mach header", 5879 region_info.addr, region_info.addr + region_info.size, 5880 (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', 5881 (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', 5882 (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-'); 5883 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5884 return mach_header_addr; 5885 } else { 5886 DNBLogThreadedIf( 5887 LOG_RNB_PROC, 5888 "[0x%16.16llx - 0x%16.16llx): permissions = %c%c%c: skipping region", 5889 region_info.addr, region_info.addr + region_info.size, 5890 (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', 5891 (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', 5892 (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-'); 5893 } 5894 // Set the address to the next mapped region 5895 mach_header_addr = region_info.addr + region_info.size; 5896 } 5897 bzero(&mh, sizeof(mh)); 5898 return INVALID_NUB_ADDRESS; 5899 } 5900 5901 rnb_err_t RNBRemote::HandlePacket_qSymbol(const char *command) { 5902 const char *p = command; 5903 p += strlen("qSymbol:"); 5904 const char *sep = strchr(p, ':'); 5905 5906 std::string symbol_name; 5907 std::string symbol_value_str; 5908 // Extract the symbol value if there is one 5909 if (sep > p) 5910 symbol_value_str.assign(p, sep - p); 5911 p = sep + 1; 5912 5913 if (*p) { 5914 // We have a symbol name 5915 symbol_name = decode_hex_ascii_string(p); 5916 if (!symbol_value_str.empty()) { 5917 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5918 if (symbol_name == "dispatch_queue_offsets") 5919 m_dispatch_queue_offsets_addr = symbol_value; 5920 } 5921 ++m_qSymbol_index; 5922 } else { 5923 // No symbol name, set our symbol index to zero so we can 5924 // read any symbols that we need 5925 m_qSymbol_index = 0; 5926 } 5927 5928 symbol_name.clear(); 5929 5930 if (m_qSymbol_index == 0) { 5931 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5932 symbol_name = "dispatch_queue_offsets"; 5933 else 5934 ++m_qSymbol_index; 5935 } 5936 5937 // // Lookup next symbol when we have one... 5938 // if (m_qSymbol_index == 1) 5939 // { 5940 // } 5941 5942 if (symbol_name.empty()) { 5943 // Done with symbol lookups 5944 return SendPacket("OK"); 5945 } else { 5946 std::ostringstream reply; 5947 reply << "qSymbol:"; 5948 for (size_t i = 0; i < symbol_name.size(); ++i) 5949 reply << RAWHEX8(symbol_name[i]); 5950 return SendPacket(reply.str().c_str()); 5951 } 5952 } 5953 5954 // Note that all numeric values returned by qProcessInfo are hex encoded, 5955 // including the pid and the cpu type. 5956 5957 rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) { 5958 nub_process_t pid; 5959 std::ostringstream rep; 5960 5961 // If we haven't run the process yet, return an error. 5962 if (!m_ctx.HasValidProcessID()) 5963 return SendPacket("E68"); 5964 5965 pid = m_ctx.ProcessID(); 5966 5967 rep << "pid:" << std::hex << pid << ';'; 5968 5969 int procpid_mib[4]; 5970 procpid_mib[0] = CTL_KERN; 5971 procpid_mib[1] = KERN_PROC; 5972 procpid_mib[2] = KERN_PROC_PID; 5973 procpid_mib[3] = pid; 5974 struct kinfo_proc proc_kinfo; 5975 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 5976 5977 if (::sysctl(procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { 5978 if (proc_kinfo_size > 0) { 5979 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';'; 5980 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid 5981 << ';'; 5982 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid 5983 << ';'; 5984 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid 5985 << ';'; 5986 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 5987 rep << "effective-gid:" << std::hex 5988 << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';'; 5989 } 5990 } 5991 5992 cpu_type_t cputype = DNBProcessGetCPUType(pid); 5993 if (cputype == 0) { 5994 DNBLog("Unable to get the process cpu_type, making a best guess."); 5995 cputype = best_guess_cpu_type(); 5996 } 5997 5998 uint32_t addr_size = 0; 5999 if (cputype != 0) { 6000 rep << "cputype:" << std::hex << cputype << ";"; 6001 if (cputype & CPU_ARCH_ABI64) 6002 addr_size = 8; 6003 else 6004 addr_size = 4; 6005 } 6006 6007 bool host_cpu_is_64bit = false; 6008 uint32_t is64bit_capable; 6009 size_t is64bit_capable_len = sizeof(is64bit_capable); 6010 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, 6011 &is64bit_capable_len, NULL, 0) == 0) 6012 host_cpu_is_64bit = is64bit_capable != 0; 6013 6014 uint32_t cpusubtype; 6015 size_t cpusubtype_len = sizeof(cpusubtype); 6016 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 6017 0) { 6018 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 6019 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 6020 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu 6021 // subtype 6022 // for i386... 6023 if (host_cpu_is_64bit) { 6024 if (cputype == CPU_TYPE_X86) { 6025 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 6026 } else if (cputype == CPU_TYPE_ARM) { 6027 // We can query a process' cputype but we cannot query a process' 6028 // cpusubtype. 6029 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit 6030 // process) and we 6031 // need to override the host cpusubtype (which is in the 6032 // CPU_SUBTYPE_ARM64 subtype namespace) 6033 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 6034 cpusubtype = 12; // CPU_SUBTYPE_ARM_V7K 6035 } 6036 } 6037 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 6038 } 6039 6040 bool os_handled = false; 6041 if (addr_size > 0) { 6042 rep << "ptrsize:" << std::dec << addr_size << ';'; 6043 6044 #if (defined(__x86_64__) || defined(__i386__)) 6045 // Try and get the OS type by looking at the load commands in the main 6046 // executable and looking for a LC_VERSION_MIN load command. This is the 6047 // most reliable way to determine the "ostype" value when on desktop. 6048 6049 mach_header mh; 6050 nub_addr_t exe_mach_header_addr = 6051 GetMachHeaderForMainExecutable(pid, addr_size, mh); 6052 if (exe_mach_header_addr != INVALID_NUB_ADDRESS) { 6053 uint64_t load_command_addr = 6054 exe_mach_header_addr + 6055 ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header)); 6056 load_command lc; 6057 for (uint32_t i = 0; i < mh.ncmds && !os_handled; ++i) { 6058 const nub_size_t bytes_read = 6059 DNBProcessMemoryRead(pid, load_command_addr, sizeof(lc), &lc); 6060 (void)bytes_read; 6061 6062 uint32_t major_version, minor_version, patch_version; 6063 auto *platform = DNBGetDeploymentInfo(pid, lc, load_command_addr, 6064 major_version, minor_version, 6065 patch_version); 6066 if (platform) { 6067 os_handled = true; 6068 rep << "ostype:" << platform << ";"; 6069 break; 6070 } 6071 load_command_addr = load_command_addr + lc.cmdsize; 6072 } 6073 } 6074 #endif // when compiling this on x86 targets 6075 } 6076 6077 // If we weren't able to find the OS in a LC_VERSION_MIN load command, try 6078 // to set it correctly by using the cpu type and other tricks 6079 if (!os_handled) { 6080 // The OS in the triple should be "ios" or "macosx" which doesn't match our 6081 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 6082 // this for now. 6083 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) { 6084 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6085 rep << "ostype:tvos;"; 6086 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6087 rep << "ostype:watchos;"; 6088 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 6089 rep << "ostype:bridgeos;"; 6090 #else 6091 rep << "ostype:ios;"; 6092 #endif 6093 } else { 6094 bool is_ios_simulator = false; 6095 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) { 6096 // Check for iOS simulator binaries by getting the process argument 6097 // and environment and checking for SIMULATOR_UDID in the environment 6098 int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2, (int)pid}; 6099 6100 uint8_t arg_data[8192]; 6101 size_t arg_data_size = sizeof(arg_data); 6102 if (::sysctl(proc_args_mib, 3, arg_data, &arg_data_size, NULL, 0) == 6103 0) { 6104 DNBDataRef data(arg_data, arg_data_size, false); 6105 DNBDataRef::offset_t offset = 0; 6106 uint32_t argc = data.Get32(&offset); 6107 const char *cstr; 6108 6109 cstr = data.GetCStr(&offset); 6110 if (cstr) { 6111 // Skip NULLs 6112 while (true) { 6113 const char *p = data.PeekCStr(offset); 6114 if ((p == NULL) || (*p != '\0')) 6115 break; 6116 ++offset; 6117 } 6118 // Now skip all arguments 6119 for (uint32_t i = 0; i < argc; ++i) { 6120 data.GetCStr(&offset); 6121 } 6122 6123 // Now iterate across all environment variables 6124 while ((cstr = data.GetCStr(&offset))) { 6125 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 6126 0) { 6127 is_ios_simulator = true; 6128 break; 6129 } 6130 if (cstr[0] == '\0') 6131 break; 6132 } 6133 } 6134 } 6135 } 6136 if (is_ios_simulator) { 6137 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6138 rep << "ostype:tvos;"; 6139 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6140 rep << "ostype:watchos;"; 6141 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 6142 rep << "ostype:bridgeos;"; 6143 #else 6144 rep << "ostype:ios;"; 6145 #endif 6146 } else { 6147 rep << "ostype:macosx;"; 6148 } 6149 } 6150 } 6151 6152 rep << "vendor:apple;"; 6153 6154 #if defined(__LITTLE_ENDIAN__) 6155 rep << "endian:little;"; 6156 #elif defined(__BIG_ENDIAN__) 6157 rep << "endian:big;"; 6158 #elif defined(__PDP_ENDIAN__) 6159 rep << "endian:pdp;"; 6160 #endif 6161 6162 if (addr_size == 0) { 6163 #if (defined(__x86_64__) || defined(__i386__)) && defined(x86_THREAD_STATE) 6164 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6165 kern_return_t kr; 6166 x86_thread_state_t gp_regs; 6167 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 6168 kr = thread_get_state(static_cast<thread_act_t>(thread), x86_THREAD_STATE, 6169 (thread_state_t)&gp_regs, &gp_count); 6170 if (kr == KERN_SUCCESS) { 6171 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 6172 rep << "ptrsize:8;"; 6173 else 6174 rep << "ptrsize:4;"; 6175 } 6176 #elif defined(__arm__) 6177 rep << "ptrsize:4;"; 6178 #elif (defined(__arm64__) || defined(__aarch64__)) && \ 6179 defined(ARM_UNIFIED_THREAD_STATE) 6180 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6181 kern_return_t kr; 6182 arm_unified_thread_state_t gp_regs; 6183 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 6184 kr = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE, 6185 (thread_state_t)&gp_regs, &gp_count); 6186 if (kr == KERN_SUCCESS) { 6187 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 6188 rep << "ptrsize:8;"; 6189 else 6190 rep << "ptrsize:4;"; 6191 } 6192 #endif 6193 } 6194 6195 return SendPacket(rep.str()); 6196 } 6197 6198 const RNBRemote::DispatchQueueOffsets *RNBRemote::GetDispatchQueueOffsets() { 6199 if (!m_dispatch_queue_offsets.IsValid() && 6200 m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && 6201 m_ctx.HasValidProcessID()) { 6202 nub_process_t pid = m_ctx.ProcessID(); 6203 nub_size_t bytes_read = DNBProcessMemoryRead( 6204 pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), 6205 &m_dispatch_queue_offsets); 6206 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 6207 m_dispatch_queue_offsets.Clear(); 6208 } 6209 6210 if (m_dispatch_queue_offsets.IsValid()) 6211 return &m_dispatch_queue_offsets; 6212 else 6213 return nullptr; 6214 } 6215 6216 void RNBRemote::EnableCompressionNextSendPacket(compression_types type) { 6217 m_compression_mode = type; 6218 m_enable_compression_next_send_packet = true; 6219 } 6220 6221 compression_types RNBRemote::GetCompressionType() { 6222 // The first packet we send back to the debugger after a QEnableCompression 6223 // request 6224 // should be uncompressed -- so we can indicate whether the compression was 6225 // enabled 6226 // or not via OK / Enn returns. After that, all packets sent will be using 6227 // the 6228 // compression protocol. 6229 6230 if (m_enable_compression_next_send_packet) { 6231 // One time, we send back "None" as our compression type 6232 m_enable_compression_next_send_packet = false; 6233 return compression_types::none; 6234 } 6235 return m_compression_mode; 6236 } 6237