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