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