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