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 error_explainer += " ("; 4080 error_explainer += err_str; 4081 error_explainer += ")"; 4082 } 4083 std::string default_return_msg = "E96;"; 4084 default_return_msg += cstring_to_asciihex_string 4085 (error_explainer.c_str()); 4086 SendPacket (default_return_msg.c_str()); 4087 DNBLogError("Attach failed: \"%s\".", err_str); 4088 return rnb_err; 4089 } 4090 } 4091 4092 // All other failures come through here 4093 return HandlePacket_UNIMPLEMENTED(p); 4094 } 4095 4096 /* 'T XX' -- status of thread 4097 Check if the specified thread is alive. 4098 The thread number is in hex? */ 4099 4100 rnb_err_t RNBRemote::HandlePacket_T(const char *p) { 4101 p++; 4102 if (p == NULL || *p == '\0') { 4103 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4104 "No thread specified in T packet"); 4105 } 4106 if (!m_ctx.HasValidProcessID()) { 4107 return SendPacket("E15"); 4108 } 4109 errno = 0; 4110 nub_thread_t tid = strtoul(p, NULL, 16); 4111 if (errno != 0 && tid == 0) { 4112 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4113 "Could not parse thread number in T packet"); 4114 } 4115 4116 nub_state_t state = DNBThreadGetState(m_ctx.ProcessID(), tid); 4117 if (state == eStateInvalid || state == eStateExited || 4118 state == eStateCrashed) { 4119 return SendPacket("E16"); 4120 } 4121 4122 return SendPacket("OK"); 4123 } 4124 4125 rnb_err_t RNBRemote::HandlePacket_z(const char *p) { 4126 if (p == NULL || *p == '\0') 4127 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4128 "No thread specified in z packet"); 4129 4130 if (!m_ctx.HasValidProcessID()) 4131 return SendPacket("E15"); 4132 4133 char packet_cmd = *p++; 4134 char break_type = *p++; 4135 4136 if (*p++ != ',') 4137 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4138 "Comma separator missing in z packet"); 4139 4140 char *c = NULL; 4141 nub_process_t pid = m_ctx.ProcessID(); 4142 errno = 0; 4143 nub_addr_t addr = strtoull(p, &c, 16); 4144 if (errno != 0 && addr == 0) 4145 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4146 "Invalid address in z packet"); 4147 p = c; 4148 if (*p++ != ',') 4149 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4150 "Comma separator missing in z packet"); 4151 4152 errno = 0; 4153 auto byte_size = strtoul(p, &c, 16); 4154 if (errno != 0 && byte_size == 0) 4155 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4156 "Invalid length in z packet"); 4157 4158 if (packet_cmd == 'Z') { 4159 // set 4160 switch (break_type) { 4161 case '0': // set software breakpoint 4162 case '1': // set hardware breakpoint 4163 { 4164 // gdb can send multiple Z packets for the same address and 4165 // these calls must be ref counted. 4166 bool hardware = (break_type == '1'); 4167 4168 if (DNBBreakpointSet(pid, addr, byte_size, hardware)) { 4169 // We successfully created a breakpoint, now lets full out 4170 // a ref count structure with the breakID and add it to our 4171 // map. 4172 return SendPacket("OK"); 4173 } else { 4174 // We failed to set the software breakpoint 4175 return SendPacket("E09"); 4176 } 4177 } break; 4178 4179 case '2': // set write watchpoint 4180 case '3': // set read watchpoint 4181 case '4': // set access watchpoint 4182 { 4183 bool hardware = true; 4184 uint32_t watch_flags = 0; 4185 if (break_type == '2') 4186 watch_flags = WATCH_TYPE_WRITE; 4187 else if (break_type == '3') 4188 watch_flags = WATCH_TYPE_READ; 4189 else 4190 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 4191 4192 if (DNBWatchpointSet(pid, addr, byte_size, watch_flags, hardware)) { 4193 return SendPacket("OK"); 4194 } else { 4195 // We failed to set the watchpoint 4196 return SendPacket("E09"); 4197 } 4198 } break; 4199 4200 default: 4201 break; 4202 } 4203 } else if (packet_cmd == 'z') { 4204 // remove 4205 switch (break_type) { 4206 case '0': // remove software breakpoint 4207 case '1': // remove hardware breakpoint 4208 if (DNBBreakpointClear(pid, addr)) { 4209 return SendPacket("OK"); 4210 } else { 4211 return SendPacket("E08"); 4212 } 4213 break; 4214 4215 case '2': // remove write watchpoint 4216 case '3': // remove read watchpoint 4217 case '4': // remove access watchpoint 4218 if (DNBWatchpointClear(pid, addr)) { 4219 return SendPacket("OK"); 4220 } else { 4221 return SendPacket("E08"); 4222 } 4223 break; 4224 4225 default: 4226 break; 4227 } 4228 } 4229 return HandlePacket_UNIMPLEMENTED(p); 4230 } 4231 4232 // Extract the thread number from the thread suffix that might be appended to 4233 // thread specific packets. This will only be enabled if 4234 // m_thread_suffix_supported 4235 // is true. 4236 nub_thread_t RNBRemote::ExtractThreadIDFromThreadSuffix(const char *p) { 4237 if (m_thread_suffix_supported) { 4238 nub_thread_t tid = INVALID_NUB_THREAD; 4239 if (p) { 4240 const char *tid_cstr = strstr(p, "thread:"); 4241 if (tid_cstr) { 4242 tid_cstr += strlen("thread:"); 4243 tid = strtoul(tid_cstr, NULL, 16); 4244 } 4245 } 4246 return tid; 4247 } 4248 return GetCurrentThread(); 4249 } 4250 4251 /* 'p XX' 4252 print the contents of register X */ 4253 4254 rnb_err_t RNBRemote::HandlePacket_p(const char *p) { 4255 if (g_num_reg_entries == 0) 4256 InitializeRegisters(); 4257 4258 if (p == NULL || *p == '\0') { 4259 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4260 "No thread specified in p packet"); 4261 } 4262 if (!m_ctx.HasValidProcessID()) { 4263 return SendPacket("E15"); 4264 } 4265 nub_process_t pid = m_ctx.ProcessID(); 4266 errno = 0; 4267 char *tid_cstr = NULL; 4268 uint32_t reg = static_cast<uint32_t>(strtoul(p + 1, &tid_cstr, 16)); 4269 if (errno != 0 && reg == 0) { 4270 return HandlePacket_ILLFORMED( 4271 __FILE__, __LINE__, p, "Could not parse register number in p packet"); 4272 } 4273 4274 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(tid_cstr); 4275 if (tid == INVALID_NUB_THREAD) 4276 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4277 "No thread specified in p packet"); 4278 4279 const register_map_entry_t *reg_entry; 4280 4281 if (reg < g_num_reg_entries) 4282 reg_entry = &g_reg_entries[reg]; 4283 else 4284 reg_entry = NULL; 4285 4286 std::ostringstream ostrm; 4287 if (reg_entry == NULL) { 4288 DNBLogError( 4289 "RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", 4290 p, reg); 4291 ostrm << "00000000"; 4292 } else if (reg_entry->nub_info.reg == (uint32_t)-1) { 4293 if (reg_entry->nub_info.size > 0) { 4294 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 4295 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 4296 } 4297 } else { 4298 register_value_in_hex_fixed_width(ostrm, pid, tid, reg_entry, NULL); 4299 } 4300 return SendPacket(ostrm.str()); 4301 } 4302 4303 /* 'Pnn=rrrrr' 4304 Set register number n to value r. 4305 n and r are hex strings. */ 4306 4307 rnb_err_t RNBRemote::HandlePacket_P(const char *p) { 4308 if (g_num_reg_entries == 0) 4309 InitializeRegisters(); 4310 4311 if (p == NULL || *p == '\0') { 4312 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Empty P packet"); 4313 } 4314 if (!m_ctx.HasValidProcessID()) { 4315 return SendPacket("E28"); 4316 } 4317 4318 nub_process_t pid = m_ctx.ProcessID(); 4319 4320 StdStringExtractor packet(p); 4321 4322 const char cmd_char = packet.GetChar(); 4323 // Register ID is always in big endian 4324 const uint32_t reg = packet.GetHexMaxU32(false, UINT32_MAX); 4325 const char equal_char = packet.GetChar(); 4326 4327 if (cmd_char != 'P') 4328 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4329 "Improperly formed P packet"); 4330 4331 if (reg == UINT32_MAX) 4332 return SendPacket("E29"); 4333 4334 if (equal_char != '=') 4335 return SendPacket("E30"); 4336 4337 const register_map_entry_t *reg_entry; 4338 4339 if (reg >= g_num_reg_entries) 4340 return SendPacket("E47"); 4341 4342 reg_entry = &g_reg_entries[reg]; 4343 4344 if (reg_entry->nub_info.set == (uint32_t)-1 && 4345 reg_entry->nub_info.reg == (uint32_t)-1) { 4346 DNBLogError( 4347 "RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", 4348 p, reg); 4349 return SendPacket("E48"); 4350 } 4351 4352 DNBRegisterValue reg_value; 4353 reg_value.info = reg_entry->nub_info; 4354 packet.GetHexBytes(reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 4355 4356 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 4357 if (tid == INVALID_NUB_THREAD) 4358 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4359 "No thread specified in p packet"); 4360 4361 if (!DNBThreadSetRegisterValueByID(pid, tid, reg_entry->nub_info.set, 4362 reg_entry->nub_info.reg, ®_value)) { 4363 return SendPacket("E32"); 4364 } 4365 return SendPacket("OK"); 4366 } 4367 4368 /* 'c [addr]' 4369 Continue, optionally from a specified address. */ 4370 4371 rnb_err_t RNBRemote::HandlePacket_c(const char *p) { 4372 const nub_process_t pid = m_ctx.ProcessID(); 4373 4374 if (pid == INVALID_NUB_PROCESS) 4375 return SendPacket("E23"); 4376 4377 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, 4378 INVALID_NUB_ADDRESS}; 4379 4380 if (*(p + 1) != '\0') { 4381 action.tid = GetContinueThread(); 4382 errno = 0; 4383 action.addr = strtoull(p + 1, NULL, 16); 4384 if (errno != 0 && action.addr == 0) 4385 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4386 "Could not parse address in c packet"); 4387 } 4388 4389 DNBThreadResumeActions thread_actions; 4390 thread_actions.Append(action); 4391 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 4392 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4393 thread_actions.GetSize())) 4394 return SendPacket("E25"); 4395 // Don't send an "OK" packet; response is the stopped/exited message. 4396 return rnb_success; 4397 } 4398 4399 rnb_err_t RNBRemote::HandlePacket_MemoryRegionInfo(const char *p) { 4400 /* This packet will find memory attributes (e.g. readable, writable, 4401 executable, stack, jitted code) 4402 for the memory region containing a given address and return that 4403 information. 4404 4405 Users of this packet must be prepared for three results: 4406 4407 Region information is returned 4408 Region information is unavailable for this address because the address 4409 is in unmapped memory 4410 Region lookup cannot be performed on this platform or process is not 4411 yet launched 4412 This packet isn't implemented 4413 4414 Examples of use: 4415 qMemoryRegionInfo:3a55140 4416 start:3a50000,size:100000,permissions:rwx 4417 4418 qMemoryRegionInfo:0 4419 error:address in unmapped region 4420 4421 qMemoryRegionInfo:3a551140 (on a different platform) 4422 error:region lookup cannot be performed 4423 4424 qMemoryRegionInfo 4425 OK // this packet is implemented by the remote nub 4426 */ 4427 4428 p += sizeof("qMemoryRegionInfo") - 1; 4429 if (*p == '\0') 4430 return SendPacket("OK"); 4431 if (*p++ != ':') 4432 return SendPacket("E67"); 4433 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 4434 p += 2; 4435 4436 errno = 0; 4437 uint64_t address = strtoul(p, NULL, 16); 4438 if (errno != 0 && address == 0) { 4439 return HandlePacket_ILLFORMED( 4440 __FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 4441 } 4442 4443 DNBRegionInfo region_info = {0, 0, 0}; 4444 DNBProcessMemoryRegionInfo(m_ctx.ProcessID(), address, ®ion_info); 4445 std::ostringstream ostrm; 4446 4447 // start:3a50000,size:100000,permissions:rwx 4448 ostrm << "start:" << std::hex << region_info.addr << ';'; 4449 4450 if (region_info.size > 0) 4451 ostrm << "size:" << std::hex << region_info.size << ';'; 4452 4453 if (region_info.permissions) { 4454 ostrm << "permissions:"; 4455 4456 if (region_info.permissions & eMemoryPermissionsReadable) 4457 ostrm << 'r'; 4458 if (region_info.permissions & eMemoryPermissionsWritable) 4459 ostrm << 'w'; 4460 if (region_info.permissions & eMemoryPermissionsExecutable) 4461 ostrm << 'x'; 4462 ostrm << ';'; 4463 } 4464 return SendPacket(ostrm.str()); 4465 } 4466 4467 // qGetProfileData;scan_type:0xYYYYYYY 4468 rnb_err_t RNBRemote::HandlePacket_GetProfileData(const char *p) { 4469 nub_process_t pid = m_ctx.ProcessID(); 4470 if (pid == INVALID_NUB_PROCESS) 4471 return SendPacket("OK"); 4472 4473 StdStringExtractor packet(p += sizeof("qGetProfileData")); 4474 DNBProfileDataScanType scan_type = eProfileAll; 4475 std::string name; 4476 std::string value; 4477 while (packet.GetNameColonValue(name, value)) { 4478 if (name == "scan_type") { 4479 std::istringstream iss(value); 4480 uint32_t int_value = 0; 4481 if (iss >> std::hex >> int_value) { 4482 scan_type = (DNBProfileDataScanType)int_value; 4483 } 4484 } 4485 } 4486 4487 std::string data = DNBProcessGetProfileData(pid, scan_type); 4488 if (!data.empty()) { 4489 return SendPacket(data.c_str()); 4490 } else { 4491 return SendPacket("OK"); 4492 } 4493 } 4494 4495 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 4496 rnb_err_t RNBRemote::HandlePacket_SetEnableAsyncProfiling(const char *p) { 4497 nub_process_t pid = m_ctx.ProcessID(); 4498 if (pid == INVALID_NUB_PROCESS) 4499 return SendPacket("OK"); 4500 4501 StdStringExtractor packet(p += sizeof("QSetEnableAsyncProfiling")); 4502 bool enable = false; 4503 uint64_t interval_usec = 0; 4504 DNBProfileDataScanType scan_type = eProfileAll; 4505 std::string name; 4506 std::string value; 4507 while (packet.GetNameColonValue(name, value)) { 4508 if (name == "enable") { 4509 enable = strtoul(value.c_str(), NULL, 10) > 0; 4510 } else if (name == "interval_usec") { 4511 interval_usec = strtoul(value.c_str(), NULL, 10); 4512 } else if (name == "scan_type") { 4513 std::istringstream iss(value); 4514 uint32_t int_value = 0; 4515 if (iss >> std::hex >> int_value) { 4516 scan_type = (DNBProfileDataScanType)int_value; 4517 } 4518 } 4519 } 4520 4521 if (interval_usec == 0) { 4522 enable = false; 4523 } 4524 4525 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 4526 return SendPacket("OK"); 4527 } 4528 4529 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO 4530 // COMPRESS>; 4531 // 4532 // type: must be a type previously reported by the qXfer:features: 4533 // SupportedCompressions list 4534 // 4535 // minsize: is optional; by default the qXfer:features: 4536 // DefaultCompressionMinSize value is used 4537 // debugserver may have a better idea of what a good minimum packet size to 4538 // compress is than lldb. 4539 4540 rnb_err_t RNBRemote::HandlePacket_QEnableCompression(const char *p) { 4541 p += sizeof("QEnableCompression:") - 1; 4542 4543 size_t new_compression_minsize = m_compression_minsize; 4544 const char *new_compression_minsize_str = strstr(p, "minsize:"); 4545 if (new_compression_minsize_str) { 4546 new_compression_minsize_str += strlen("minsize:"); 4547 errno = 0; 4548 new_compression_minsize = strtoul(new_compression_minsize_str, NULL, 10); 4549 if (errno != 0 || new_compression_minsize == ULONG_MAX) { 4550 new_compression_minsize = m_compression_minsize; 4551 } 4552 } 4553 4554 if (strstr(p, "type:zlib-deflate;") != nullptr) { 4555 EnableCompressionNextSendPacket(compression_types::zlib_deflate); 4556 m_compression_minsize = new_compression_minsize; 4557 return SendPacket("OK"); 4558 } else if (strstr(p, "type:lz4;") != nullptr) { 4559 EnableCompressionNextSendPacket(compression_types::lz4); 4560 m_compression_minsize = new_compression_minsize; 4561 return SendPacket("OK"); 4562 } else if (strstr(p, "type:lzma;") != nullptr) { 4563 EnableCompressionNextSendPacket(compression_types::lzma); 4564 m_compression_minsize = new_compression_minsize; 4565 return SendPacket("OK"); 4566 } else if (strstr(p, "type:lzfse;") != nullptr) { 4567 EnableCompressionNextSendPacket(compression_types::lzfse); 4568 m_compression_minsize = new_compression_minsize; 4569 return SendPacket("OK"); 4570 } 4571 4572 return SendPacket("E88"); 4573 } 4574 4575 rnb_err_t RNBRemote::HandlePacket_qSpeedTest(const char *p) { 4576 p += strlen("qSpeedTest:response_size:"); 4577 char *end = NULL; 4578 errno = 0; 4579 uint64_t response_size = ::strtoul(p, &end, 16); 4580 if (errno != 0) 4581 return HandlePacket_ILLFORMED( 4582 __FILE__, __LINE__, p, 4583 "Didn't find response_size value at right offset"); 4584 else if (*end == ';') { 4585 static char g_data[4 * 1024 * 1024 + 16] = "data:"; 4586 memset(g_data + 5, 'a', response_size); 4587 g_data[response_size + 5] = '\0'; 4588 return SendPacket(g_data); 4589 } else { 4590 return SendPacket("E79"); 4591 } 4592 } 4593 4594 rnb_err_t RNBRemote::HandlePacket_WatchpointSupportInfo(const char *p) { 4595 /* This packet simply returns the number of supported hardware watchpoints. 4596 4597 Examples of use: 4598 qWatchpointSupportInfo: 4599 num:4 4600 4601 qWatchpointSupportInfo 4602 OK // this packet is implemented by the remote nub 4603 */ 4604 4605 p += sizeof("qWatchpointSupportInfo") - 1; 4606 if (*p == '\0') 4607 return SendPacket("OK"); 4608 if (*p++ != ':') 4609 return SendPacket("E67"); 4610 4611 errno = 0; 4612 uint32_t num = DNBWatchpointGetNumSupportedHWP(m_ctx.ProcessID()); 4613 std::ostringstream ostrm; 4614 4615 // size:4 4616 ostrm << "num:" << std::dec << num << ';'; 4617 return SendPacket(ostrm.str()); 4618 } 4619 4620 /* 'C sig [;addr]' 4621 Resume with signal sig, optionally at address addr. */ 4622 4623 rnb_err_t RNBRemote::HandlePacket_C(const char *p) { 4624 const nub_process_t pid = m_ctx.ProcessID(); 4625 4626 if (pid == INVALID_NUB_PROCESS) 4627 return SendPacket("E36"); 4628 4629 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, 4630 INVALID_NUB_ADDRESS}; 4631 int process_signo = -1; 4632 if (*(p + 1) != '\0') { 4633 action.tid = GetContinueThread(); 4634 char *end = NULL; 4635 errno = 0; 4636 process_signo = static_cast<int>(strtoul(p + 1, &end, 16)); 4637 if (errno != 0) 4638 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4639 "Could not parse signal in C packet"); 4640 else if (*end == ';') { 4641 errno = 0; 4642 action.addr = strtoull(end + 1, NULL, 16); 4643 if (errno != 0 && action.addr == 0) 4644 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4645 "Could not parse address in C packet"); 4646 } 4647 } 4648 4649 DNBThreadResumeActions thread_actions; 4650 thread_actions.Append(action); 4651 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, action.signal); 4652 if (!DNBProcessSignal(pid, process_signo)) 4653 return SendPacket("E52"); 4654 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4655 thread_actions.GetSize())) 4656 return SendPacket("E38"); 4657 /* Don't send an "OK" packet; response is the stopped/exited message. */ 4658 return rnb_success; 4659 } 4660 4661 // 'D' packet 4662 // Detach from gdb. 4663 rnb_err_t RNBRemote::HandlePacket_D(const char *p) { 4664 if (m_ctx.HasValidProcessID()) { 4665 if (DNBProcessDetach(m_ctx.ProcessID())) 4666 SendPacket("OK"); 4667 else 4668 SendPacket("E"); 4669 } else { 4670 SendPacket("E"); 4671 } 4672 return rnb_success; 4673 } 4674 4675 /* 'k' 4676 Kill the inferior process. */ 4677 4678 rnb_err_t RNBRemote::HandlePacket_k(const char *p) { 4679 DNBLog("Got a 'k' packet, killing the inferior process."); 4680 // No response to should be sent to the kill packet 4681 if (m_ctx.HasValidProcessID()) 4682 DNBProcessKill(m_ctx.ProcessID()); 4683 SendPacket("X09"); 4684 return rnb_success; 4685 } 4686 4687 rnb_err_t RNBRemote::HandlePacket_stop_process(const char *p) { 4688 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test 4689 //exiting on interrupt 4690 #if defined(TEST_EXIT_ON_INTERRUPT) 4691 rnb_err_t err = HandlePacket_k(p); 4692 m_comm.Disconnect(true); 4693 return err; 4694 #else 4695 if (!DNBProcessInterrupt(m_ctx.ProcessID())) { 4696 // If we failed to interrupt the process, then send a stop 4697 // reply packet as the process was probably already stopped 4698 DNBLogThreaded("RNBRemote::HandlePacket_stop_process() sending extra stop " 4699 "reply because DNBProcessInterrupt returned false"); 4700 HandlePacket_last_signal(NULL); 4701 } 4702 return rnb_success; 4703 #endif 4704 } 4705 4706 /* 's' 4707 Step the inferior process. */ 4708 4709 rnb_err_t RNBRemote::HandlePacket_s(const char *p) { 4710 const nub_process_t pid = m_ctx.ProcessID(); 4711 if (pid == INVALID_NUB_PROCESS) 4712 return SendPacket("E32"); 4713 4714 // Hardware supported stepping not supported on arm 4715 nub_thread_t tid = GetContinueThread(); 4716 if (tid == 0 || tid == (nub_thread_t)-1) 4717 tid = GetCurrentThread(); 4718 4719 if (tid == INVALID_NUB_THREAD) 4720 return SendPacket("E33"); 4721 4722 DNBThreadResumeActions thread_actions; 4723 thread_actions.AppendAction(tid, eStateStepping); 4724 4725 // Make all other threads stop when we are stepping 4726 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4727 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4728 thread_actions.GetSize())) 4729 return SendPacket("E49"); 4730 // Don't send an "OK" packet; response is the stopped/exited message. 4731 return rnb_success; 4732 } 4733 4734 /* 'S sig [;addr]' 4735 Step with signal sig, optionally at address addr. */ 4736 4737 rnb_err_t RNBRemote::HandlePacket_S(const char *p) { 4738 const nub_process_t pid = m_ctx.ProcessID(); 4739 if (pid == INVALID_NUB_PROCESS) 4740 return SendPacket("E36"); 4741 4742 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateStepping, 0, 4743 INVALID_NUB_ADDRESS}; 4744 4745 if (*(p + 1) != '\0') { 4746 char *end = NULL; 4747 errno = 0; 4748 action.signal = static_cast<int>(strtoul(p + 1, &end, 16)); 4749 if (errno != 0) 4750 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4751 "Could not parse signal in S packet"); 4752 else if (*end == ';') { 4753 errno = 0; 4754 action.addr = strtoull(end + 1, NULL, 16); 4755 if (errno != 0 && action.addr == 0) { 4756 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4757 "Could not parse address in S packet"); 4758 } 4759 } 4760 } 4761 4762 action.tid = GetContinueThread(); 4763 if (action.tid == 0 || action.tid == (nub_thread_t)-1) 4764 return SendPacket("E40"); 4765 4766 nub_state_t tstate = DNBThreadGetState(pid, action.tid); 4767 if (tstate == eStateInvalid || tstate == eStateExited) 4768 return SendPacket("E37"); 4769 4770 DNBThreadResumeActions thread_actions; 4771 thread_actions.Append(action); 4772 4773 // Make all other threads stop when we are stepping 4774 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4775 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4776 thread_actions.GetSize())) 4777 return SendPacket("E39"); 4778 4779 // Don't send an "OK" packet; response is the stopped/exited message. 4780 return rnb_success; 4781 } 4782 4783 static const char *GetArchName(const uint32_t cputype, 4784 const uint32_t cpusubtype) { 4785 switch (cputype) { 4786 case CPU_TYPE_ARM: 4787 switch (cpusubtype) { 4788 case 5: 4789 return "armv4"; 4790 case 6: 4791 return "armv6"; 4792 case 7: 4793 return "armv5t"; 4794 case 8: 4795 return "xscale"; 4796 case 9: 4797 return "armv7"; 4798 case 10: 4799 return "armv7f"; 4800 case 11: 4801 return "armv7s"; 4802 case 12: 4803 return "armv7k"; 4804 case 14: 4805 return "armv6m"; 4806 case 15: 4807 return "armv7m"; 4808 case 16: 4809 return "armv7em"; 4810 default: 4811 return "arm"; 4812 } 4813 break; 4814 case CPU_TYPE_ARM64: 4815 return "arm64"; 4816 case CPU_TYPE_ARM64_32: 4817 return "arm64_32"; 4818 case CPU_TYPE_I386: 4819 return "i386"; 4820 case CPU_TYPE_X86_64: 4821 switch (cpusubtype) { 4822 default: 4823 return "x86_64"; 4824 case 8: 4825 return "x86_64h"; 4826 } 4827 break; 4828 } 4829 return NULL; 4830 } 4831 4832 static bool GetHostCPUType(uint32_t &cputype, uint32_t &cpusubtype, 4833 uint32_t &is_64_bit_capable, bool &promoted_to_64) { 4834 static uint32_t g_host_cputype = 0; 4835 static uint32_t g_host_cpusubtype = 0; 4836 static uint32_t g_is_64_bit_capable = 0; 4837 static bool g_promoted_to_64 = false; 4838 4839 if (g_host_cputype == 0) { 4840 g_promoted_to_64 = false; 4841 size_t len = sizeof(uint32_t); 4842 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) { 4843 len = sizeof(uint32_t); 4844 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, 4845 NULL, 0) == 0) { 4846 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) { 4847 g_promoted_to_64 = true; 4848 g_host_cputype |= CPU_ARCH_ABI64; 4849 } 4850 } 4851 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4852 if (g_host_cputype == CPU_TYPE_ARM64 && sizeof (void*) == 4) 4853 g_host_cputype = CPU_TYPE_ARM64_32; 4854 #endif 4855 } 4856 4857 len = sizeof(uint32_t); 4858 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 4859 0) { 4860 if (g_promoted_to_64 && g_host_cputype == CPU_TYPE_X86_64 && 4861 g_host_cpusubtype == CPU_SUBTYPE_486) 4862 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4863 } 4864 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4865 // on arm64_32 devices, the machine's native cpu type is 4866 // CPU_TYPE_ARM64 and subtype is 2 indicating arm64e. 4867 // But we change the cputype to CPU_TYPE_ARM64_32 because 4868 // the user processes are all ILP32 processes today. 4869 // We also need to rewrite the cpusubtype so we vend 4870 // a valid cputype + cpusubtype combination. 4871 if (g_host_cputype == CPU_TYPE_ARM64_32) 4872 g_host_cpusubtype = CPU_SUBTYPE_ARM64_32_V8; 4873 #endif 4874 } 4875 4876 cputype = g_host_cputype; 4877 cpusubtype = g_host_cpusubtype; 4878 is_64_bit_capable = g_is_64_bit_capable; 4879 promoted_to_64 = g_promoted_to_64; 4880 return g_host_cputype != 0; 4881 } 4882 4883 static bool GetAddressingBits(uint32_t &addressing_bits) { 4884 static uint32_t g_addressing_bits = 0; 4885 static bool g_tried_addressing_bits_syscall = false; 4886 if (g_tried_addressing_bits_syscall == false) { 4887 size_t len = sizeof (uint32_t); 4888 if (::sysctlbyname("machdep.virtual_address_size", 4889 &g_addressing_bits, &len, NULL, 0) != 0) { 4890 g_addressing_bits = 0; 4891 } 4892 } 4893 g_tried_addressing_bits_syscall = true; 4894 addressing_bits = g_addressing_bits; 4895 if (addressing_bits > 0) 4896 return true; 4897 else 4898 return false; 4899 } 4900 4901 rnb_err_t RNBRemote::HandlePacket_qHostInfo(const char *p) { 4902 std::ostringstream strm; 4903 4904 uint32_t cputype = 0; 4905 uint32_t cpusubtype = 0; 4906 uint32_t is_64_bit_capable = 0; 4907 bool promoted_to_64 = false; 4908 if (GetHostCPUType(cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) { 4909 strm << "cputype:" << std::dec << cputype << ';'; 4910 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4911 } 4912 4913 uint32_t addressing_bits = 0; 4914 if (GetAddressingBits(addressing_bits)) { 4915 strm << "addressing_bits:" << std::dec << addressing_bits << ';'; 4916 } 4917 4918 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4919 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4920 // this for now. 4921 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64 4922 || cputype == CPU_TYPE_ARM64_32) { 4923 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 4924 strm << "ostype:tvos;"; 4925 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4926 strm << "ostype:watchos;"; 4927 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 4928 strm << "ostype:bridgeos;"; 4929 #else 4930 strm << "ostype:ios;"; 4931 #endif 4932 4933 // On armv7 we use "synchronous" watchpoints which means the exception is 4934 // delivered before the instruction executes. 4935 strm << "watchpoint_exceptions_received:before;"; 4936 } else { 4937 strm << "ostype:macosx;"; 4938 strm << "watchpoint_exceptions_received:after;"; 4939 } 4940 // char ostype[64]; 4941 // len = sizeof(ostype); 4942 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4943 // { 4944 // len = strlen(ostype); 4945 // std::transform (ostype, ostype + len, ostype, tolower); 4946 // strm << "ostype:" << std::dec << ostype << ';'; 4947 // } 4948 4949 strm << "vendor:apple;"; 4950 4951 uint64_t major, minor, patch; 4952 if (DNBGetOSVersionNumbers(&major, &minor, &patch)) { 4953 strm << "os_version:" << major << "." << minor; 4954 if (patch != UINT64_MAX) 4955 strm << "." << patch; 4956 strm << ";"; 4957 } 4958 4959 std::string maccatalyst_version = DNBGetMacCatalystVersionString(); 4960 if (!maccatalyst_version.empty() && 4961 std::all_of(maccatalyst_version.begin(), maccatalyst_version.end(), 4962 [](char c) { return (c >= '0' && c <= '9') || c == '.'; })) 4963 strm << "maccatalyst_version:" << maccatalyst_version << ";"; 4964 4965 #if defined(__LITTLE_ENDIAN__) 4966 strm << "endian:little;"; 4967 #elif defined(__BIG_ENDIAN__) 4968 strm << "endian:big;"; 4969 #elif defined(__PDP_ENDIAN__) 4970 strm << "endian:pdp;"; 4971 #endif 4972 4973 if (promoted_to_64) 4974 strm << "ptrsize:8;"; 4975 else 4976 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4977 4978 #if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4979 strm << "default_packet_timeout:10;"; 4980 #endif 4981 4982 return SendPacket(strm.str()); 4983 } 4984 4985 void XMLElementStart(std::ostringstream &s, uint32_t indent, const char *name, 4986 bool has_attributes) { 4987 if (indent) 4988 s << INDENT_WITH_SPACES(indent); 4989 s << '<' << name; 4990 if (!has_attributes) 4991 s << '>' << std::endl; 4992 } 4993 4994 void XMLElementStartEndAttributes(std::ostringstream &s, bool empty) { 4995 if (empty) 4996 s << '/'; 4997 s << '>' << std::endl; 4998 } 4999 5000 void XMLElementEnd(std::ostringstream &s, uint32_t indent, const char *name) { 5001 if (indent) 5002 s << INDENT_WITH_SPACES(indent); 5003 s << '<' << '/' << name << '>' << std::endl; 5004 } 5005 5006 void XMLElementWithStringValue(std::ostringstream &s, uint32_t indent, 5007 const char *name, const char *value, 5008 bool close = true) { 5009 if (value) { 5010 if (indent) 5011 s << INDENT_WITH_SPACES(indent); 5012 s << '<' << name << '>' << value; 5013 if (close) 5014 XMLElementEnd(s, 0, name); 5015 } 5016 } 5017 5018 void XMLElementWithUnsignedValue(std::ostringstream &s, uint32_t indent, 5019 const char *name, uint64_t value, 5020 bool close = true) { 5021 if (indent) 5022 s << INDENT_WITH_SPACES(indent); 5023 5024 s << '<' << name << '>' << DECIMAL << value; 5025 if (close) 5026 XMLElementEnd(s, 0, name); 5027 } 5028 5029 void XMLAttributeString(std::ostringstream &s, const char *name, 5030 const char *value, const char *default_value = NULL) { 5031 if (value) { 5032 if (default_value && strcmp(value, default_value) == 0) 5033 return; // No need to emit the attribute because it matches the default 5034 // value 5035 s << ' ' << name << "=\"" << value << "\""; 5036 } 5037 } 5038 5039 void XMLAttributeUnsignedDecimal(std::ostringstream &s, const char *name, 5040 uint64_t value) { 5041 s << ' ' << name << "=\"" << DECIMAL << value << "\""; 5042 } 5043 5044 void GenerateTargetXMLRegister(std::ostringstream &s, const uint32_t reg_num, 5045 nub_size_t num_reg_sets, 5046 const DNBRegisterSetInfo *reg_set_info, 5047 const register_map_entry_t ®) { 5048 const char *default_lldb_encoding = "uint"; 5049 const char *lldb_encoding = default_lldb_encoding; 5050 const char *gdb_group = "general"; 5051 const char *default_gdb_type = "int"; 5052 const char *gdb_type = default_gdb_type; 5053 const char *default_lldb_format = "hex"; 5054 const char *lldb_format = default_lldb_format; 5055 const char *lldb_set = NULL; 5056 5057 switch (reg.nub_info.type) { 5058 case Uint: 5059 lldb_encoding = "uint"; 5060 break; 5061 case Sint: 5062 lldb_encoding = "sint"; 5063 break; 5064 case IEEE754: 5065 lldb_encoding = "ieee754"; 5066 if (reg.nub_info.set > 0) 5067 gdb_group = "float"; 5068 break; 5069 case Vector: 5070 lldb_encoding = "vector"; 5071 if (reg.nub_info.set > 0) 5072 gdb_group = "vector"; 5073 break; 5074 } 5075 5076 switch (reg.nub_info.format) { 5077 case Binary: 5078 lldb_format = "binary"; 5079 break; 5080 case Decimal: 5081 lldb_format = "decimal"; 5082 break; 5083 case Hex: 5084 lldb_format = "hex"; 5085 break; 5086 case Float: 5087 gdb_type = "float"; 5088 lldb_format = "float"; 5089 break; 5090 case VectorOfSInt8: 5091 gdb_type = "float"; 5092 lldb_format = "vector-sint8"; 5093 break; 5094 case VectorOfUInt8: 5095 gdb_type = "float"; 5096 lldb_format = "vector-uint8"; 5097 break; 5098 case VectorOfSInt16: 5099 gdb_type = "float"; 5100 lldb_format = "vector-sint16"; 5101 break; 5102 case VectorOfUInt16: 5103 gdb_type = "float"; 5104 lldb_format = "vector-uint16"; 5105 break; 5106 case VectorOfSInt32: 5107 gdb_type = "float"; 5108 lldb_format = "vector-sint32"; 5109 break; 5110 case VectorOfUInt32: 5111 gdb_type = "float"; 5112 lldb_format = "vector-uint32"; 5113 break; 5114 case VectorOfFloat32: 5115 gdb_type = "float"; 5116 lldb_format = "vector-float32"; 5117 break; 5118 case VectorOfUInt128: 5119 gdb_type = "float"; 5120 lldb_format = "vector-uint128"; 5121 break; 5122 }; 5123 if (reg_set_info && reg.nub_info.set < num_reg_sets) 5124 lldb_set = reg_set_info[reg.nub_info.set].name; 5125 5126 uint32_t indent = 2; 5127 5128 XMLElementStart(s, indent, "reg", true); 5129 XMLAttributeString(s, "name", reg.nub_info.name); 5130 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 5131 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 5132 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 5133 XMLAttributeString(s, "group", gdb_group); 5134 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 5135 XMLAttributeString(s, "altname", reg.nub_info.alt); 5136 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 5137 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 5138 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 5139 if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM) 5140 XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe); 5141 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 5142 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 5143 5144 const char *lldb_generic = NULL; 5145 switch (reg.nub_info.reg_generic) { 5146 case GENERIC_REGNUM_FP: 5147 lldb_generic = "fp"; 5148 break; 5149 case GENERIC_REGNUM_PC: 5150 lldb_generic = "pc"; 5151 break; 5152 case GENERIC_REGNUM_SP: 5153 lldb_generic = "sp"; 5154 break; 5155 case GENERIC_REGNUM_RA: 5156 lldb_generic = "ra"; 5157 break; 5158 case GENERIC_REGNUM_FLAGS: 5159 lldb_generic = "flags"; 5160 break; 5161 case GENERIC_REGNUM_ARG1: 5162 lldb_generic = "arg1"; 5163 break; 5164 case GENERIC_REGNUM_ARG2: 5165 lldb_generic = "arg2"; 5166 break; 5167 case GENERIC_REGNUM_ARG3: 5168 lldb_generic = "arg3"; 5169 break; 5170 case GENERIC_REGNUM_ARG4: 5171 lldb_generic = "arg4"; 5172 break; 5173 case GENERIC_REGNUM_ARG5: 5174 lldb_generic = "arg5"; 5175 break; 5176 case GENERIC_REGNUM_ARG6: 5177 lldb_generic = "arg6"; 5178 break; 5179 case GENERIC_REGNUM_ARG7: 5180 lldb_generic = "arg7"; 5181 break; 5182 case GENERIC_REGNUM_ARG8: 5183 lldb_generic = "arg8"; 5184 break; 5185 default: 5186 break; 5187 } 5188 XMLAttributeString(s, "generic", lldb_generic); 5189 5190 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 5191 if (!empty) { 5192 if (!reg.value_regnums.empty()) { 5193 std::ostringstream regnums; 5194 bool first = true; 5195 regnums << DECIMAL; 5196 for (auto regnum : reg.value_regnums) { 5197 if (!first) 5198 regnums << ','; 5199 regnums << regnum; 5200 first = false; 5201 } 5202 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 5203 } 5204 5205 if (!reg.invalidate_regnums.empty()) { 5206 std::ostringstream regnums; 5207 bool first = true; 5208 regnums << DECIMAL; 5209 for (auto regnum : reg.invalidate_regnums) { 5210 if (!first) 5211 regnums << ','; 5212 regnums << regnum; 5213 first = false; 5214 } 5215 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 5216 } 5217 } 5218 XMLElementStartEndAttributes(s, true); 5219 } 5220 5221 void GenerateTargetXMLRegisters(std::ostringstream &s) { 5222 nub_size_t num_reg_sets = 0; 5223 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo(&num_reg_sets); 5224 5225 uint32_t cputype = DNBGetRegisterCPUType(); 5226 if (cputype) { 5227 XMLElementStart(s, 0, "feature", true); 5228 std::ostringstream name_strm; 5229 name_strm << "com.apple.debugserver." << GetArchName(cputype, 0); 5230 XMLAttributeString(s, "name", name_strm.str().c_str()); 5231 XMLElementStartEndAttributes(s, false); 5232 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 5233 // for (const auto ®: g_dynamic_register_map) 5234 { 5235 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, 5236 g_reg_entries[reg_num]); 5237 } 5238 XMLElementEnd(s, 0, "feature"); 5239 5240 if (num_reg_sets > 0) { 5241 XMLElementStart(s, 0, "groups", false); 5242 for (uint32_t set = 1; set < num_reg_sets; ++set) { 5243 XMLElementStart(s, 2, "group", true); 5244 XMLAttributeUnsignedDecimal(s, "id", set); 5245 XMLAttributeString(s, "name", reg_sets[set].name); 5246 XMLElementStartEndAttributes(s, true); 5247 } 5248 XMLElementEnd(s, 0, "groups"); 5249 } 5250 } 5251 } 5252 5253 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 5254 <target version="1.0">)"; 5255 5256 static const char *g_target_xml_footer = "</target>"; 5257 5258 static std::string g_target_xml; 5259 5260 void UpdateTargetXML() { 5261 std::ostringstream s; 5262 s << g_target_xml_header << std::endl; 5263 5264 // Set the architecture 5265 // 5266 // On raw targets (no OS, vendor info), I've seen replies like 5267 // <architecture>i386:x86-64</architecture> (for x86_64 systems - from vmware) 5268 // <architecture>arm</architecture> (for an unspecified arm device - from a Segger JLink) 5269 // For good interop, I'm not sure what's expected here. e.g. will anyone understand 5270 // <architecture>x86_64</architecture> ? Or is i386:x86_64 the expected phrasing? 5271 // 5272 // s << "<architecture>" << arch "</architecture>" << std::endl; 5273 5274 // Set the OSABI 5275 // s << "<osabi>abi-name</osabi>" 5276 5277 GenerateTargetXMLRegisters(s); 5278 5279 s << g_target_xml_footer << std::endl; 5280 5281 // Save the XML output in case it gets retrieved in chunks 5282 g_target_xml = s.str(); 5283 } 5284 5285 rnb_err_t RNBRemote::HandlePacket_qXfer(const char *command) { 5286 const char *p = command; 5287 p += strlen("qXfer:"); 5288 const char *sep = strchr(p, ':'); 5289 if (sep) { 5290 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 5291 p = sep + 1; 5292 sep = strchr(p, ':'); 5293 if (sep) { 5294 std::string rw(p, sep - p); // "read" or "write" 5295 p = sep + 1; 5296 sep = strchr(p, ':'); 5297 if (sep) { 5298 std::string annex(p, sep - p); // "read" or "write" 5299 5300 p = sep + 1; 5301 sep = strchr(p, ','); 5302 if (sep) { 5303 std::string offset_str(p, sep - p); // read the length as a string 5304 p = sep + 1; 5305 std::string length_str(p); // read the offset as a string 5306 char *end = nullptr; 5307 const uint64_t offset = strtoul(offset_str.c_str(), &end, 5308 16); // convert offset_str to a offset 5309 if (*end == '\0') { 5310 const uint64_t length = strtoul( 5311 length_str.c_str(), &end, 16); // convert length_str to a length 5312 if (*end == '\0') { 5313 if (object == "features" && rw == "read" && 5314 annex == "target.xml") { 5315 std::ostringstream xml_out; 5316 5317 if (offset == 0) { 5318 InitializeRegisters(true); 5319 5320 UpdateTargetXML(); 5321 if (g_target_xml.empty()) 5322 return SendPacket("E83"); 5323 5324 if (length > g_target_xml.size()) { 5325 xml_out << 'l'; // No more data 5326 xml_out << binary_encode_string(g_target_xml); 5327 } else { 5328 xml_out << 'm'; // More data needs to be read with a 5329 // subsequent call 5330 xml_out << binary_encode_string( 5331 std::string(g_target_xml, offset, length)); 5332 } 5333 } else { 5334 // Retrieving target XML in chunks 5335 if (offset < g_target_xml.size()) { 5336 std::string chunk(g_target_xml, offset, length); 5337 if (chunk.size() < length) 5338 xml_out << 'l'; // No more data 5339 else 5340 xml_out << 'm'; // More data needs to be read with a 5341 // subsequent call 5342 xml_out << binary_encode_string(chunk.data()); 5343 } 5344 } 5345 return SendPacket(xml_out.str()); 5346 } 5347 // Well formed, put not supported 5348 return HandlePacket_UNIMPLEMENTED(command); 5349 } 5350 } 5351 } 5352 } else { 5353 SendPacket("E85"); 5354 } 5355 } else { 5356 SendPacket("E86"); 5357 } 5358 } 5359 return SendPacket("E82"); 5360 } 5361 5362 rnb_err_t RNBRemote::HandlePacket_qGDBServerVersion(const char *p) { 5363 std::ostringstream strm; 5364 5365 #if defined(DEBUGSERVER_PROGRAM_NAME) 5366 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 5367 #else 5368 strm << "name:debugserver;"; 5369 #endif 5370 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 5371 5372 return SendPacket(strm.str()); 5373 } 5374 5375 // A helper function that retrieves a single integer value from 5376 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5377 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 5378 // 5379 uint64_t get_integer_value_for_key_name_from_json(const char *key, 5380 const char *json_string) { 5381 uint64_t retval = INVALID_NUB_ADDRESS; 5382 std::string key_with_quotes = "\""; 5383 key_with_quotes += key; 5384 key_with_quotes += "\""; 5385 const char *c = strstr(json_string, key_with_quotes.c_str()); 5386 if (c) { 5387 c += key_with_quotes.size(); 5388 5389 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5390 c++; 5391 5392 if (*c == ':') { 5393 c++; 5394 5395 while (*c != '\0' && 5396 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5397 c++; 5398 5399 errno = 0; 5400 retval = strtoul(c, NULL, 10); 5401 if (errno != 0) { 5402 retval = INVALID_NUB_ADDRESS; 5403 } 5404 } 5405 } 5406 return retval; 5407 } 5408 5409 // A helper function that retrieves a boolean value from 5410 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5411 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}] 5412 5413 // Returns true if it was able to find the key name, and sets the 'value' 5414 // argument to the value found. 5415 5416 bool get_boolean_value_for_key_name_from_json(const char *key, 5417 const char *json_string, 5418 bool &value) { 5419 std::string key_with_quotes = "\""; 5420 key_with_quotes += key; 5421 key_with_quotes += "\""; 5422 const char *c = strstr(json_string, key_with_quotes.c_str()); 5423 if (c) { 5424 c += key_with_quotes.size(); 5425 5426 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5427 c++; 5428 5429 if (*c == ':') { 5430 c++; 5431 5432 while (*c != '\0' && 5433 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5434 c++; 5435 5436 if (strncmp(c, "true", 4) == 0) { 5437 value = true; 5438 return true; 5439 } else if (strncmp(c, "false", 5) == 0) { 5440 value = false; 5441 return true; 5442 } 5443 } 5444 } 5445 return false; 5446 } 5447 5448 // A helper function that reads an array of uint64_t's from 5449 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5450 // jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}] 5451 5452 // Returns true if it was able to find the key name, false if it did not. 5453 // "ints" will have all integers found in the array appended to it. 5454 5455 bool get_array_of_ints_value_for_key_name_from_json( 5456 const char *key, const char *json_string, std::vector<uint64_t> &ints) { 5457 std::string key_with_quotes = "\""; 5458 key_with_quotes += key; 5459 key_with_quotes += "\""; 5460 const char *c = strstr(json_string, key_with_quotes.c_str()); 5461 if (c) { 5462 c += key_with_quotes.size(); 5463 5464 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5465 c++; 5466 5467 if (*c == ':') { 5468 c++; 5469 5470 while (*c != '\0' && 5471 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5472 c++; 5473 5474 if (*c == '[') { 5475 c++; 5476 while (*c != '\0' && 5477 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5478 c++; 5479 while (true) { 5480 if (!isdigit(*c)) { 5481 return true; 5482 } 5483 5484 errno = 0; 5485 char *endptr; 5486 uint64_t value = strtoul(c, &endptr, 10); 5487 if (errno == 0) { 5488 ints.push_back(value); 5489 } else { 5490 break; 5491 } 5492 if (endptr == c || endptr == nullptr || *endptr == '\0') { 5493 break; 5494 } 5495 c = endptr; 5496 5497 while (*c != '\0' && 5498 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5499 c++; 5500 if (*c == ',') 5501 c++; 5502 while (*c != '\0' && 5503 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5504 c++; 5505 if (*c == ']') { 5506 return true; 5507 } 5508 } 5509 } 5510 } 5511 } 5512 return false; 5513 } 5514 5515 JSONGenerator::ObjectSP 5516 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) { 5517 JSONGenerator::ArraySP threads_array_sp; 5518 if (m_ctx.HasValidProcessID()) { 5519 threads_array_sp = std::make_shared<JSONGenerator::Array>(); 5520 5521 nub_process_t pid = m_ctx.ProcessID(); 5522 5523 nub_size_t numthreads = DNBProcessGetNumThreads(pid); 5524 for (nub_size_t i = 0; i < numthreads; ++i) { 5525 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, i); 5526 5527 struct DNBThreadStopInfo tid_stop_info; 5528 5529 const bool stop_info_valid = 5530 DNBThreadGetStopReason(pid, tid, &tid_stop_info); 5531 5532 // If we are doing stop info only, then we only show threads that have a 5533 // valid stop reason 5534 if (threads_with_valid_stop_info_only) { 5535 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5536 continue; 5537 } 5538 5539 JSONGenerator::DictionarySP thread_dict_sp( 5540 new JSONGenerator::Dictionary()); 5541 thread_dict_sp->AddIntegerItem("tid", tid); 5542 5543 std::string reason_value("none"); 5544 5545 if (stop_info_valid) { 5546 switch (tid_stop_info.reason) { 5547 case eStopTypeInvalid: 5548 break; 5549 5550 case eStopTypeSignal: 5551 if (tid_stop_info.details.signal.signo != 0) { 5552 thread_dict_sp->AddIntegerItem("signal", 5553 tid_stop_info.details.signal.signo); 5554 reason_value = "signal"; 5555 } 5556 break; 5557 5558 case eStopTypeException: 5559 if (tid_stop_info.details.exception.type != 0) { 5560 reason_value = "exception"; 5561 thread_dict_sp->AddIntegerItem( 5562 "metype", tid_stop_info.details.exception.type); 5563 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5564 for (nub_size_t i = 0; 5565 i < tid_stop_info.details.exception.data_count; ++i) { 5566 medata_array_sp->AddItem( 5567 JSONGenerator::IntegerSP(new JSONGenerator::Integer( 5568 tid_stop_info.details.exception.data[i]))); 5569 } 5570 thread_dict_sp->AddItem("medata", medata_array_sp); 5571 } 5572 break; 5573 5574 case eStopTypeExec: 5575 reason_value = "exec"; 5576 break; 5577 } 5578 } 5579 5580 thread_dict_sp->AddStringItem("reason", reason_value); 5581 5582 if (!threads_with_valid_stop_info_only) { 5583 const char *thread_name = DNBThreadGetName(pid, tid); 5584 if (thread_name && thread_name[0]) 5585 thread_dict_sp->AddStringItem("name", thread_name); 5586 5587 thread_identifier_info_data_t thread_ident_info; 5588 if (DNBThreadGetIdentifierInfo(pid, tid, &thread_ident_info)) { 5589 if (thread_ident_info.dispatch_qaddr != 0) { 5590 thread_dict_sp->AddIntegerItem("qaddr", 5591 thread_ident_info.dispatch_qaddr); 5592 5593 const DispatchQueueOffsets *dispatch_queue_offsets = 5594 GetDispatchQueueOffsets(); 5595 if (dispatch_queue_offsets) { 5596 std::string queue_name; 5597 uint64_t queue_width = 0; 5598 uint64_t queue_serialnum = 0; 5599 nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS; 5600 dispatch_queue_offsets->GetThreadQueueInfo( 5601 pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, 5602 queue_name, queue_width, queue_serialnum); 5603 if (dispatch_queue_t == 0 && queue_name.empty() && 5604 queue_serialnum == 0) { 5605 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5606 false); 5607 } else { 5608 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5609 true); 5610 } 5611 if (dispatch_queue_t != INVALID_NUB_ADDRESS && 5612 dispatch_queue_t != 0) 5613 thread_dict_sp->AddIntegerItem("dispatch_queue_t", 5614 dispatch_queue_t); 5615 if (!queue_name.empty()) 5616 thread_dict_sp->AddStringItem("qname", queue_name); 5617 if (queue_width == 1) 5618 thread_dict_sp->AddStringItem("qkind", "serial"); 5619 else if (queue_width > 1) 5620 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5621 if (queue_serialnum > 0) 5622 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum); 5623 } 5624 } 5625 } 5626 5627 DNBRegisterValue reg_value; 5628 5629 if (g_reg_entries != NULL) { 5630 JSONGenerator::DictionarySP registers_dict_sp( 5631 new JSONGenerator::Dictionary()); 5632 5633 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) { 5634 // Expedite all registers in the first register set that aren't 5635 // contained in other registers 5636 if (g_reg_entries[reg].nub_info.set == 1 && 5637 g_reg_entries[reg].nub_info.value_regs == NULL) { 5638 if (!DNBThreadGetRegisterValueByID( 5639 pid, tid, g_reg_entries[reg].nub_info.set, 5640 g_reg_entries[reg].nub_info.reg, ®_value)) 5641 continue; 5642 5643 std::ostringstream reg_num; 5644 reg_num << std::dec << g_reg_entries[reg].debugserver_regnum; 5645 // Encode native byte ordered bytes as hex ascii 5646 registers_dict_sp->AddBytesAsHexASCIIString( 5647 reg_num.str(), reg_value.value.v_uint8, 5648 g_reg_entries[reg].nub_info.size); 5649 } 5650 } 5651 thread_dict_sp->AddItem("registers", registers_dict_sp); 5652 } 5653 5654 // Add expedited stack memory so stack backtracing doesn't need to read 5655 // anything from the 5656 // frame pointer chain. 5657 StackMemoryMap stack_mmap; 5658 ReadStackMemory(pid, tid, stack_mmap); 5659 if (!stack_mmap.empty()) { 5660 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5661 5662 for (const auto &stack_memory : stack_mmap) { 5663 JSONGenerator::DictionarySP stack_memory_sp( 5664 new JSONGenerator::Dictionary()); 5665 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5666 stack_memory_sp->AddBytesAsHexASCIIString( 5667 "bytes", stack_memory.second.bytes, stack_memory.second.length); 5668 memory_array_sp->AddItem(stack_memory_sp); 5669 } 5670 thread_dict_sp->AddItem("memory", memory_array_sp); 5671 } 5672 } 5673 5674 threads_array_sp->AddItem(thread_dict_sp); 5675 } 5676 } 5677 return threads_array_sp; 5678 } 5679 5680 rnb_err_t RNBRemote::HandlePacket_jThreadsInfo(const char *p) { 5681 JSONGenerator::ObjectSP threads_info_sp; 5682 std::ostringstream json; 5683 std::ostringstream reply_strm; 5684 // If we haven't run the process yet, return an error. 5685 if (m_ctx.HasValidProcessID()) { 5686 const bool threads_with_valid_stop_info_only = false; 5687 JSONGenerator::ObjectSP threads_info_sp = 5688 GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5689 5690 if (threads_info_sp) { 5691 std::ostringstream strm; 5692 threads_info_sp->Dump(strm); 5693 std::string binary_packet = binary_encode_string(strm.str()); 5694 if (!binary_packet.empty()) 5695 return SendPacket(binary_packet.c_str()); 5696 } 5697 } 5698 return SendPacket("E85"); 5699 } 5700 5701 rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) { 5702 nub_process_t pid; 5703 std::ostringstream json; 5704 // If we haven't run the process yet, return an error. 5705 if (!m_ctx.HasValidProcessID()) { 5706 return SendPacket("E81"); 5707 } 5708 5709 pid = m_ctx.ProcessID(); 5710 5711 const char thread_extended_info_str[] = {"jThreadExtendedInfo:{"}; 5712 if (strncmp(p, thread_extended_info_str, 5713 sizeof(thread_extended_info_str) - 1) == 0) { 5714 p += strlen(thread_extended_info_str); 5715 5716 uint64_t tid = get_integer_value_for_key_name_from_json("thread", p); 5717 uint64_t plo_pthread_tsd_base_address_offset = 5718 get_integer_value_for_key_name_from_json( 5719 "plo_pthread_tsd_base_address_offset", p); 5720 uint64_t plo_pthread_tsd_base_offset = 5721 get_integer_value_for_key_name_from_json("plo_pthread_tsd_base_offset", 5722 p); 5723 uint64_t plo_pthread_tsd_entry_size = 5724 get_integer_value_for_key_name_from_json("plo_pthread_tsd_entry_size", 5725 p); 5726 uint64_t dti_qos_class_index = 5727 get_integer_value_for_key_name_from_json("dti_qos_class_index", p); 5728 5729 if (tid != INVALID_NUB_ADDRESS) { 5730 nub_addr_t pthread_t_value = DNBGetPThreadT(pid, tid); 5731 5732 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5733 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS && 5734 plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS && 5735 plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) { 5736 tsd_address = DNBGetTSDAddressForThread( 5737 pid, tid, plo_pthread_tsd_base_address_offset, 5738 plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5739 } 5740 5741 bool timed_out = false; 5742 Genealogy::ThreadActivitySP thread_activity_sp; 5743 5744 // If the pthread_t value is invalid, or if we were able to fetch the 5745 // thread's TSD base 5746 // and got an invalid value back, then we have a thread in early startup 5747 // or shutdown and 5748 // it's possible that gathering the genealogy information for this thread 5749 // go badly. 5750 // Ideally fetching this info for a thread in these odd states shouldn't 5751 // matter - but 5752 // we've seen some problems with these new SPI and threads in edge-casey 5753 // states. 5754 5755 double genealogy_fetch_time = 0; 5756 if (pthread_t_value != INVALID_NUB_ADDRESS && 5757 tsd_address != INVALID_NUB_ADDRESS) { 5758 DNBTimer timer(false); 5759 thread_activity_sp = DNBGetGenealogyInfoForThread(pid, tid, timed_out); 5760 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5761 } 5762 5763 std::unordered_set<uint32_t> 5764 process_info_indexes; // an array of the process info #'s seen 5765 5766 json << "{"; 5767 5768 bool need_to_print_comma = false; 5769 5770 if (thread_activity_sp && !timed_out) { 5771 const Genealogy::Activity *activity = 5772 &thread_activity_sp->current_activity; 5773 bool need_vouchers_comma_sep = false; 5774 json << "\"activity_query_timed_out\":false,"; 5775 if (genealogy_fetch_time != 0) { 5776 // If we append the floating point value with << we'll get it in 5777 // scientific 5778 // notation. 5779 char floating_point_ascii_buffer[64]; 5780 floating_point_ascii_buffer[0] = '\0'; 5781 snprintf(floating_point_ascii_buffer, 5782 sizeof(floating_point_ascii_buffer), "%f", 5783 genealogy_fetch_time); 5784 if (strlen(floating_point_ascii_buffer) > 0) { 5785 if (need_to_print_comma) 5786 json << ","; 5787 need_to_print_comma = true; 5788 json << "\"activity_query_duration\":" 5789 << floating_point_ascii_buffer; 5790 } 5791 } 5792 if (activity->activity_id != 0) { 5793 if (need_to_print_comma) 5794 json << ","; 5795 need_to_print_comma = true; 5796 need_vouchers_comma_sep = true; 5797 json << "\"activity\":{"; 5798 json << "\"start\":" << activity->activity_start << ","; 5799 json << "\"id\":" << activity->activity_id << ","; 5800 json << "\"parent_id\":" << activity->parent_id << ","; 5801 json << "\"name\":\"" 5802 << json_string_quote_metachars(activity->activity_name) << "\","; 5803 json << "\"reason\":\"" 5804 << json_string_quote_metachars(activity->reason) << "\""; 5805 json << "}"; 5806 } 5807 if (thread_activity_sp->messages.size() > 0) { 5808 need_to_print_comma = true; 5809 if (need_vouchers_comma_sep) 5810 json << ","; 5811 need_vouchers_comma_sep = true; 5812 json << "\"trace_messages\":["; 5813 bool printed_one_message = false; 5814 for (auto iter = thread_activity_sp->messages.begin(); 5815 iter != thread_activity_sp->messages.end(); ++iter) { 5816 if (printed_one_message) 5817 json << ","; 5818 else 5819 printed_one_message = true; 5820 json << "{"; 5821 json << "\"timestamp\":" << iter->timestamp << ","; 5822 json << "\"activity_id\":" << iter->activity_id << ","; 5823 json << "\"trace_id\":" << iter->trace_id << ","; 5824 json << "\"thread\":" << iter->thread << ","; 5825 json << "\"type\":" << (int)iter->type << ","; 5826 json << "\"process_info_index\":" << iter->process_info_index 5827 << ","; 5828 process_info_indexes.insert(iter->process_info_index); 5829 json << "\"message\":\"" 5830 << json_string_quote_metachars(iter->message) << "\""; 5831 json << "}"; 5832 } 5833 json << "]"; 5834 } 5835 if (thread_activity_sp->breadcrumbs.size() == 1) { 5836 need_to_print_comma = true; 5837 if (need_vouchers_comma_sep) 5838 json << ","; 5839 need_vouchers_comma_sep = true; 5840 json << "\"breadcrumb\":{"; 5841 for (auto iter = thread_activity_sp->breadcrumbs.begin(); 5842 iter != thread_activity_sp->breadcrumbs.end(); ++iter) { 5843 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5844 json << "\"activity_id\":" << iter->activity_id << ","; 5845 json << "\"timestamp\":" << iter->timestamp << ","; 5846 json << "\"name\":\"" << json_string_quote_metachars(iter->name) 5847 << "\""; 5848 } 5849 json << "}"; 5850 } 5851 if (process_info_indexes.size() > 0) { 5852 need_to_print_comma = true; 5853 if (need_vouchers_comma_sep) 5854 json << ","; 5855 need_vouchers_comma_sep = true; 5856 bool printed_one_process_info = false; 5857 for (auto iter = process_info_indexes.begin(); 5858 iter != process_info_indexes.end(); ++iter) { 5859 if (printed_one_process_info) 5860 json << ","; 5861 Genealogy::ProcessExecutableInfoSP image_info_sp; 5862 uint32_t idx = *iter; 5863 image_info_sp = DNBGetGenealogyImageInfo(pid, idx); 5864 if (image_info_sp) { 5865 if (!printed_one_process_info) { 5866 json << "\"process_infos\":["; 5867 printed_one_process_info = true; 5868 } 5869 5870 json << "{"; 5871 char uuid_buf[37]; 5872 uuid_unparse_upper(image_info_sp->image_uuid, uuid_buf); 5873 json << "\"process_info_index\":" << idx << ","; 5874 json << "\"image_path\":\"" 5875 << json_string_quote_metachars(image_info_sp->image_path) 5876 << "\","; 5877 json << "\"image_uuid\":\"" << uuid_buf << "\""; 5878 json << "}"; 5879 } 5880 } 5881 if (printed_one_process_info) 5882 json << "]"; 5883 } 5884 } else { 5885 if (timed_out) { 5886 if (need_to_print_comma) 5887 json << ","; 5888 need_to_print_comma = true; 5889 json << "\"activity_query_timed_out\":true"; 5890 if (genealogy_fetch_time != 0) { 5891 // If we append the floating point value with << we'll get it in 5892 // scientific 5893 // notation. 5894 char floating_point_ascii_buffer[64]; 5895 floating_point_ascii_buffer[0] = '\0'; 5896 snprintf(floating_point_ascii_buffer, 5897 sizeof(floating_point_ascii_buffer), "%f", 5898 genealogy_fetch_time); 5899 if (strlen(floating_point_ascii_buffer) > 0) { 5900 json << ","; 5901 json << "\"activity_query_duration\":" 5902 << floating_point_ascii_buffer; 5903 } 5904 } 5905 } 5906 } 5907 5908 if (tsd_address != INVALID_NUB_ADDRESS) { 5909 if (need_to_print_comma) 5910 json << ","; 5911 need_to_print_comma = true; 5912 json << "\"tsd_address\":" << tsd_address; 5913 5914 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) { 5915 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread( 5916 pid, tid, tsd_address, dti_qos_class_index); 5917 if (requested_qos.IsValid()) { 5918 if (need_to_print_comma) 5919 json << ","; 5920 need_to_print_comma = true; 5921 json << "\"requested_qos\":{"; 5922 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5923 json << "\"constant_name\":\"" 5924 << json_string_quote_metachars(requested_qos.constant_name) 5925 << "\","; 5926 json << "\"printable_name\":\"" 5927 << json_string_quote_metachars(requested_qos.printable_name) 5928 << "\""; 5929 json << "}"; 5930 } 5931 } 5932 } 5933 5934 if (pthread_t_value != INVALID_NUB_ADDRESS) { 5935 if (need_to_print_comma) 5936 json << ","; 5937 need_to_print_comma = true; 5938 json << "\"pthread_t\":" << pthread_t_value; 5939 } 5940 5941 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT(pid, tid); 5942 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) { 5943 if (need_to_print_comma) 5944 json << ","; 5945 need_to_print_comma = true; 5946 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5947 } 5948 5949 json << "}"; 5950 std::string json_quoted = binary_encode_string(json.str()); 5951 return SendPacket(json_quoted); 5952 } 5953 } 5954 return SendPacket("OK"); 5955 } 5956 5957 // This packet may be called in one of three ways: 5958 // 5959 // jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704} 5960 // Look for an array of the old dyld_all_image_infos style of binary infos 5961 // at the image_list_address. 5962 // This an array of {void* load_addr, void* mod_date, void* pathname} 5963 // 5964 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} 5965 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5966 // get a list of all the 5967 // libraries loaded 5968 // 5969 // jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} 5970 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5971 // get the information 5972 // about the libraries loaded at these addresses. 5973 // 5974 rnb_err_t 5975 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) { 5976 nub_process_t pid; 5977 // If we haven't run the process yet, return an error. 5978 if (!m_ctx.HasValidProcessID()) { 5979 return SendPacket("E83"); 5980 } 5981 5982 pid = m_ctx.ProcessID(); 5983 5984 const char get_loaded_dynamic_libraries_infos_str[] = { 5985 "jGetLoadedDynamicLibrariesInfos:{"}; 5986 if (strncmp(p, get_loaded_dynamic_libraries_infos_str, 5987 sizeof(get_loaded_dynamic_libraries_infos_str) - 1) == 0) { 5988 p += strlen(get_loaded_dynamic_libraries_infos_str); 5989 5990 JSONGenerator::ObjectSP json_sp; 5991 5992 std::vector<uint64_t> macho_addresses; 5993 bool fetch_all_solibs = false; 5994 if (get_boolean_value_for_key_name_from_json("fetch_all_solibs", p, 5995 fetch_all_solibs) && 5996 fetch_all_solibs) { 5997 json_sp = DNBGetAllLoadedLibrariesInfos(pid); 5998 } else if (get_array_of_ints_value_for_key_name_from_json( 5999 "solib_addresses", p, macho_addresses)) { 6000 json_sp = DNBGetLibrariesInfoForAddresses(pid, macho_addresses); 6001 } else { 6002 nub_addr_t image_list_address = 6003 get_integer_value_for_key_name_from_json("image_list_address", p); 6004 nub_addr_t image_count = 6005 get_integer_value_for_key_name_from_json("image_count", p); 6006 6007 if (image_list_address != INVALID_NUB_ADDRESS && 6008 image_count != INVALID_NUB_ADDRESS) { 6009 json_sp = DNBGetLoadedDynamicLibrariesInfos(pid, image_list_address, 6010 image_count); 6011 } 6012 } 6013 6014 if (json_sp.get()) { 6015 std::ostringstream json_str; 6016 json_sp->Dump(json_str); 6017 if (json_str.str().size() > 0) { 6018 std::string json_str_quoted = binary_encode_string(json_str.str()); 6019 return SendPacket(json_str_quoted.c_str()); 6020 } else { 6021 SendPacket("E84"); 6022 } 6023 } 6024 } 6025 return SendPacket("OK"); 6026 } 6027 6028 // This packet does not currently take any arguments. So the behavior is 6029 // jGetSharedCacheInfo:{} 6030 // send information about the inferior's shared cache 6031 // jGetSharedCacheInfo: 6032 // send "OK" to indicate that this packet is supported 6033 rnb_err_t RNBRemote::HandlePacket_jGetSharedCacheInfo(const char *p) { 6034 nub_process_t pid; 6035 // If we haven't run the process yet, return an error. 6036 if (!m_ctx.HasValidProcessID()) { 6037 return SendPacket("E85"); 6038 } 6039 6040 pid = m_ctx.ProcessID(); 6041 6042 const char get_shared_cache_info_str[] = {"jGetSharedCacheInfo:{"}; 6043 if (strncmp(p, get_shared_cache_info_str, 6044 sizeof(get_shared_cache_info_str) - 1) == 0) { 6045 JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo(pid); 6046 6047 if (json_sp.get()) { 6048 std::ostringstream json_str; 6049 json_sp->Dump(json_str); 6050 if (json_str.str().size() > 0) { 6051 std::string json_str_quoted = binary_encode_string(json_str.str()); 6052 return SendPacket(json_str_quoted.c_str()); 6053 } else { 6054 SendPacket("E86"); 6055 } 6056 } 6057 } 6058 return SendPacket("OK"); 6059 } 6060 6061 static bool MachHeaderIsMainExecutable(nub_process_t pid, uint32_t addr_size, 6062 nub_addr_t mach_header_addr, 6063 mach_header &mh) { 6064 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, " 6065 "addr_size = %u, mach_header_addr = " 6066 "0x%16.16llx)", 6067 pid, addr_size, mach_header_addr); 6068 const nub_size_t bytes_read = 6069 DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh); 6070 if (bytes_read == sizeof(mh)) { 6071 DNBLogThreadedIf( 6072 LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = " 6073 "%u, mach_header_addr = 0x%16.16llx): mh = {\n magic = " 6074 "0x%8.8x\n cpu = 0x%8.8x\n sub = 0x%8.8x\n filetype = " 6075 "%u\n ncmds = %u\n sizeofcmds = 0x%8.8x\n flags = " 6076 "0x%8.8x }", 6077 pid, addr_size, mach_header_addr, mh.magic, mh.cputype, mh.cpusubtype, 6078 mh.filetype, mh.ncmds, mh.sizeofcmds, mh.flags); 6079 if ((addr_size == 4 && mh.magic == MH_MAGIC) || 6080 (addr_size == 8 && mh.magic == MH_MAGIC_64)) { 6081 if (mh.filetype == MH_EXECUTE) { 6082 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = " 6083 "%u, addr_size = %u, mach_header_addr = " 6084 "0x%16.16llx) -> this is the " 6085 "executable!!!", 6086 pid, addr_size, mach_header_addr); 6087 return true; 6088 } 6089 } 6090 } 6091 return false; 6092 } 6093 6094 static nub_addr_t GetMachHeaderForMainExecutable(const nub_process_t pid, 6095 const uint32_t addr_size, 6096 mach_header &mh) { 6097 struct AllImageInfos { 6098 uint32_t version; 6099 uint32_t dylib_info_count; 6100 uint64_t dylib_info_addr; 6101 }; 6102 6103 uint64_t mach_header_addr = 0; 6104 6105 const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress(pid); 6106 uint8_t bytes[256]; 6107 nub_size_t bytes_read = 0; 6108 DNBDataRef data(bytes, sizeof(bytes), false); 6109 DNBDataRef::offset_t offset = 0; 6110 data.SetPointerSize(addr_size); 6111 6112 // When we are sitting at __dyld_start, the kernel has placed the 6113 // address of the mach header of the main executable on the stack. If we 6114 // read the SP and dereference a pointer, we might find the mach header 6115 // for the executable. We also just make sure there is only 1 thread 6116 // since if we are at __dyld_start we shouldn't have multiple threads. 6117 if (DNBProcessGetNumThreads(pid) == 1) { 6118 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0); 6119 if (tid != INVALID_NUB_THREAD) { 6120 DNBRegisterValue sp_value; 6121 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, 6122 GENERIC_REGNUM_SP, &sp_value)) { 6123 uint64_t sp = 6124 addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32; 6125 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes); 6126 if (bytes_read == addr_size) { 6127 offset = 0; 6128 mach_header_addr = data.GetPointer(&offset); 6129 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 6130 return mach_header_addr; 6131 } 6132 } 6133 } 6134 } 6135 6136 // Check the dyld_all_image_info structure for a list of mach header 6137 // since it is a very easy thing to check 6138 if (shlib_addr != INVALID_NUB_ADDRESS) { 6139 bytes_read = 6140 DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes); 6141 if (bytes_read > 0) { 6142 AllImageInfos aii; 6143 offset = 0; 6144 aii.version = data.Get32(&offset); 6145 aii.dylib_info_count = data.Get32(&offset); 6146 if (aii.dylib_info_count > 0) { 6147 aii.dylib_info_addr = data.GetPointer(&offset); 6148 if (aii.dylib_info_addr != 0) { 6149 const size_t image_info_byte_size = 3 * addr_size; 6150 for (uint32_t i = 0; i < aii.dylib_info_count; ++i) { 6151 bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + 6152 i * image_info_byte_size, 6153 image_info_byte_size, bytes); 6154 if (bytes_read != image_info_byte_size) 6155 break; 6156 offset = 0; 6157 mach_header_addr = data.GetPointer(&offset); 6158 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, 6159 mh)) 6160 return mach_header_addr; 6161 } 6162 } 6163 } 6164 } 6165 } 6166 6167 // We failed to find the executable's mach header from the all image 6168 // infos and by dereferencing the stack pointer. Now we fall back to 6169 // enumerating the memory regions and looking for regions that are 6170 // executable. 6171 DNBRegionInfo region_info; 6172 mach_header_addr = 0; 6173 while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, ®ion_info)) { 6174 if (region_info.size == 0) 6175 break; 6176 6177 if (region_info.permissions & eMemoryPermissionsExecutable) { 6178 DNBLogThreadedIf( 6179 LOG_RNB_PROC, "[0x%16.16llx - 0x%16.16llx) permissions = %c%c%c: " 6180 "checking region for executable mach header", 6181 region_info.addr, region_info.addr + region_info.size, 6182 (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', 6183 (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', 6184 (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-'); 6185 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 6186 return mach_header_addr; 6187 } else { 6188 DNBLogThreadedIf( 6189 LOG_RNB_PROC, 6190 "[0x%16.16llx - 0x%16.16llx): permissions = %c%c%c: skipping region", 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 } 6196 // Set the address to the next mapped region 6197 mach_header_addr = region_info.addr + region_info.size; 6198 } 6199 bzero(&mh, sizeof(mh)); 6200 return INVALID_NUB_ADDRESS; 6201 } 6202 6203 rnb_err_t RNBRemote::HandlePacket_qSymbol(const char *command) { 6204 const char *p = command; 6205 p += strlen("qSymbol:"); 6206 const char *sep = strchr(p, ':'); 6207 6208 std::string symbol_name; 6209 std::string symbol_value_str; 6210 // Extract the symbol value if there is one 6211 if (sep > p) 6212 symbol_value_str.assign(p, sep - p); 6213 p = sep + 1; 6214 6215 if (*p) { 6216 // We have a symbol name 6217 symbol_name = decode_hex_ascii_string(p); 6218 if (!symbol_value_str.empty()) { 6219 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 6220 if (symbol_name == "dispatch_queue_offsets") 6221 m_dispatch_queue_offsets_addr = symbol_value; 6222 } 6223 ++m_qSymbol_index; 6224 } else { 6225 // No symbol name, set our symbol index to zero so we can 6226 // read any symbols that we need 6227 m_qSymbol_index = 0; 6228 } 6229 6230 symbol_name.clear(); 6231 6232 if (m_qSymbol_index == 0) { 6233 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 6234 symbol_name = "dispatch_queue_offsets"; 6235 else 6236 ++m_qSymbol_index; 6237 } 6238 6239 // // Lookup next symbol when we have one... 6240 // if (m_qSymbol_index == 1) 6241 // { 6242 // } 6243 6244 if (symbol_name.empty()) { 6245 // Done with symbol lookups 6246 return SendPacket("OK"); 6247 } else { 6248 std::ostringstream reply; 6249 reply << "qSymbol:"; 6250 for (size_t i = 0; i < symbol_name.size(); ++i) 6251 reply << RAWHEX8(symbol_name[i]); 6252 return SendPacket(reply.str().c_str()); 6253 } 6254 } 6255 6256 // Note that all numeric values returned by qProcessInfo are hex encoded, 6257 // including the pid and the cpu type. 6258 6259 rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) { 6260 nub_process_t pid; 6261 std::ostringstream rep; 6262 6263 // If we haven't run the process yet, return an error. 6264 if (!m_ctx.HasValidProcessID()) 6265 return SendPacket("E68"); 6266 6267 pid = m_ctx.ProcessID(); 6268 6269 rep << "pid:" << std::hex << pid << ';'; 6270 6271 int procpid_mib[4]; 6272 procpid_mib[0] = CTL_KERN; 6273 procpid_mib[1] = KERN_PROC; 6274 procpid_mib[2] = KERN_PROC_PID; 6275 procpid_mib[3] = pid; 6276 struct kinfo_proc proc_kinfo; 6277 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 6278 6279 if (::sysctl(procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { 6280 if (proc_kinfo_size > 0) { 6281 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';'; 6282 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid 6283 << ';'; 6284 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid 6285 << ';'; 6286 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid 6287 << ';'; 6288 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 6289 rep << "effective-gid:" << std::hex 6290 << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';'; 6291 } 6292 } 6293 6294 cpu_type_t cputype = DNBProcessGetCPUType(pid); 6295 if (cputype == 0) { 6296 DNBLog("Unable to get the process cpu_type, making a best guess."); 6297 cputype = best_guess_cpu_type(); 6298 } 6299 6300 uint32_t addr_size = 0; 6301 if (cputype != 0) { 6302 rep << "cputype:" << std::hex << cputype << ";"; 6303 if (cputype & CPU_ARCH_ABI64) 6304 addr_size = 8; 6305 else 6306 addr_size = 4; 6307 } 6308 6309 bool host_cpu_is_64bit = false; 6310 uint32_t is64bit_capable; 6311 size_t is64bit_capable_len = sizeof(is64bit_capable); 6312 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, 6313 &is64bit_capable_len, NULL, 0) == 0) 6314 host_cpu_is_64bit = is64bit_capable != 0; 6315 6316 uint32_t cpusubtype; 6317 size_t cpusubtype_len = sizeof(cpusubtype); 6318 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 6319 0) { 6320 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 6321 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 6322 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu 6323 // subtype 6324 // for i386... 6325 if (host_cpu_is_64bit) { 6326 if (cputype == CPU_TYPE_X86) { 6327 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 6328 } else if (cputype == CPU_TYPE_ARM) { 6329 // We can query a process' cputype but we cannot query a process' 6330 // cpusubtype. 6331 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit 6332 // process) and we 6333 // need to override the host cpusubtype (which is in the 6334 // CPU_SUBTYPE_ARM64 subtype namespace) 6335 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 6336 cpusubtype = 12; // CPU_SUBTYPE_ARM_V7K 6337 } 6338 } 6339 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6340 // on arm64_32 devices, the machine's native cpu type is 6341 // CPU_TYPE_ARM64 and subtype is 2 indicating arm64e. 6342 // But we change the cputype to CPU_TYPE_ARM64_32 because 6343 // the user processes are all ILP32 processes today. 6344 // We also need to rewrite the cpusubtype so we vend 6345 // a valid cputype + cpusubtype combination. 6346 if (cputype == CPU_TYPE_ARM64_32 && cpusubtype == 2) 6347 cpusubtype = CPU_SUBTYPE_ARM64_32_V8; 6348 #endif 6349 6350 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 6351 } 6352 6353 bool os_handled = false; 6354 if (addr_size > 0) { 6355 rep << "ptrsize:" << std::dec << addr_size << ';'; 6356 6357 #if (defined(__x86_64__) || defined(__i386__)) 6358 // Try and get the OS type by looking at the load commands in the main 6359 // executable and looking for a LC_VERSION_MIN load command. This is the 6360 // most reliable way to determine the "ostype" value when on desktop. 6361 6362 mach_header mh; 6363 nub_addr_t exe_mach_header_addr = 6364 GetMachHeaderForMainExecutable(pid, addr_size, mh); 6365 if (exe_mach_header_addr != INVALID_NUB_ADDRESS) { 6366 uint64_t load_command_addr = 6367 exe_mach_header_addr + 6368 ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header)); 6369 load_command lc; 6370 for (uint32_t i = 0; i < mh.ncmds && !os_handled; ++i) { 6371 const nub_size_t bytes_read = 6372 DNBProcessMemoryRead(pid, load_command_addr, sizeof(lc), &lc); 6373 (void)bytes_read; 6374 6375 uint32_t major_version, minor_version, patch_version; 6376 auto *platform = DNBGetDeploymentInfo(pid, lc, load_command_addr, 6377 major_version, minor_version, 6378 patch_version); 6379 if (platform) { 6380 os_handled = true; 6381 rep << "ostype:" << platform << ";"; 6382 break; 6383 } 6384 load_command_addr = load_command_addr + lc.cmdsize; 6385 } 6386 } 6387 #endif // when compiling this on x86 targets 6388 } 6389 6390 // If we weren't able to find the OS in a LC_VERSION_MIN load command, try 6391 // to set it correctly by using the cpu type and other tricks 6392 if (!os_handled) { 6393 // The OS in the triple should be "ios" or "macosx" which doesn't match our 6394 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 6395 // this for now. 6396 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64 6397 || cputype == CPU_TYPE_ARM64_32) { 6398 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6399 rep << "ostype:tvos;"; 6400 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6401 rep << "ostype:watchos;"; 6402 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 6403 rep << "ostype:bridgeos;"; 6404 #else 6405 rep << "ostype:ios;"; 6406 #endif 6407 } else { 6408 bool is_ios_simulator = false; 6409 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) { 6410 // Check for iOS simulator binaries by getting the process argument 6411 // and environment and checking for SIMULATOR_UDID in the environment 6412 int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2, (int)pid}; 6413 6414 uint8_t arg_data[8192]; 6415 size_t arg_data_size = sizeof(arg_data); 6416 if (::sysctl(proc_args_mib, 3, arg_data, &arg_data_size, NULL, 0) == 6417 0) { 6418 DNBDataRef data(arg_data, arg_data_size, false); 6419 DNBDataRef::offset_t offset = 0; 6420 uint32_t argc = data.Get32(&offset); 6421 const char *cstr; 6422 6423 cstr = data.GetCStr(&offset); 6424 if (cstr) { 6425 // Skip NULLs 6426 while (true) { 6427 const char *p = data.PeekCStr(offset); 6428 if ((p == NULL) || (*p != '\0')) 6429 break; 6430 ++offset; 6431 } 6432 // Now skip all arguments 6433 for (uint32_t i = 0; i < argc; ++i) { 6434 data.GetCStr(&offset); 6435 } 6436 6437 // Now iterate across all environment variables 6438 while ((cstr = data.GetCStr(&offset))) { 6439 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 6440 0) { 6441 is_ios_simulator = true; 6442 break; 6443 } 6444 if (cstr[0] == '\0') 6445 break; 6446 } 6447 } 6448 } 6449 } 6450 if (is_ios_simulator) { 6451 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6452 rep << "ostype:tvos;"; 6453 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6454 rep << "ostype:watchos;"; 6455 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 6456 rep << "ostype:bridgeos;"; 6457 #else 6458 rep << "ostype:ios;"; 6459 #endif 6460 } else { 6461 rep << "ostype:macosx;"; 6462 } 6463 } 6464 } 6465 6466 rep << "vendor:apple;"; 6467 6468 #if defined(__LITTLE_ENDIAN__) 6469 rep << "endian:little;"; 6470 #elif defined(__BIG_ENDIAN__) 6471 rep << "endian:big;"; 6472 #elif defined(__PDP_ENDIAN__) 6473 rep << "endian:pdp;"; 6474 #endif 6475 6476 if (addr_size == 0) { 6477 #if (defined(__x86_64__) || defined(__i386__)) && defined(x86_THREAD_STATE) 6478 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6479 kern_return_t kr; 6480 x86_thread_state_t gp_regs; 6481 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 6482 kr = thread_get_state(static_cast<thread_act_t>(thread), x86_THREAD_STATE, 6483 (thread_state_t)&gp_regs, &gp_count); 6484 if (kr == KERN_SUCCESS) { 6485 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 6486 rep << "ptrsize:8;"; 6487 else 6488 rep << "ptrsize:4;"; 6489 } 6490 #elif defined(__arm__) 6491 rep << "ptrsize:4;"; 6492 #elif (defined(__arm64__) || defined(__aarch64__)) && \ 6493 defined(ARM_UNIFIED_THREAD_STATE) 6494 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6495 kern_return_t kr; 6496 arm_unified_thread_state_t gp_regs; 6497 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 6498 kr = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE, 6499 (thread_state_t)&gp_regs, &gp_count); 6500 if (kr == KERN_SUCCESS) { 6501 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 6502 rep << "ptrsize:8;"; 6503 else 6504 rep << "ptrsize:4;"; 6505 } 6506 #endif 6507 } 6508 6509 return SendPacket(rep.str()); 6510 } 6511 6512 const RNBRemote::DispatchQueueOffsets *RNBRemote::GetDispatchQueueOffsets() { 6513 if (!m_dispatch_queue_offsets.IsValid() && 6514 m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && 6515 m_ctx.HasValidProcessID()) { 6516 nub_process_t pid = m_ctx.ProcessID(); 6517 nub_size_t bytes_read = DNBProcessMemoryRead( 6518 pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), 6519 &m_dispatch_queue_offsets); 6520 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 6521 m_dispatch_queue_offsets.Clear(); 6522 } 6523 6524 if (m_dispatch_queue_offsets.IsValid()) 6525 return &m_dispatch_queue_offsets; 6526 else 6527 return nullptr; 6528 } 6529 6530 void RNBRemote::EnableCompressionNextSendPacket(compression_types type) { 6531 m_compression_mode = type; 6532 m_enable_compression_next_send_packet = true; 6533 } 6534 6535 compression_types RNBRemote::GetCompressionType() { 6536 // The first packet we send back to the debugger after a QEnableCompression 6537 // request 6538 // should be uncompressed -- so we can indicate whether the compression was 6539 // enabled 6540 // or not via OK / Enn returns. After that, all packets sent will be using 6541 // the 6542 // compression protocol. 6543 6544 if (m_enable_compression_next_send_packet) { 6545 // One time, we send back "None" as our compression type 6546 m_enable_compression_next_send_packet = false; 6547 return compression_types::none; 6548 } 6549 return m_compression_mode; 6550 } 6551