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