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