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