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