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