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