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