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