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