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