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