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