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