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> // for endianness predefines 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 if (remote->Comm().IsConnected()) 3417 return false; 3418 else 3419 return true; 3420 } 3421 return true; 3422 } 3423 3424 // FORMAT: _MXXXXXX,PPP 3425 // XXXXXX: big endian hex chars 3426 // PPP: permissions can be any combo of r w x chars 3427 // 3428 // RESPONSE: XXXXXX 3429 // XXXXXX: hex address of the newly allocated memory 3430 // EXX: error code 3431 // 3432 // EXAMPLES: 3433 // _M123000,rw 3434 // _M123000,rwx 3435 // _M123000,xw 3436 3437 rnb_err_t RNBRemote::HandlePacket_AllocateMemory(const char *p) { 3438 StdStringExtractor packet(p); 3439 packet.SetFilePos(2); // Skip the "_M" 3440 3441 nub_addr_t size = packet.GetHexMaxU64(StdStringExtractor::BigEndian, 0); 3442 if (size != 0) { 3443 if (packet.GetChar() == ',') { 3444 uint32_t permissions = 0; 3445 char ch; 3446 bool success = true; 3447 while (success && (ch = packet.GetChar()) != '\0') { 3448 switch (ch) { 3449 case 'r': 3450 permissions |= eMemoryPermissionsReadable; 3451 break; 3452 case 'w': 3453 permissions |= eMemoryPermissionsWritable; 3454 break; 3455 case 'x': 3456 permissions |= eMemoryPermissionsExecutable; 3457 break; 3458 default: 3459 success = false; 3460 break; 3461 } 3462 } 3463 3464 if (success) { 3465 nub_addr_t addr = 3466 DNBProcessMemoryAllocate(m_ctx.ProcessID(), size, permissions); 3467 if (addr != INVALID_NUB_ADDRESS) { 3468 std::ostringstream ostrm; 3469 ostrm << RAW_HEXBASE << addr; 3470 return SendPacket(ostrm.str()); 3471 } 3472 } 3473 } 3474 } 3475 return SendPacket("E53"); 3476 } 3477 3478 // FORMAT: _mXXXXXX 3479 // XXXXXX: address that was previously allocated 3480 // 3481 // RESPONSE: XXXXXX 3482 // OK: address was deallocated 3483 // EXX: error code 3484 // 3485 // EXAMPLES: 3486 // _m123000 3487 3488 rnb_err_t RNBRemote::HandlePacket_DeallocateMemory(const char *p) { 3489 StdStringExtractor packet(p); 3490 packet.SetFilePos(2); // Skip the "_m" 3491 nub_addr_t addr = 3492 packet.GetHexMaxU64(StdStringExtractor::BigEndian, INVALID_NUB_ADDRESS); 3493 3494 if (addr != INVALID_NUB_ADDRESS) { 3495 if (DNBProcessMemoryDeallocate(m_ctx.ProcessID(), addr)) 3496 return SendPacket("OK"); 3497 } 3498 return SendPacket("E54"); 3499 } 3500 3501 // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) 3502 // FORMAT: QSaveRegisterState (when thread suffix is NOT 3503 // supported) 3504 // TTTT: thread ID in hex 3505 // 3506 // RESPONSE: 3507 // SAVEID: Where SAVEID is a decimal number that represents the save ID 3508 // that can be passed back into a "QRestoreRegisterState" packet 3509 // EXX: error code 3510 // 3511 // EXAMPLES: 3512 // QSaveRegisterState;thread:1E34; (when thread suffix is supported) 3513 // QSaveRegisterState (when thread suffix is NOT 3514 // supported) 3515 3516 rnb_err_t RNBRemote::HandlePacket_SaveRegisterState(const char *p) { 3517 nub_process_t pid = m_ctx.ProcessID(); 3518 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 3519 if (tid == INVALID_NUB_THREAD) { 3520 if (m_thread_suffix_supported) 3521 return HandlePacket_ILLFORMED( 3522 __FILE__, __LINE__, p, 3523 "No thread specified in QSaveRegisterState packet"); 3524 else 3525 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3526 "No thread was is set with the Hg packet"); 3527 } 3528 3529 // Get the register context size first by calling with NULL buffer 3530 const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid); 3531 if (save_id != 0) { 3532 char response[64]; 3533 snprintf(response, sizeof(response), "%u", save_id); 3534 return SendPacket(response); 3535 } else { 3536 return SendPacket("E75"); 3537 } 3538 } 3539 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is 3540 // supported) 3541 // FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT 3542 // supported) 3543 // TTTT: thread ID in hex 3544 // SAVEID: a decimal number that represents the save ID that was 3545 // returned from a call to "QSaveRegisterState" 3546 // 3547 // RESPONSE: 3548 // OK: successfully restored registers for the specified thread 3549 // EXX: error code 3550 // 3551 // EXAMPLES: 3552 // QRestoreRegisterState:1;thread:1E34; (when thread suffix is 3553 // supported) 3554 // QRestoreRegisterState:1 (when thread suffix is NOT 3555 // supported) 3556 3557 rnb_err_t RNBRemote::HandlePacket_RestoreRegisterState(const char *p) { 3558 nub_process_t pid = m_ctx.ProcessID(); 3559 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 3560 if (tid == INVALID_NUB_THREAD) { 3561 if (m_thread_suffix_supported) 3562 return HandlePacket_ILLFORMED( 3563 __FILE__, __LINE__, p, 3564 "No thread specified in QSaveRegisterState packet"); 3565 else 3566 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3567 "No thread was is set with the Hg packet"); 3568 } 3569 3570 StdStringExtractor packet(p); 3571 packet.SetFilePos( 3572 strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:" 3573 const uint32_t save_id = packet.GetU32(0); 3574 3575 if (save_id != 0) { 3576 // Get the register context size first by calling with NULL buffer 3577 if (DNBThreadRestoreRegisterState(pid, tid, save_id)) 3578 return SendPacket("OK"); 3579 else 3580 return SendPacket("E77"); 3581 } 3582 return SendPacket("E76"); 3583 } 3584 3585 static bool GetProcessNameFrom_vAttach(const char *&p, 3586 std::string &attach_name) { 3587 bool return_val = true; 3588 while (*p != '\0') { 3589 char smallbuf[3]; 3590 smallbuf[0] = *p; 3591 smallbuf[1] = *(p + 1); 3592 smallbuf[2] = '\0'; 3593 3594 errno = 0; 3595 int ch = static_cast<int>(strtoul(smallbuf, NULL, 16)); 3596 if (errno != 0 && ch == 0) { 3597 return_val = false; 3598 break; 3599 } 3600 3601 attach_name.push_back(ch); 3602 p += 2; 3603 } 3604 return return_val; 3605 } 3606 3607 rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) { 3608 uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet 3609 // size--debugger can always use less 3610 char buf[256]; 3611 snprintf(buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", 3612 max_packet_size); 3613 3614 bool enable_compression = false; 3615 (void)enable_compression; 3616 3617 #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) 3618 enable_compression = true; 3619 #endif 3620 3621 #if defined(HAVE_LIBCOMPRESSION) 3622 // libcompression is weak linked so test if compression_decode_buffer() is 3623 // available 3624 if (enable_compression) { 3625 strcat(buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;" 3626 "DefaultCompressionMinSize="); 3627 char numbuf[16]; 3628 snprintf(numbuf, sizeof(numbuf), "%zu", m_compression_minsize); 3629 numbuf[sizeof(numbuf) - 1] = '\0'; 3630 strcat(buf, numbuf); 3631 } 3632 #elif defined(HAVE_LIBZ) 3633 if (enable_compression) { 3634 strcat(buf, 3635 ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize="); 3636 char numbuf[16]; 3637 snprintf(numbuf, sizeof(numbuf), "%zu", m_compression_minsize); 3638 numbuf[sizeof(numbuf) - 1] = '\0'; 3639 strcat(buf, numbuf); 3640 } 3641 #endif 3642 3643 return SendPacket(buf); 3644 } 3645 3646 /* 3647 vAttach;pid 3648 3649 Attach to a new process with the specified process ID. pid is a hexadecimal 3650 integer 3651 identifying the process. If the stub is currently controlling a process, it is 3652 killed. The attached process is stopped.This packet is only available in 3653 extended 3654 mode (see extended mode). 3655 3656 Reply: 3657 "ENN" for an error 3658 "Any Stop Reply Packet" for success 3659 */ 3660 3661 rnb_err_t RNBRemote::HandlePacket_v(const char *p) { 3662 if (strcmp(p, "vCont;c") == 0) { 3663 // Simple continue 3664 return RNBRemote::HandlePacket_c("c"); 3665 } else if (strcmp(p, "vCont;s") == 0) { 3666 // Simple step 3667 return RNBRemote::HandlePacket_s("s"); 3668 } else if (strstr(p, "vCont") == p) { 3669 DNBThreadResumeActions thread_actions; 3670 char *c = const_cast<char *>(p += strlen("vCont")); 3671 char *c_end = c + strlen(c); 3672 if (*c == '?') 3673 return SendPacket("vCont;c;C;s;S"); 3674 3675 while (c < c_end && *c == ';') { 3676 ++c; // Skip the semi-colon 3677 DNBThreadResumeAction thread_action; 3678 thread_action.tid = INVALID_NUB_THREAD; 3679 thread_action.state = eStateInvalid; 3680 thread_action.signal = 0; 3681 thread_action.addr = INVALID_NUB_ADDRESS; 3682 3683 char action = *c++; 3684 3685 switch (action) { 3686 case 'C': 3687 errno = 0; 3688 thread_action.signal = static_cast<int>(strtoul(c, &c, 16)); 3689 if (errno != 0) 3690 return HandlePacket_ILLFORMED( 3691 __FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3692 // Fall through to next case... 3693 3694 case 'c': 3695 // Continue 3696 thread_action.state = eStateRunning; 3697 break; 3698 3699 case 'S': 3700 errno = 0; 3701 thread_action.signal = static_cast<int>(strtoul(c, &c, 16)); 3702 if (errno != 0) 3703 return HandlePacket_ILLFORMED( 3704 __FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3705 // Fall through to next case... 3706 3707 case 's': 3708 // Step 3709 thread_action.state = eStateStepping; 3710 break; 3711 3712 default: 3713 HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3714 "Unsupported action in vCont packet"); 3715 break; 3716 } 3717 if (*c == ':') { 3718 errno = 0; 3719 thread_action.tid = strtoul(++c, &c, 16); 3720 if (errno != 0) 3721 return HandlePacket_ILLFORMED( 3722 __FILE__, __LINE__, p, 3723 "Could not parse thread number in vCont packet"); 3724 } 3725 3726 thread_actions.Append(thread_action); 3727 } 3728 3729 // If a default action for all other threads wasn't mentioned 3730 // then we should stop the threads 3731 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3732 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst(), 3733 thread_actions.GetSize()); 3734 return rnb_success; 3735 } else if (strstr(p, "vAttach") == p) { 3736 nub_process_t attach_pid = 3737 INVALID_NUB_PROCESS; // attach_pid will be set to 0 if the attach fails 3738 nub_process_t pid_attaching_to = 3739 INVALID_NUB_PROCESS; // pid_attaching_to is the original pid specified 3740 char err_str[1024] = {'\0'}; 3741 std::string attach_name; 3742 3743 if (strstr(p, "vAttachWait;") == p) { 3744 p += strlen("vAttachWait;"); 3745 if (!GetProcessNameFrom_vAttach(p, attach_name)) { 3746 return HandlePacket_ILLFORMED( 3747 __FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 3748 } 3749 const bool ignore_existing = true; 3750 attach_pid = DNBProcessAttachWait( 3751 attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL, 3752 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3753 3754 } else if (strstr(p, "vAttachOrWait;") == p) { 3755 p += strlen("vAttachOrWait;"); 3756 if (!GetProcessNameFrom_vAttach(p, attach_name)) { 3757 return HandlePacket_ILLFORMED( 3758 __FILE__, __LINE__, p, 3759 "non-hex char in arg on 'vAttachOrWait' pkt"); 3760 } 3761 const bool ignore_existing = false; 3762 attach_pid = DNBProcessAttachWait( 3763 attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL, 3764 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3765 } else if (strstr(p, "vAttachName;") == p) { 3766 p += strlen("vAttachName;"); 3767 if (!GetProcessNameFrom_vAttach(p, attach_name)) { 3768 return HandlePacket_ILLFORMED( 3769 __FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 3770 } 3771 3772 attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL, err_str, 3773 sizeof(err_str)); 3774 3775 } else if (strstr(p, "vAttach;") == p) { 3776 p += strlen("vAttach;"); 3777 char *end = NULL; 3778 pid_attaching_to = static_cast<int>( 3779 strtoul(p, &end, 16)); // PID will be in hex, so use base 16 to decode 3780 if (p != end && *end == '\0') { 3781 // Wait at most 30 second for attach 3782 struct timespec attach_timeout_abstime; 3783 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 3784 attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime, 3785 err_str, sizeof(err_str)); 3786 } 3787 } else { 3788 return HandlePacket_UNIMPLEMENTED(p); 3789 } 3790 3791 if (attach_pid != INVALID_NUB_PROCESS) { 3792 if (m_ctx.ProcessID() != attach_pid) 3793 m_ctx.SetProcessID(attach_pid); 3794 // Send a stop reply packet to indicate we successfully attached! 3795 NotifyThatProcessStopped(); 3796 return rnb_success; 3797 } else { 3798 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3799 if (err_str[0]) 3800 m_ctx.LaunchStatus().SetErrorString(err_str); 3801 else 3802 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3803 3804 #if defined(__APPLE__) && \ 3805 (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000) 3806 if (pid_attaching_to == INVALID_NUB_PROCESS && !attach_name.empty()) { 3807 pid_attaching_to = DNBProcessGetPIDByName(attach_name.c_str()); 3808 } 3809 if (pid_attaching_to != INVALID_NUB_PROCESS && 3810 strcmp(err_str, "No such process") != 0) { 3811 // csr_check(CSR_ALLOW_TASK_FOR_PID) will be nonzero if System Integrity 3812 // Protection is in effect. 3813 if (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0) { 3814 bool attach_failed_due_to_sip = false; 3815 3816 if (rootless_allows_task_for_pid(pid_attaching_to) == 0) { 3817 attach_failed_due_to_sip = true; 3818 } 3819 3820 if (attach_failed_due_to_sip == false) { 3821 int csops_flags = 0; 3822 int retval = ::csops(pid_attaching_to, CS_OPS_STATUS, &csops_flags, 3823 sizeof(csops_flags)); 3824 if (retval != -1 && (csops_flags & CS_RESTRICT)) { 3825 attach_failed_due_to_sip = true; 3826 } 3827 } 3828 if (attach_failed_due_to_sip) { 3829 SendPacket("E87"); // E87 is the magic value which says that we are 3830 // not allowed to attach 3831 DNBLogError("Attach failed because process does not allow " 3832 "attaching: \"%s\".", 3833 err_str); 3834 return rnb_err; 3835 } 3836 } 3837 } 3838 3839 #endif 3840 3841 SendPacket("E01"); // E01 is our magic error value for attach failed. 3842 DNBLogError("Attach failed: \"%s\".", err_str); 3843 return rnb_err; 3844 } 3845 } 3846 3847 // All other failures come through here 3848 return HandlePacket_UNIMPLEMENTED(p); 3849 } 3850 3851 /* 'T XX' -- status of thread 3852 Check if the specified thread is alive. 3853 The thread number is in hex? */ 3854 3855 rnb_err_t RNBRemote::HandlePacket_T(const char *p) { 3856 p++; 3857 if (p == NULL || *p == '\0') { 3858 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3859 "No thread specified in T packet"); 3860 } 3861 if (!m_ctx.HasValidProcessID()) { 3862 return SendPacket("E15"); 3863 } 3864 errno = 0; 3865 nub_thread_t tid = strtoul(p, NULL, 16); 3866 if (errno != 0 && tid == 0) { 3867 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3868 "Could not parse thread number in T packet"); 3869 } 3870 3871 nub_state_t state = DNBThreadGetState(m_ctx.ProcessID(), tid); 3872 if (state == eStateInvalid || state == eStateExited || 3873 state == eStateCrashed) { 3874 return SendPacket("E16"); 3875 } 3876 3877 return SendPacket("OK"); 3878 } 3879 3880 rnb_err_t RNBRemote::HandlePacket_z(const char *p) { 3881 if (p == NULL || *p == '\0') 3882 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3883 "No thread specified in z packet"); 3884 3885 if (!m_ctx.HasValidProcessID()) 3886 return SendPacket("E15"); 3887 3888 char packet_cmd = *p++; 3889 char break_type = *p++; 3890 3891 if (*p++ != ',') 3892 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3893 "Comma separator missing in z packet"); 3894 3895 char *c = NULL; 3896 nub_process_t pid = m_ctx.ProcessID(); 3897 errno = 0; 3898 nub_addr_t addr = strtoull(p, &c, 16); 3899 if (errno != 0 && addr == 0) 3900 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3901 "Invalid address in z packet"); 3902 p = c; 3903 if (*p++ != ',') 3904 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3905 "Comma separator missing in z packet"); 3906 3907 errno = 0; 3908 auto byte_size = strtoul(p, &c, 16); 3909 if (errno != 0 && byte_size == 0) 3910 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 3911 "Invalid length in z packet"); 3912 3913 if (packet_cmd == 'Z') { 3914 // set 3915 switch (break_type) { 3916 case '0': // set software breakpoint 3917 case '1': // set hardware breakpoint 3918 { 3919 // gdb can send multiple Z packets for the same address and 3920 // these calls must be ref counted. 3921 bool hardware = (break_type == '1'); 3922 3923 if (DNBBreakpointSet(pid, addr, byte_size, hardware)) { 3924 // We successfully created a breakpoint, now lets full out 3925 // a ref count structure with the breakID and add it to our 3926 // map. 3927 return SendPacket("OK"); 3928 } else { 3929 // We failed to set the software breakpoint 3930 return SendPacket("E09"); 3931 } 3932 } break; 3933 3934 case '2': // set write watchpoint 3935 case '3': // set read watchpoint 3936 case '4': // set access watchpoint 3937 { 3938 bool hardware = true; 3939 uint32_t watch_flags = 0; 3940 if (break_type == '2') 3941 watch_flags = WATCH_TYPE_WRITE; 3942 else if (break_type == '3') 3943 watch_flags = WATCH_TYPE_READ; 3944 else 3945 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3946 3947 if (DNBWatchpointSet(pid, addr, byte_size, watch_flags, hardware)) { 3948 return SendPacket("OK"); 3949 } else { 3950 // We failed to set the watchpoint 3951 return SendPacket("E09"); 3952 } 3953 } break; 3954 3955 default: 3956 break; 3957 } 3958 } else if (packet_cmd == 'z') { 3959 // remove 3960 switch (break_type) { 3961 case '0': // remove software breakpoint 3962 case '1': // remove hardware breakpoint 3963 if (DNBBreakpointClear(pid, addr)) { 3964 return SendPacket("OK"); 3965 } else { 3966 return SendPacket("E08"); 3967 } 3968 break; 3969 3970 case '2': // remove write watchpoint 3971 case '3': // remove read watchpoint 3972 case '4': // remove access watchpoint 3973 if (DNBWatchpointClear(pid, addr)) { 3974 return SendPacket("OK"); 3975 } else { 3976 return SendPacket("E08"); 3977 } 3978 break; 3979 3980 default: 3981 break; 3982 } 3983 } 3984 return HandlePacket_UNIMPLEMENTED(p); 3985 } 3986 3987 // Extract the thread number from the thread suffix that might be appended to 3988 // thread specific packets. This will only be enabled if 3989 // m_thread_suffix_supported 3990 // is true. 3991 nub_thread_t RNBRemote::ExtractThreadIDFromThreadSuffix(const char *p) { 3992 if (m_thread_suffix_supported) { 3993 nub_thread_t tid = INVALID_NUB_THREAD; 3994 if (p) { 3995 const char *tid_cstr = strstr(p, "thread:"); 3996 if (tid_cstr) { 3997 tid_cstr += strlen("thread:"); 3998 tid = strtoul(tid_cstr, NULL, 16); 3999 } 4000 } 4001 return tid; 4002 } 4003 return GetCurrentThread(); 4004 } 4005 4006 /* 'p XX' 4007 print the contents of register X */ 4008 4009 rnb_err_t RNBRemote::HandlePacket_p(const char *p) { 4010 if (g_num_reg_entries == 0) 4011 InitializeRegisters(); 4012 4013 if (p == NULL || *p == '\0') { 4014 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4015 "No thread specified in p packet"); 4016 } 4017 if (!m_ctx.HasValidProcessID()) { 4018 return SendPacket("E15"); 4019 } 4020 nub_process_t pid = m_ctx.ProcessID(); 4021 errno = 0; 4022 char *tid_cstr = NULL; 4023 uint32_t reg = static_cast<uint32_t>(strtoul(p + 1, &tid_cstr, 16)); 4024 if (errno != 0 && reg == 0) { 4025 return HandlePacket_ILLFORMED( 4026 __FILE__, __LINE__, p, "Could not parse register number in p packet"); 4027 } 4028 4029 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(tid_cstr); 4030 if (tid == INVALID_NUB_THREAD) 4031 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4032 "No thread specified in p packet"); 4033 4034 const register_map_entry_t *reg_entry; 4035 4036 if (reg < g_num_reg_entries) 4037 reg_entry = &g_reg_entries[reg]; 4038 else 4039 reg_entry = NULL; 4040 4041 std::ostringstream ostrm; 4042 if (reg_entry == NULL) { 4043 DNBLogError( 4044 "RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", 4045 p, reg); 4046 ostrm << "00000000"; 4047 } else if (reg_entry->nub_info.reg == (uint32_t)-1) { 4048 if (reg_entry->nub_info.size > 0) { 4049 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 4050 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 4051 } 4052 } else { 4053 register_value_in_hex_fixed_width(ostrm, pid, tid, reg_entry, NULL); 4054 } 4055 return SendPacket(ostrm.str()); 4056 } 4057 4058 /* 'Pnn=rrrrr' 4059 Set register number n to value r. 4060 n and r are hex strings. */ 4061 4062 rnb_err_t RNBRemote::HandlePacket_P(const char *p) { 4063 if (g_num_reg_entries == 0) 4064 InitializeRegisters(); 4065 4066 if (p == NULL || *p == '\0') { 4067 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, "Empty P packet"); 4068 } 4069 if (!m_ctx.HasValidProcessID()) { 4070 return SendPacket("E28"); 4071 } 4072 4073 nub_process_t pid = m_ctx.ProcessID(); 4074 4075 StdStringExtractor packet(p); 4076 4077 const char cmd_char = packet.GetChar(); 4078 // Register ID is always in big endian 4079 const uint32_t reg = packet.GetHexMaxU32(false, UINT32_MAX); 4080 const char equal_char = packet.GetChar(); 4081 4082 if (cmd_char != 'P') 4083 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4084 "Improperly formed P packet"); 4085 4086 if (reg == UINT32_MAX) 4087 return SendPacket("E29"); 4088 4089 if (equal_char != '=') 4090 return SendPacket("E30"); 4091 4092 const register_map_entry_t *reg_entry; 4093 4094 if (reg >= g_num_reg_entries) 4095 return SendPacket("E47"); 4096 4097 reg_entry = &g_reg_entries[reg]; 4098 4099 if (reg_entry->nub_info.set == (uint32_t)-1 && 4100 reg_entry->nub_info.reg == (uint32_t)-1) { 4101 DNBLogError( 4102 "RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", 4103 p, reg); 4104 return SendPacket("E48"); 4105 } 4106 4107 DNBRegisterValue reg_value; 4108 reg_value.info = reg_entry->nub_info; 4109 packet.GetHexBytes(reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 4110 4111 nub_thread_t tid = ExtractThreadIDFromThreadSuffix(p); 4112 if (tid == INVALID_NUB_THREAD) 4113 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4114 "No thread specified in p packet"); 4115 4116 if (!DNBThreadSetRegisterValueByID(pid, tid, reg_entry->nub_info.set, 4117 reg_entry->nub_info.reg, ®_value)) { 4118 return SendPacket("E32"); 4119 } 4120 return SendPacket("OK"); 4121 } 4122 4123 /* 'c [addr]' 4124 Continue, optionally from a specified address. */ 4125 4126 rnb_err_t RNBRemote::HandlePacket_c(const char *p) { 4127 const nub_process_t pid = m_ctx.ProcessID(); 4128 4129 if (pid == INVALID_NUB_PROCESS) 4130 return SendPacket("E23"); 4131 4132 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, 4133 INVALID_NUB_ADDRESS}; 4134 4135 if (*(p + 1) != '\0') { 4136 action.tid = GetContinueThread(); 4137 errno = 0; 4138 action.addr = strtoull(p + 1, NULL, 16); 4139 if (errno != 0 && action.addr == 0) 4140 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4141 "Could not parse address in c packet"); 4142 } 4143 4144 DNBThreadResumeActions thread_actions; 4145 thread_actions.Append(action); 4146 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 4147 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4148 thread_actions.GetSize())) 4149 return SendPacket("E25"); 4150 // Don't send an "OK" packet; response is the stopped/exited message. 4151 return rnb_success; 4152 } 4153 4154 rnb_err_t RNBRemote::HandlePacket_MemoryRegionInfo(const char *p) { 4155 /* This packet will find memory attributes (e.g. readable, writable, 4156 executable, stack, jitted code) 4157 for the memory region containing a given address and return that 4158 information. 4159 4160 Users of this packet must be prepared for three results: 4161 4162 Region information is returned 4163 Region information is unavailable for this address because the address 4164 is in unmapped memory 4165 Region lookup cannot be performed on this platform or process is not 4166 yet launched 4167 This packet isn't implemented 4168 4169 Examples of use: 4170 qMemoryRegionInfo:3a55140 4171 start:3a50000,size:100000,permissions:rwx 4172 4173 qMemoryRegionInfo:0 4174 error:address in unmapped region 4175 4176 qMemoryRegionInfo:3a551140 (on a different platform) 4177 error:region lookup cannot be performed 4178 4179 qMemoryRegionInfo 4180 OK // this packet is implemented by the remote nub 4181 */ 4182 4183 p += sizeof("qMemoryRegionInfo") - 1; 4184 if (*p == '\0') 4185 return SendPacket("OK"); 4186 if (*p++ != ':') 4187 return SendPacket("E67"); 4188 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 4189 p += 2; 4190 4191 errno = 0; 4192 uint64_t address = strtoul(p, NULL, 16); 4193 if (errno != 0 && address == 0) { 4194 return HandlePacket_ILLFORMED( 4195 __FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 4196 } 4197 4198 DNBRegionInfo region_info = {0, 0, 0}; 4199 DNBProcessMemoryRegionInfo(m_ctx.ProcessID(), address, ®ion_info); 4200 std::ostringstream ostrm; 4201 4202 // start:3a50000,size:100000,permissions:rwx 4203 ostrm << "start:" << std::hex << region_info.addr << ';'; 4204 4205 if (region_info.size > 0) 4206 ostrm << "size:" << std::hex << region_info.size << ';'; 4207 4208 if (region_info.permissions) { 4209 ostrm << "permissions:"; 4210 4211 if (region_info.permissions & eMemoryPermissionsReadable) 4212 ostrm << 'r'; 4213 if (region_info.permissions & eMemoryPermissionsWritable) 4214 ostrm << 'w'; 4215 if (region_info.permissions & eMemoryPermissionsExecutable) 4216 ostrm << 'x'; 4217 ostrm << ';'; 4218 } 4219 return SendPacket(ostrm.str()); 4220 } 4221 4222 // qGetProfileData;scan_type:0xYYYYYYY 4223 rnb_err_t RNBRemote::HandlePacket_GetProfileData(const char *p) { 4224 nub_process_t pid = m_ctx.ProcessID(); 4225 if (pid == INVALID_NUB_PROCESS) 4226 return SendPacket("OK"); 4227 4228 StdStringExtractor packet(p += sizeof("qGetProfileData")); 4229 DNBProfileDataScanType scan_type = eProfileAll; 4230 std::string name; 4231 std::string value; 4232 while (packet.GetNameColonValue(name, value)) { 4233 if (name.compare("scan_type") == 0) { 4234 std::istringstream iss(value); 4235 uint32_t int_value = 0; 4236 if (iss >> std::hex >> int_value) { 4237 scan_type = (DNBProfileDataScanType)int_value; 4238 } 4239 } 4240 } 4241 4242 std::string data = DNBProcessGetProfileData(pid, scan_type); 4243 if (!data.empty()) { 4244 return SendPacket(data.c_str()); 4245 } else { 4246 return SendPacket("OK"); 4247 } 4248 } 4249 4250 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 4251 rnb_err_t RNBRemote::HandlePacket_SetEnableAsyncProfiling(const char *p) { 4252 nub_process_t pid = m_ctx.ProcessID(); 4253 if (pid == INVALID_NUB_PROCESS) 4254 return SendPacket("OK"); 4255 4256 StdStringExtractor packet(p += sizeof("QSetEnableAsyncProfiling")); 4257 bool enable = false; 4258 uint64_t interval_usec = 0; 4259 DNBProfileDataScanType scan_type = eProfileAll; 4260 std::string name; 4261 std::string value; 4262 while (packet.GetNameColonValue(name, value)) { 4263 if (name.compare("enable") == 0) { 4264 enable = strtoul(value.c_str(), NULL, 10) > 0; 4265 } else if (name.compare("interval_usec") == 0) { 4266 interval_usec = strtoul(value.c_str(), NULL, 10); 4267 } else if (name.compare("scan_type") == 0) { 4268 std::istringstream iss(value); 4269 uint32_t int_value = 0; 4270 if (iss >> std::hex >> int_value) { 4271 scan_type = (DNBProfileDataScanType)int_value; 4272 } 4273 } 4274 } 4275 4276 if (interval_usec == 0) { 4277 enable = 0; 4278 } 4279 4280 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 4281 return SendPacket("OK"); 4282 } 4283 4284 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO 4285 // COMPRESS>; 4286 // 4287 // type: must be a type previously reported by the qXfer:features: 4288 // SupportedCompressions list 4289 // 4290 // minsize: is optional; by default the qXfer:features: 4291 // DefaultCompressionMinSize value is used 4292 // debugserver may have a better idea of what a good minimum packet size to 4293 // compress is than lldb. 4294 4295 rnb_err_t RNBRemote::HandlePacket_QEnableCompression(const char *p) { 4296 p += sizeof("QEnableCompression:") - 1; 4297 4298 size_t new_compression_minsize = m_compression_minsize; 4299 const char *new_compression_minsize_str = strstr(p, "minsize:"); 4300 if (new_compression_minsize_str) { 4301 new_compression_minsize_str += strlen("minsize:"); 4302 errno = 0; 4303 new_compression_minsize = strtoul(new_compression_minsize_str, NULL, 10); 4304 if (errno != 0 || new_compression_minsize == ULONG_MAX) { 4305 new_compression_minsize = m_compression_minsize; 4306 } 4307 } 4308 4309 #if defined(HAVE_LIBCOMPRESSION) 4310 if (strstr(p, "type:zlib-deflate;") != nullptr) { 4311 EnableCompressionNextSendPacket(compression_types::zlib_deflate); 4312 m_compression_minsize = new_compression_minsize; 4313 return SendPacket("OK"); 4314 } else if (strstr(p, "type:lz4;") != nullptr) { 4315 EnableCompressionNextSendPacket(compression_types::lz4); 4316 m_compression_minsize = new_compression_minsize; 4317 return SendPacket("OK"); 4318 } else if (strstr(p, "type:lzma;") != nullptr) { 4319 EnableCompressionNextSendPacket(compression_types::lzma); 4320 m_compression_minsize = new_compression_minsize; 4321 return SendPacket("OK"); 4322 } else if (strstr(p, "type:lzfse;") != nullptr) { 4323 EnableCompressionNextSendPacket(compression_types::lzfse); 4324 m_compression_minsize = new_compression_minsize; 4325 return SendPacket("OK"); 4326 } 4327 #endif 4328 4329 #if defined(HAVE_LIBZ) 4330 if (strstr(p, "type:zlib-deflate;") != nullptr) { 4331 EnableCompressionNextSendPacket(compression_types::zlib_deflate); 4332 m_compression_minsize = new_compression_minsize; 4333 return SendPacket("OK"); 4334 } 4335 #endif 4336 4337 return SendPacket("E88"); 4338 } 4339 4340 rnb_err_t RNBRemote::HandlePacket_qSpeedTest(const char *p) { 4341 p += strlen("qSpeedTest:response_size:"); 4342 char *end = NULL; 4343 errno = 0; 4344 uint64_t response_size = ::strtoul(p, &end, 16); 4345 if (errno != 0) 4346 return HandlePacket_ILLFORMED( 4347 __FILE__, __LINE__, p, 4348 "Didn't find response_size value at right offset"); 4349 else if (*end == ';') { 4350 static char g_data[4 * 1024 * 1024 + 16] = "data:"; 4351 memset(g_data + 5, 'a', response_size); 4352 g_data[response_size + 5] = '\0'; 4353 return SendPacket(g_data); 4354 } else { 4355 return SendPacket("E79"); 4356 } 4357 } 4358 4359 rnb_err_t RNBRemote::HandlePacket_WatchpointSupportInfo(const char *p) { 4360 /* This packet simply returns the number of supported hardware watchpoints. 4361 4362 Examples of use: 4363 qWatchpointSupportInfo: 4364 num:4 4365 4366 qWatchpointSupportInfo 4367 OK // this packet is implemented by the remote nub 4368 */ 4369 4370 p += sizeof("qWatchpointSupportInfo") - 1; 4371 if (*p == '\0') 4372 return SendPacket("OK"); 4373 if (*p++ != ':') 4374 return SendPacket("E67"); 4375 4376 errno = 0; 4377 uint32_t num = DNBWatchpointGetNumSupportedHWP(m_ctx.ProcessID()); 4378 std::ostringstream ostrm; 4379 4380 // size:4 4381 ostrm << "num:" << std::dec << num << ';'; 4382 return SendPacket(ostrm.str()); 4383 } 4384 4385 /* 'C sig [;addr]' 4386 Resume with signal sig, optionally at address addr. */ 4387 4388 rnb_err_t RNBRemote::HandlePacket_C(const char *p) { 4389 const nub_process_t pid = m_ctx.ProcessID(); 4390 4391 if (pid == INVALID_NUB_PROCESS) 4392 return SendPacket("E36"); 4393 4394 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateRunning, 0, 4395 INVALID_NUB_ADDRESS}; 4396 int process_signo = -1; 4397 if (*(p + 1) != '\0') { 4398 action.tid = GetContinueThread(); 4399 char *end = NULL; 4400 errno = 0; 4401 process_signo = static_cast<int>(strtoul(p + 1, &end, 16)); 4402 if (errno != 0) 4403 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4404 "Could not parse signal in C packet"); 4405 else if (*end == ';') { 4406 errno = 0; 4407 action.addr = strtoull(end + 1, NULL, 16); 4408 if (errno != 0 && action.addr == 0) 4409 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4410 "Could not parse address in C packet"); 4411 } 4412 } 4413 4414 DNBThreadResumeActions thread_actions; 4415 thread_actions.Append(action); 4416 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, action.signal); 4417 if (!DNBProcessSignal(pid, process_signo)) 4418 return SendPacket("E52"); 4419 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4420 thread_actions.GetSize())) 4421 return SendPacket("E38"); 4422 /* Don't send an "OK" packet; response is the stopped/exited message. */ 4423 return rnb_success; 4424 } 4425 4426 //---------------------------------------------------------------------- 4427 // 'D' packet 4428 // Detach from gdb. 4429 //---------------------------------------------------------------------- 4430 rnb_err_t RNBRemote::HandlePacket_D(const char *p) { 4431 if (m_ctx.HasValidProcessID()) { 4432 if (DNBProcessDetach(m_ctx.ProcessID())) 4433 SendPacket("OK"); 4434 else 4435 SendPacket("E"); 4436 } else { 4437 SendPacket("E"); 4438 } 4439 return rnb_success; 4440 } 4441 4442 /* 'k' 4443 Kill the inferior process. */ 4444 4445 rnb_err_t RNBRemote::HandlePacket_k(const char *p) { 4446 DNBLog("Got a 'k' packet, killing the inferior process."); 4447 // No response to should be sent to the kill packet 4448 if (m_ctx.HasValidProcessID()) 4449 DNBProcessKill(m_ctx.ProcessID()); 4450 SendPacket("X09"); 4451 return rnb_success; 4452 } 4453 4454 rnb_err_t RNBRemote::HandlePacket_stop_process(const char *p) { 4455 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test 4456 //exiting on interrupt 4457 #if defined(TEST_EXIT_ON_INTERRUPT) 4458 rnb_err_t err = HandlePacket_k(p); 4459 m_comm.Disconnect(true); 4460 return err; 4461 #else 4462 if (!DNBProcessInterrupt(m_ctx.ProcessID())) { 4463 // If we failed to interrupt the process, then send a stop 4464 // reply packet as the process was probably already stopped 4465 DNBLogThreaded("RNBRemote::HandlePacket_stop_process() sending extra stop " 4466 "reply because DNBProcessInterrupt returned false"); 4467 HandlePacket_last_signal(NULL); 4468 } 4469 return rnb_success; 4470 #endif 4471 } 4472 4473 /* 's' 4474 Step the inferior process. */ 4475 4476 rnb_err_t RNBRemote::HandlePacket_s(const char *p) { 4477 const nub_process_t pid = m_ctx.ProcessID(); 4478 if (pid == INVALID_NUB_PROCESS) 4479 return SendPacket("E32"); 4480 4481 // Hardware supported stepping not supported on arm 4482 nub_thread_t tid = GetContinueThread(); 4483 if (tid == 0 || tid == (nub_thread_t)-1) 4484 tid = GetCurrentThread(); 4485 4486 if (tid == INVALID_NUB_THREAD) 4487 return SendPacket("E33"); 4488 4489 DNBThreadResumeActions thread_actions; 4490 thread_actions.AppendAction(tid, eStateStepping); 4491 4492 // Make all other threads stop when we are stepping 4493 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4494 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4495 thread_actions.GetSize())) 4496 return SendPacket("E49"); 4497 // Don't send an "OK" packet; response is the stopped/exited message. 4498 return rnb_success; 4499 } 4500 4501 /* 'S sig [;addr]' 4502 Step with signal sig, optionally at address addr. */ 4503 4504 rnb_err_t RNBRemote::HandlePacket_S(const char *p) { 4505 const nub_process_t pid = m_ctx.ProcessID(); 4506 if (pid == INVALID_NUB_PROCESS) 4507 return SendPacket("E36"); 4508 4509 DNBThreadResumeAction action = {INVALID_NUB_THREAD, eStateStepping, 0, 4510 INVALID_NUB_ADDRESS}; 4511 4512 if (*(p + 1) != '\0') { 4513 char *end = NULL; 4514 errno = 0; 4515 action.signal = static_cast<int>(strtoul(p + 1, &end, 16)); 4516 if (errno != 0) 4517 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4518 "Could not parse signal in S packet"); 4519 else if (*end == ';') { 4520 errno = 0; 4521 action.addr = strtoull(end + 1, NULL, 16); 4522 if (errno != 0 && action.addr == 0) { 4523 return HandlePacket_ILLFORMED(__FILE__, __LINE__, p, 4524 "Could not parse address in S packet"); 4525 } 4526 } 4527 } 4528 4529 action.tid = GetContinueThread(); 4530 if (action.tid == 0 || action.tid == (nub_thread_t)-1) 4531 return SendPacket("E40"); 4532 4533 nub_state_t tstate = DNBThreadGetState(pid, action.tid); 4534 if (tstate == eStateInvalid || tstate == eStateExited) 4535 return SendPacket("E37"); 4536 4537 DNBThreadResumeActions thread_actions; 4538 thread_actions.Append(action); 4539 4540 // Make all other threads stop when we are stepping 4541 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4542 if (!DNBProcessResume(pid, thread_actions.GetFirst(), 4543 thread_actions.GetSize())) 4544 return SendPacket("E39"); 4545 4546 // Don't send an "OK" packet; response is the stopped/exited message. 4547 return rnb_success; 4548 } 4549 4550 static const char *GetArchName(const uint32_t cputype, 4551 const uint32_t cpusubtype) { 4552 switch (cputype) { 4553 case CPU_TYPE_ARM: 4554 switch (cpusubtype) { 4555 case 5: 4556 return "armv4"; 4557 case 6: 4558 return "armv6"; 4559 case 7: 4560 return "armv5t"; 4561 case 8: 4562 return "xscale"; 4563 case 9: 4564 return "armv7"; 4565 case 10: 4566 return "armv7f"; 4567 case 11: 4568 return "armv7s"; 4569 case 12: 4570 return "armv7k"; 4571 case 14: 4572 return "armv6m"; 4573 case 15: 4574 return "armv7m"; 4575 case 16: 4576 return "armv7em"; 4577 default: 4578 return "arm"; 4579 } 4580 break; 4581 case CPU_TYPE_ARM64: 4582 return "arm64"; 4583 case CPU_TYPE_I386: 4584 return "i386"; 4585 case CPU_TYPE_X86_64: 4586 switch (cpusubtype) { 4587 default: 4588 return "x86_64"; 4589 case 8: 4590 return "x86_64h"; 4591 } 4592 break; 4593 } 4594 return NULL; 4595 } 4596 4597 static bool GetHostCPUType(uint32_t &cputype, uint32_t &cpusubtype, 4598 uint32_t &is_64_bit_capable, bool &promoted_to_64) { 4599 static uint32_t g_host_cputype = 0; 4600 static uint32_t g_host_cpusubtype = 0; 4601 static uint32_t g_is_64_bit_capable = 0; 4602 static bool g_promoted_to_64 = false; 4603 4604 if (g_host_cputype == 0) { 4605 g_promoted_to_64 = false; 4606 size_t len = sizeof(uint32_t); 4607 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) { 4608 len = sizeof(uint32_t); 4609 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, 4610 NULL, 0) == 0) { 4611 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) { 4612 g_promoted_to_64 = true; 4613 g_host_cputype |= CPU_ARCH_ABI64; 4614 } 4615 } 4616 } 4617 4618 len = sizeof(uint32_t); 4619 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 4620 0) { 4621 if (g_promoted_to_64 && g_host_cputype == CPU_TYPE_X86_64 && 4622 g_host_cpusubtype == CPU_SUBTYPE_486) 4623 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4624 } 4625 } 4626 4627 cputype = g_host_cputype; 4628 cpusubtype = g_host_cpusubtype; 4629 is_64_bit_capable = g_is_64_bit_capable; 4630 promoted_to_64 = g_promoted_to_64; 4631 return g_host_cputype != 0; 4632 } 4633 4634 rnb_err_t RNBRemote::HandlePacket_qHostInfo(const char *p) { 4635 std::ostringstream strm; 4636 4637 uint32_t cputype = 0; 4638 uint32_t cpusubtype = 0; 4639 uint32_t is_64_bit_capable = 0; 4640 bool promoted_to_64 = false; 4641 if (GetHostCPUType(cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) { 4642 strm << "cputype:" << std::dec << cputype << ';'; 4643 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4644 } 4645 4646 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4647 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4648 // this for now. 4649 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) { 4650 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 4651 strm << "ostype:tvos;"; 4652 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4653 strm << "ostype:watchos;"; 4654 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 4655 strm << "ostype:bridgeos;"; 4656 #else 4657 strm << "ostype:ios;"; 4658 #endif 4659 4660 // On armv7 we use "synchronous" watchpoints which means the exception is 4661 // delivered before the instruction executes. 4662 strm << "watchpoint_exceptions_received:before;"; 4663 } else { 4664 strm << "ostype:macosx;"; 4665 strm << "watchpoint_exceptions_received:after;"; 4666 } 4667 // char ostype[64]; 4668 // len = sizeof(ostype); 4669 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4670 // { 4671 // len = strlen(ostype); 4672 // std::transform (ostype, ostype + len, ostype, tolower); 4673 // strm << "ostype:" << std::dec << ostype << ';'; 4674 // } 4675 4676 strm << "vendor:apple;"; 4677 4678 uint64_t major, minor, patch; 4679 if (DNBGetOSVersionNumbers(&major, &minor, &patch)) { 4680 strm << "os_version:" << major << "." << minor; 4681 if (patch != UINT64_MAX) 4682 strm << "." << patch; 4683 strm << ";"; 4684 } 4685 4686 #if defined(__LITTLE_ENDIAN__) 4687 strm << "endian:little;"; 4688 #elif defined(__BIG_ENDIAN__) 4689 strm << "endian:big;"; 4690 #elif defined(__PDP_ENDIAN__) 4691 strm << "endian:pdp;"; 4692 #endif 4693 4694 if (promoted_to_64) 4695 strm << "ptrsize:8;"; 4696 else 4697 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4698 4699 #if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4700 strm << "default_packet_timeout:10;"; 4701 #endif 4702 4703 return SendPacket(strm.str()); 4704 } 4705 4706 void XMLElementStart(std::ostringstream &s, uint32_t indent, const char *name, 4707 bool has_attributes) { 4708 if (indent) 4709 s << INDENT_WITH_SPACES(indent); 4710 s << '<' << name; 4711 if (!has_attributes) 4712 s << '>' << std::endl; 4713 } 4714 4715 void XMLElementStartEndAttributes(std::ostringstream &s, bool empty) { 4716 if (empty) 4717 s << '/'; 4718 s << '>' << std::endl; 4719 } 4720 4721 void XMLElementEnd(std::ostringstream &s, uint32_t indent, const char *name) { 4722 if (indent) 4723 s << INDENT_WITH_SPACES(indent); 4724 s << '<' << '/' << name << '>' << std::endl; 4725 } 4726 4727 void XMLElementWithStringValue(std::ostringstream &s, uint32_t indent, 4728 const char *name, const char *value, 4729 bool close = true) { 4730 if (value) { 4731 if (indent) 4732 s << INDENT_WITH_SPACES(indent); 4733 s << '<' << name << '>' << value; 4734 if (close) 4735 XMLElementEnd(s, 0, name); 4736 } 4737 } 4738 4739 void XMLElementWithUnsignedValue(std::ostringstream &s, uint32_t indent, 4740 const char *name, uint64_t value, 4741 bool close = true) { 4742 if (indent) 4743 s << INDENT_WITH_SPACES(indent); 4744 4745 s << '<' << name << '>' << DECIMAL << value; 4746 if (close) 4747 XMLElementEnd(s, 0, name); 4748 } 4749 4750 void XMLAttributeString(std::ostringstream &s, const char *name, 4751 const char *value, const char *default_value = NULL) { 4752 if (value) { 4753 if (default_value && strcmp(value, default_value) == 0) 4754 return; // No need to emit the attribute because it matches the default 4755 // value 4756 s << ' ' << name << "=\"" << value << "\""; 4757 } 4758 } 4759 4760 void XMLAttributeUnsignedDecimal(std::ostringstream &s, const char *name, 4761 uint64_t value) { 4762 s << ' ' << name << "=\"" << DECIMAL << value << "\""; 4763 } 4764 4765 void GenerateTargetXMLRegister(std::ostringstream &s, const uint32_t reg_num, 4766 nub_size_t num_reg_sets, 4767 const DNBRegisterSetInfo *reg_set_info, 4768 const register_map_entry_t ®) { 4769 const char *default_lldb_encoding = "uint"; 4770 const char *lldb_encoding = default_lldb_encoding; 4771 const char *gdb_group = "general"; 4772 const char *default_gdb_type = "int"; 4773 const char *gdb_type = default_gdb_type; 4774 const char *default_lldb_format = "hex"; 4775 const char *lldb_format = default_lldb_format; 4776 const char *lldb_set = NULL; 4777 4778 switch (reg.nub_info.type) { 4779 case Uint: 4780 lldb_encoding = "uint"; 4781 break; 4782 case Sint: 4783 lldb_encoding = "sint"; 4784 break; 4785 case IEEE754: 4786 lldb_encoding = "ieee754"; 4787 if (reg.nub_info.set > 0) 4788 gdb_group = "float"; 4789 break; 4790 case Vector: 4791 lldb_encoding = "vector"; 4792 if (reg.nub_info.set > 0) 4793 gdb_group = "vector"; 4794 break; 4795 } 4796 4797 switch (reg.nub_info.format) { 4798 case Binary: 4799 lldb_format = "binary"; 4800 break; 4801 case Decimal: 4802 lldb_format = "decimal"; 4803 break; 4804 case Hex: 4805 lldb_format = "hex"; 4806 break; 4807 case Float: 4808 gdb_type = "float"; 4809 lldb_format = "float"; 4810 break; 4811 case VectorOfSInt8: 4812 gdb_type = "float"; 4813 lldb_format = "vector-sint8"; 4814 break; 4815 case VectorOfUInt8: 4816 gdb_type = "float"; 4817 lldb_format = "vector-uint8"; 4818 break; 4819 case VectorOfSInt16: 4820 gdb_type = "float"; 4821 lldb_format = "vector-sint16"; 4822 break; 4823 case VectorOfUInt16: 4824 gdb_type = "float"; 4825 lldb_format = "vector-uint16"; 4826 break; 4827 case VectorOfSInt32: 4828 gdb_type = "float"; 4829 lldb_format = "vector-sint32"; 4830 break; 4831 case VectorOfUInt32: 4832 gdb_type = "float"; 4833 lldb_format = "vector-uint32"; 4834 break; 4835 case VectorOfFloat32: 4836 gdb_type = "float"; 4837 lldb_format = "vector-float32"; 4838 break; 4839 case VectorOfUInt128: 4840 gdb_type = "float"; 4841 lldb_format = "vector-uint128"; 4842 break; 4843 }; 4844 if (reg_set_info && reg.nub_info.set < num_reg_sets) 4845 lldb_set = reg_set_info[reg.nub_info.set].name; 4846 4847 uint32_t indent = 2; 4848 4849 XMLElementStart(s, indent, "reg", true); 4850 XMLAttributeString(s, "name", reg.nub_info.name); 4851 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 4852 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 4853 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 4854 XMLAttributeString(s, "group", gdb_group); 4855 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 4856 XMLAttributeString(s, "altname", reg.nub_info.alt); 4857 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 4858 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 4859 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 4860 if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM) 4861 XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe); 4862 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 4863 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 4864 4865 const char *lldb_generic = NULL; 4866 switch (reg.nub_info.reg_generic) { 4867 case GENERIC_REGNUM_FP: 4868 lldb_generic = "fp"; 4869 break; 4870 case GENERIC_REGNUM_PC: 4871 lldb_generic = "pc"; 4872 break; 4873 case GENERIC_REGNUM_SP: 4874 lldb_generic = "sp"; 4875 break; 4876 case GENERIC_REGNUM_RA: 4877 lldb_generic = "ra"; 4878 break; 4879 case GENERIC_REGNUM_FLAGS: 4880 lldb_generic = "flags"; 4881 break; 4882 case GENERIC_REGNUM_ARG1: 4883 lldb_generic = "arg1"; 4884 break; 4885 case GENERIC_REGNUM_ARG2: 4886 lldb_generic = "arg2"; 4887 break; 4888 case GENERIC_REGNUM_ARG3: 4889 lldb_generic = "arg3"; 4890 break; 4891 case GENERIC_REGNUM_ARG4: 4892 lldb_generic = "arg4"; 4893 break; 4894 case GENERIC_REGNUM_ARG5: 4895 lldb_generic = "arg5"; 4896 break; 4897 case GENERIC_REGNUM_ARG6: 4898 lldb_generic = "arg6"; 4899 break; 4900 case GENERIC_REGNUM_ARG7: 4901 lldb_generic = "arg7"; 4902 break; 4903 case GENERIC_REGNUM_ARG8: 4904 lldb_generic = "arg8"; 4905 break; 4906 default: 4907 break; 4908 } 4909 XMLAttributeString(s, "generic", lldb_generic); 4910 4911 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 4912 if (!empty) { 4913 if (!reg.value_regnums.empty()) { 4914 std::ostringstream regnums; 4915 bool first = true; 4916 regnums << DECIMAL; 4917 for (auto regnum : reg.value_regnums) { 4918 if (!first) 4919 regnums << ','; 4920 regnums << regnum; 4921 first = false; 4922 } 4923 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 4924 } 4925 4926 if (!reg.invalidate_regnums.empty()) { 4927 std::ostringstream regnums; 4928 bool first = true; 4929 regnums << DECIMAL; 4930 for (auto regnum : reg.invalidate_regnums) { 4931 if (!first) 4932 regnums << ','; 4933 regnums << regnum; 4934 first = false; 4935 } 4936 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 4937 } 4938 } 4939 XMLElementStartEndAttributes(s, true); 4940 } 4941 4942 void GenerateTargetXMLRegisters(std::ostringstream &s) { 4943 nub_size_t num_reg_sets = 0; 4944 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo(&num_reg_sets); 4945 4946 uint32_t cputype = DNBGetRegisterCPUType(); 4947 if (cputype) { 4948 XMLElementStart(s, 0, "feature", true); 4949 std::ostringstream name_strm; 4950 name_strm << "com.apple.debugserver." << GetArchName(cputype, 0); 4951 XMLAttributeString(s, "name", name_strm.str().c_str()); 4952 XMLElementStartEndAttributes(s, false); 4953 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 4954 // for (const auto ®: g_dynamic_register_map) 4955 { 4956 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, 4957 g_reg_entries[reg_num]); 4958 } 4959 XMLElementEnd(s, 0, "feature"); 4960 4961 if (num_reg_sets > 0) { 4962 XMLElementStart(s, 0, "groups", false); 4963 for (uint32_t set = 1; set < num_reg_sets; ++set) { 4964 XMLElementStart(s, 2, "group", true); 4965 XMLAttributeUnsignedDecimal(s, "id", set); 4966 XMLAttributeString(s, "name", reg_sets[set].name); 4967 XMLElementStartEndAttributes(s, true); 4968 } 4969 XMLElementEnd(s, 0, "groups"); 4970 } 4971 } 4972 } 4973 4974 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 4975 <target version="1.0">)"; 4976 4977 static const char *g_target_xml_footer = "</target>"; 4978 4979 static std::string g_target_xml; 4980 4981 void UpdateTargetXML() { 4982 std::ostringstream s; 4983 s << g_target_xml_header << std::endl; 4984 4985 // Set the architecture 4986 // 4987 // On raw targets (no OS, vendor info), I've seen replies like 4988 // <architecture>i386:x86-64</architecture> (for x86_64 systems - from vmware) 4989 // <architecture>arm</architecture> (for an unspecified arm device - from a Segger JLink) 4990 // For good interop, I'm not sure what's expected here. e.g. will anyone understand 4991 // <architecture>x86_64</architecture> ? Or is i386:x86_64 the expected phrasing? 4992 // 4993 // s << "<architecture>" << arch "</architecture>" << std::endl; 4994 4995 // Set the OSABI 4996 // s << "<osabi>abi-name</osabi>" 4997 4998 GenerateTargetXMLRegisters(s); 4999 5000 s << g_target_xml_footer << std::endl; 5001 5002 // Save the XML output in case it gets retrieved in chunks 5003 g_target_xml = s.str(); 5004 } 5005 5006 rnb_err_t RNBRemote::HandlePacket_qXfer(const char *command) { 5007 const char *p = command; 5008 p += strlen("qXfer:"); 5009 const char *sep = strchr(p, ':'); 5010 if (sep) { 5011 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 5012 p = sep + 1; 5013 sep = strchr(p, ':'); 5014 if (sep) { 5015 std::string rw(p, sep - p); // "read" or "write" 5016 p = sep + 1; 5017 sep = strchr(p, ':'); 5018 if (sep) { 5019 std::string annex(p, sep - p); // "read" or "write" 5020 5021 p = sep + 1; 5022 sep = strchr(p, ','); 5023 if (sep) { 5024 std::string offset_str(p, sep - p); // read the length as a string 5025 p = sep + 1; 5026 std::string length_str(p); // read the offset as a string 5027 char *end = nullptr; 5028 const uint64_t offset = strtoul(offset_str.c_str(), &end, 5029 16); // convert offset_str to a offset 5030 if (*end == '\0') { 5031 const uint64_t length = strtoul( 5032 length_str.c_str(), &end, 16); // convert length_str to a length 5033 if (*end == '\0') { 5034 if (object == "features" && rw == "read" && 5035 annex == "target.xml") { 5036 std::ostringstream xml_out; 5037 5038 if (offset == 0) { 5039 InitializeRegisters(true); 5040 5041 UpdateTargetXML(); 5042 if (g_target_xml.empty()) 5043 return SendPacket("E83"); 5044 5045 if (length > g_target_xml.size()) { 5046 xml_out << 'l'; // No more data 5047 xml_out << binary_encode_string(g_target_xml); 5048 } else { 5049 xml_out << 'm'; // More data needs to be read with a 5050 // subsequent call 5051 xml_out << binary_encode_string( 5052 std::string(g_target_xml, offset, length)); 5053 } 5054 } else { 5055 // Retrieving target XML in chunks 5056 if (offset < g_target_xml.size()) { 5057 std::string chunk(g_target_xml, offset, length); 5058 if (chunk.size() < length) 5059 xml_out << 'l'; // No more data 5060 else 5061 xml_out << 'm'; // More data needs to be read with a 5062 // subsequent call 5063 xml_out << binary_encode_string(chunk.data()); 5064 } 5065 } 5066 return SendPacket(xml_out.str()); 5067 } 5068 // Well formed, put not supported 5069 return HandlePacket_UNIMPLEMENTED(command); 5070 } 5071 } 5072 } 5073 } else { 5074 SendPacket("E85"); 5075 } 5076 } else { 5077 SendPacket("E86"); 5078 } 5079 } 5080 return SendPacket("E82"); 5081 } 5082 5083 rnb_err_t RNBRemote::HandlePacket_qGDBServerVersion(const char *p) { 5084 std::ostringstream strm; 5085 5086 #if defined(DEBUGSERVER_PROGRAM_NAME) 5087 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 5088 #else 5089 strm << "name:debugserver;"; 5090 #endif 5091 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 5092 5093 return SendPacket(strm.str()); 5094 } 5095 5096 // A helper function that retrieves a single integer value from 5097 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5098 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 5099 // 5100 uint64_t get_integer_value_for_key_name_from_json(const char *key, 5101 const char *json_string) { 5102 uint64_t retval = INVALID_NUB_ADDRESS; 5103 std::string key_with_quotes = "\""; 5104 key_with_quotes += key; 5105 key_with_quotes += "\""; 5106 const char *c = strstr(json_string, key_with_quotes.c_str()); 5107 if (c) { 5108 c += key_with_quotes.size(); 5109 5110 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5111 c++; 5112 5113 if (*c == ':') { 5114 c++; 5115 5116 while (*c != '\0' && 5117 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5118 c++; 5119 5120 errno = 0; 5121 retval = strtoul(c, NULL, 10); 5122 if (errno != 0) { 5123 retval = INVALID_NUB_ADDRESS; 5124 } 5125 } 5126 } 5127 return retval; 5128 } 5129 5130 // A helper function that retrieves a boolean value from 5131 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5132 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}] 5133 5134 // Returns true if it was able to find the key name, and sets the 'value' 5135 // argument to the value found. 5136 5137 bool get_boolean_value_for_key_name_from_json(const char *key, 5138 const char *json_string, 5139 bool &value) { 5140 std::string key_with_quotes = "\""; 5141 key_with_quotes += key; 5142 key_with_quotes += "\""; 5143 const char *c = strstr(json_string, key_with_quotes.c_str()); 5144 if (c) { 5145 c += key_with_quotes.size(); 5146 5147 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5148 c++; 5149 5150 if (*c == ':') { 5151 c++; 5152 5153 while (*c != '\0' && 5154 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5155 c++; 5156 5157 if (strncmp(c, "true", 4) == 0) { 5158 value = true; 5159 return true; 5160 } else if (strncmp(c, "false", 5) == 0) { 5161 value = false; 5162 return true; 5163 } 5164 } 5165 } 5166 return false; 5167 } 5168 5169 // A helper function that reads an array of uint64_t's from 5170 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5171 // jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}] 5172 5173 // Returns true if it was able to find the key name, false if it did not. 5174 // "ints" will have all integers found in the array appended to it. 5175 5176 bool get_array_of_ints_value_for_key_name_from_json( 5177 const char *key, const char *json_string, std::vector<uint64_t> &ints) { 5178 std::string key_with_quotes = "\""; 5179 key_with_quotes += key; 5180 key_with_quotes += "\""; 5181 const char *c = strstr(json_string, key_with_quotes.c_str()); 5182 if (c) { 5183 c += key_with_quotes.size(); 5184 5185 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5186 c++; 5187 5188 if (*c == ':') { 5189 c++; 5190 5191 while (*c != '\0' && 5192 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5193 c++; 5194 5195 if (*c == '[') { 5196 c++; 5197 while (*c != '\0' && 5198 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5199 c++; 5200 while (1) { 5201 if (!isdigit(*c)) { 5202 return true; 5203 } 5204 5205 errno = 0; 5206 char *endptr; 5207 uint64_t value = strtoul(c, &endptr, 10); 5208 if (errno == 0) { 5209 ints.push_back(value); 5210 } else { 5211 break; 5212 } 5213 if (endptr == c || endptr == nullptr || *endptr == '\0') { 5214 break; 5215 } 5216 c = endptr; 5217 5218 while (*c != '\0' && 5219 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5220 c++; 5221 if (*c == ',') 5222 c++; 5223 while (*c != '\0' && 5224 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5225 c++; 5226 if (*c == ']') { 5227 return true; 5228 } 5229 } 5230 } 5231 } 5232 } 5233 return false; 5234 } 5235 5236 JSONGenerator::ObjectSP 5237 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) { 5238 JSONGenerator::ArraySP threads_array_sp; 5239 if (m_ctx.HasValidProcessID()) { 5240 threads_array_sp.reset(new JSONGenerator::Array()); 5241 5242 nub_process_t pid = m_ctx.ProcessID(); 5243 5244 nub_size_t numthreads = DNBProcessGetNumThreads(pid); 5245 for (nub_size_t i = 0; i < numthreads; ++i) { 5246 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, i); 5247 5248 struct DNBThreadStopInfo tid_stop_info; 5249 5250 const bool stop_info_valid = 5251 DNBThreadGetStopReason(pid, tid, &tid_stop_info); 5252 5253 // If we are doing stop info only, then we only show threads that have a 5254 // valid stop reason 5255 if (threads_with_valid_stop_info_only) { 5256 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5257 continue; 5258 } 5259 5260 JSONGenerator::DictionarySP thread_dict_sp( 5261 new JSONGenerator::Dictionary()); 5262 thread_dict_sp->AddIntegerItem("tid", tid); 5263 5264 std::string reason_value("none"); 5265 5266 if (stop_info_valid) { 5267 switch (tid_stop_info.reason) { 5268 case eStopTypeInvalid: 5269 break; 5270 5271 case eStopTypeSignal: 5272 if (tid_stop_info.details.signal.signo != 0) { 5273 thread_dict_sp->AddIntegerItem("signal", 5274 tid_stop_info.details.signal.signo); 5275 reason_value = "signal"; 5276 } 5277 break; 5278 5279 case eStopTypeException: 5280 if (tid_stop_info.details.exception.type != 0) { 5281 reason_value = "exception"; 5282 thread_dict_sp->AddIntegerItem( 5283 "metype", tid_stop_info.details.exception.type); 5284 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5285 for (nub_size_t i = 0; 5286 i < tid_stop_info.details.exception.data_count; ++i) { 5287 medata_array_sp->AddItem( 5288 JSONGenerator::IntegerSP(new JSONGenerator::Integer( 5289 tid_stop_info.details.exception.data[i]))); 5290 } 5291 thread_dict_sp->AddItem("medata", medata_array_sp); 5292 } 5293 break; 5294 5295 case eStopTypeExec: 5296 reason_value = "exec"; 5297 break; 5298 } 5299 } 5300 5301 thread_dict_sp->AddStringItem("reason", reason_value); 5302 5303 if (threads_with_valid_stop_info_only == false) { 5304 const char *thread_name = DNBThreadGetName(pid, tid); 5305 if (thread_name && thread_name[0]) 5306 thread_dict_sp->AddStringItem("name", thread_name); 5307 5308 thread_identifier_info_data_t thread_ident_info; 5309 if (DNBThreadGetIdentifierInfo(pid, tid, &thread_ident_info)) { 5310 if (thread_ident_info.dispatch_qaddr != 0) { 5311 thread_dict_sp->AddIntegerItem("qaddr", 5312 thread_ident_info.dispatch_qaddr); 5313 5314 const DispatchQueueOffsets *dispatch_queue_offsets = 5315 GetDispatchQueueOffsets(); 5316 if (dispatch_queue_offsets) { 5317 std::string queue_name; 5318 uint64_t queue_width = 0; 5319 uint64_t queue_serialnum = 0; 5320 nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS; 5321 dispatch_queue_offsets->GetThreadQueueInfo( 5322 pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, 5323 queue_name, queue_width, queue_serialnum); 5324 if (dispatch_queue_t == 0 && queue_name.empty() && 5325 queue_serialnum == 0) { 5326 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5327 false); 5328 } else { 5329 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5330 true); 5331 } 5332 if (dispatch_queue_t != INVALID_NUB_ADDRESS && 5333 dispatch_queue_t != 0) 5334 thread_dict_sp->AddIntegerItem("dispatch_queue_t", 5335 dispatch_queue_t); 5336 if (!queue_name.empty()) 5337 thread_dict_sp->AddStringItem("qname", queue_name); 5338 if (queue_width == 1) 5339 thread_dict_sp->AddStringItem("qkind", "serial"); 5340 else if (queue_width > 1) 5341 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5342 if (queue_serialnum > 0) 5343 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum); 5344 } 5345 } 5346 } 5347 5348 DNBRegisterValue reg_value; 5349 5350 if (g_reg_entries != NULL) { 5351 JSONGenerator::DictionarySP registers_dict_sp( 5352 new JSONGenerator::Dictionary()); 5353 5354 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) { 5355 // Expedite all registers in the first register set that aren't 5356 // contained in other registers 5357 if (g_reg_entries[reg].nub_info.set == 1 && 5358 g_reg_entries[reg].nub_info.value_regs == NULL) { 5359 if (!DNBThreadGetRegisterValueByID( 5360 pid, tid, g_reg_entries[reg].nub_info.set, 5361 g_reg_entries[reg].nub_info.reg, ®_value)) 5362 continue; 5363 5364 std::ostringstream reg_num; 5365 reg_num << std::dec << g_reg_entries[reg].debugserver_regnum; 5366 // Encode native byte ordered bytes as hex ascii 5367 registers_dict_sp->AddBytesAsHexASCIIString( 5368 reg_num.str(), reg_value.value.v_uint8, 5369 g_reg_entries[reg].nub_info.size); 5370 } 5371 } 5372 thread_dict_sp->AddItem("registers", registers_dict_sp); 5373 } 5374 5375 // Add expedited stack memory so stack backtracing doesn't need to read 5376 // anything from the 5377 // frame pointer chain. 5378 StackMemoryMap stack_mmap; 5379 ReadStackMemory(pid, tid, stack_mmap); 5380 if (!stack_mmap.empty()) { 5381 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5382 5383 for (const auto &stack_memory : stack_mmap) { 5384 JSONGenerator::DictionarySP stack_memory_sp( 5385 new JSONGenerator::Dictionary()); 5386 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5387 stack_memory_sp->AddBytesAsHexASCIIString( 5388 "bytes", stack_memory.second.bytes, stack_memory.second.length); 5389 memory_array_sp->AddItem(stack_memory_sp); 5390 } 5391 thread_dict_sp->AddItem("memory", memory_array_sp); 5392 } 5393 } 5394 5395 threads_array_sp->AddItem(thread_dict_sp); 5396 } 5397 } 5398 return threads_array_sp; 5399 } 5400 5401 rnb_err_t RNBRemote::HandlePacket_jThreadsInfo(const char *p) { 5402 JSONGenerator::ObjectSP threads_info_sp; 5403 std::ostringstream json; 5404 std::ostringstream reply_strm; 5405 // If we haven't run the process yet, return an error. 5406 if (m_ctx.HasValidProcessID()) { 5407 const bool threads_with_valid_stop_info_only = false; 5408 JSONGenerator::ObjectSP threads_info_sp = 5409 GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5410 5411 if (threads_info_sp) { 5412 std::ostringstream strm; 5413 threads_info_sp->Dump(strm); 5414 std::string binary_packet = binary_encode_string(strm.str()); 5415 if (!binary_packet.empty()) 5416 return SendPacket(binary_packet.c_str()); 5417 } 5418 } 5419 return SendPacket("E85"); 5420 } 5421 5422 rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) { 5423 nub_process_t pid; 5424 std::ostringstream json; 5425 // If we haven't run the process yet, return an error. 5426 if (!m_ctx.HasValidProcessID()) { 5427 return SendPacket("E81"); 5428 } 5429 5430 pid = m_ctx.ProcessID(); 5431 5432 const char thread_extended_info_str[] = {"jThreadExtendedInfo:{"}; 5433 if (strncmp(p, thread_extended_info_str, 5434 sizeof(thread_extended_info_str) - 1) == 0) { 5435 p += strlen(thread_extended_info_str); 5436 5437 uint64_t tid = get_integer_value_for_key_name_from_json("thread", p); 5438 uint64_t plo_pthread_tsd_base_address_offset = 5439 get_integer_value_for_key_name_from_json( 5440 "plo_pthread_tsd_base_address_offset", p); 5441 uint64_t plo_pthread_tsd_base_offset = 5442 get_integer_value_for_key_name_from_json("plo_pthread_tsd_base_offset", 5443 p); 5444 uint64_t plo_pthread_tsd_entry_size = 5445 get_integer_value_for_key_name_from_json("plo_pthread_tsd_entry_size", 5446 p); 5447 uint64_t dti_qos_class_index = 5448 get_integer_value_for_key_name_from_json("dti_qos_class_index", p); 5449 5450 if (tid != INVALID_NUB_ADDRESS) { 5451 nub_addr_t pthread_t_value = DNBGetPThreadT(pid, tid); 5452 5453 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5454 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS && 5455 plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS && 5456 plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) { 5457 tsd_address = DNBGetTSDAddressForThread( 5458 pid, tid, plo_pthread_tsd_base_address_offset, 5459 plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5460 } 5461 5462 bool timed_out = false; 5463 Genealogy::ThreadActivitySP thread_activity_sp; 5464 5465 // If the pthread_t value is invalid, or if we were able to fetch the 5466 // thread's TSD base 5467 // and got an invalid value back, then we have a thread in early startup 5468 // or shutdown and 5469 // it's possible that gathering the genealogy information for this thread 5470 // go badly. 5471 // Ideally fetching this info for a thread in these odd states shouldn't 5472 // matter - but 5473 // we've seen some problems with these new SPI and threads in edge-casey 5474 // states. 5475 5476 double genealogy_fetch_time = 0; 5477 if (pthread_t_value != INVALID_NUB_ADDRESS && 5478 tsd_address != INVALID_NUB_ADDRESS) { 5479 DNBTimer timer(false); 5480 thread_activity_sp = DNBGetGenealogyInfoForThread(pid, tid, timed_out); 5481 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5482 } 5483 5484 std::unordered_set<uint32_t> 5485 process_info_indexes; // an array of the process info #'s seen 5486 5487 json << "{"; 5488 5489 bool need_to_print_comma = false; 5490 5491 if (thread_activity_sp && timed_out == false) { 5492 const Genealogy::Activity *activity = 5493 &thread_activity_sp->current_activity; 5494 bool need_vouchers_comma_sep = false; 5495 json << "\"activity_query_timed_out\":false,"; 5496 if (genealogy_fetch_time != 0) { 5497 // If we append the floating point value with << we'll get it in 5498 // scientific 5499 // notation. 5500 char floating_point_ascii_buffer[64]; 5501 floating_point_ascii_buffer[0] = '\0'; 5502 snprintf(floating_point_ascii_buffer, 5503 sizeof(floating_point_ascii_buffer), "%f", 5504 genealogy_fetch_time); 5505 if (strlen(floating_point_ascii_buffer) > 0) { 5506 if (need_to_print_comma) 5507 json << ","; 5508 need_to_print_comma = true; 5509 json << "\"activity_query_duration\":" 5510 << floating_point_ascii_buffer; 5511 } 5512 } 5513 if (activity->activity_id != 0) { 5514 if (need_to_print_comma) 5515 json << ","; 5516 need_to_print_comma = true; 5517 need_vouchers_comma_sep = true; 5518 json << "\"activity\":{"; 5519 json << "\"start\":" << activity->activity_start << ","; 5520 json << "\"id\":" << activity->activity_id << ","; 5521 json << "\"parent_id\":" << activity->parent_id << ","; 5522 json << "\"name\":\"" 5523 << json_string_quote_metachars(activity->activity_name) << "\","; 5524 json << "\"reason\":\"" 5525 << json_string_quote_metachars(activity->reason) << "\""; 5526 json << "}"; 5527 } 5528 if (thread_activity_sp->messages.size() > 0) { 5529 need_to_print_comma = true; 5530 if (need_vouchers_comma_sep) 5531 json << ","; 5532 need_vouchers_comma_sep = true; 5533 json << "\"trace_messages\":["; 5534 bool printed_one_message = false; 5535 for (auto iter = thread_activity_sp->messages.begin(); 5536 iter != thread_activity_sp->messages.end(); ++iter) { 5537 if (printed_one_message) 5538 json << ","; 5539 else 5540 printed_one_message = true; 5541 json << "{"; 5542 json << "\"timestamp\":" << iter->timestamp << ","; 5543 json << "\"activity_id\":" << iter->activity_id << ","; 5544 json << "\"trace_id\":" << iter->trace_id << ","; 5545 json << "\"thread\":" << iter->thread << ","; 5546 json << "\"type\":" << (int)iter->type << ","; 5547 json << "\"process_info_index\":" << iter->process_info_index 5548 << ","; 5549 process_info_indexes.insert(iter->process_info_index); 5550 json << "\"message\":\"" 5551 << json_string_quote_metachars(iter->message) << "\""; 5552 json << "}"; 5553 } 5554 json << "]"; 5555 } 5556 if (thread_activity_sp->breadcrumbs.size() == 1) { 5557 need_to_print_comma = true; 5558 if (need_vouchers_comma_sep) 5559 json << ","; 5560 need_vouchers_comma_sep = true; 5561 json << "\"breadcrumb\":{"; 5562 for (auto iter = thread_activity_sp->breadcrumbs.begin(); 5563 iter != thread_activity_sp->breadcrumbs.end(); ++iter) { 5564 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5565 json << "\"activity_id\":" << iter->activity_id << ","; 5566 json << "\"timestamp\":" << iter->timestamp << ","; 5567 json << "\"name\":\"" << json_string_quote_metachars(iter->name) 5568 << "\""; 5569 } 5570 json << "}"; 5571 } 5572 if (process_info_indexes.size() > 0) { 5573 need_to_print_comma = true; 5574 if (need_vouchers_comma_sep) 5575 json << ","; 5576 need_vouchers_comma_sep = true; 5577 bool printed_one_process_info = false; 5578 for (auto iter = process_info_indexes.begin(); 5579 iter != process_info_indexes.end(); ++iter) { 5580 if (printed_one_process_info) 5581 json << ","; 5582 Genealogy::ProcessExecutableInfoSP image_info_sp; 5583 uint32_t idx = *iter; 5584 image_info_sp = DNBGetGenealogyImageInfo(pid, idx); 5585 if (image_info_sp) { 5586 if (!printed_one_process_info) { 5587 json << "\"process_infos\":["; 5588 printed_one_process_info = true; 5589 } 5590 5591 json << "{"; 5592 char uuid_buf[37]; 5593 uuid_unparse_upper(image_info_sp->image_uuid, uuid_buf); 5594 json << "\"process_info_index\":" << idx << ","; 5595 json << "\"image_path\":\"" 5596 << json_string_quote_metachars(image_info_sp->image_path) 5597 << "\","; 5598 json << "\"image_uuid\":\"" << uuid_buf << "\""; 5599 json << "}"; 5600 } 5601 } 5602 if (printed_one_process_info) 5603 json << "]"; 5604 } 5605 } else { 5606 if (timed_out) { 5607 if (need_to_print_comma) 5608 json << ","; 5609 need_to_print_comma = true; 5610 json << "\"activity_query_timed_out\":true"; 5611 if (genealogy_fetch_time != 0) { 5612 // If we append the floating point value with << we'll get it in 5613 // scientific 5614 // notation. 5615 char floating_point_ascii_buffer[64]; 5616 floating_point_ascii_buffer[0] = '\0'; 5617 snprintf(floating_point_ascii_buffer, 5618 sizeof(floating_point_ascii_buffer), "%f", 5619 genealogy_fetch_time); 5620 if (strlen(floating_point_ascii_buffer) > 0) { 5621 json << ","; 5622 json << "\"activity_query_duration\":" 5623 << floating_point_ascii_buffer; 5624 } 5625 } 5626 } 5627 } 5628 5629 if (tsd_address != INVALID_NUB_ADDRESS) { 5630 if (need_to_print_comma) 5631 json << ","; 5632 need_to_print_comma = true; 5633 json << "\"tsd_address\":" << tsd_address; 5634 5635 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) { 5636 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread( 5637 pid, tid, tsd_address, dti_qos_class_index); 5638 if (requested_qos.IsValid()) { 5639 if (need_to_print_comma) 5640 json << ","; 5641 need_to_print_comma = true; 5642 json << "\"requested_qos\":{"; 5643 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5644 json << "\"constant_name\":\"" 5645 << json_string_quote_metachars(requested_qos.constant_name) 5646 << "\","; 5647 json << "\"printable_name\":\"" 5648 << json_string_quote_metachars(requested_qos.printable_name) 5649 << "\""; 5650 json << "}"; 5651 } 5652 } 5653 } 5654 5655 if (pthread_t_value != INVALID_NUB_ADDRESS) { 5656 if (need_to_print_comma) 5657 json << ","; 5658 need_to_print_comma = true; 5659 json << "\"pthread_t\":" << pthread_t_value; 5660 } 5661 5662 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT(pid, tid); 5663 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) { 5664 if (need_to_print_comma) 5665 json << ","; 5666 need_to_print_comma = true; 5667 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5668 } 5669 5670 json << "}"; 5671 std::string json_quoted = binary_encode_string(json.str()); 5672 return SendPacket(json_quoted); 5673 } 5674 } 5675 return SendPacket("OK"); 5676 } 5677 5678 // This packet may be called in one of three ways: 5679 // 5680 // jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704} 5681 // Look for an array of the old dyld_all_image_infos style of binary infos 5682 // at the image_list_address. 5683 // This an array of {void* load_addr, void* mod_date, void* pathname} 5684 // 5685 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} 5686 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5687 // get a list of all the 5688 // libraries loaded 5689 // 5690 // jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} 5691 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5692 // get the information 5693 // about the libraries loaded at these addresses. 5694 // 5695 rnb_err_t 5696 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) { 5697 nub_process_t pid; 5698 // If we haven't run the process yet, return an error. 5699 if (!m_ctx.HasValidProcessID()) { 5700 return SendPacket("E83"); 5701 } 5702 5703 pid = m_ctx.ProcessID(); 5704 5705 const char get_loaded_dynamic_libraries_infos_str[] = { 5706 "jGetLoadedDynamicLibrariesInfos:{"}; 5707 if (strncmp(p, get_loaded_dynamic_libraries_infos_str, 5708 sizeof(get_loaded_dynamic_libraries_infos_str) - 1) == 0) { 5709 p += strlen(get_loaded_dynamic_libraries_infos_str); 5710 5711 JSONGenerator::ObjectSP json_sp; 5712 5713 std::vector<uint64_t> macho_addresses; 5714 bool fetch_all_solibs = false; 5715 if (get_boolean_value_for_key_name_from_json("fetch_all_solibs", p, 5716 fetch_all_solibs) && 5717 fetch_all_solibs) { 5718 json_sp = DNBGetAllLoadedLibrariesInfos(pid); 5719 } else if (get_array_of_ints_value_for_key_name_from_json( 5720 "solib_addresses", p, macho_addresses)) { 5721 json_sp = DNBGetLibrariesInfoForAddresses(pid, macho_addresses); 5722 } else { 5723 nub_addr_t image_list_address = 5724 get_integer_value_for_key_name_from_json("image_list_address", p); 5725 nub_addr_t image_count = 5726 get_integer_value_for_key_name_from_json("image_count", p); 5727 5728 if (image_list_address != INVALID_NUB_ADDRESS && 5729 image_count != INVALID_NUB_ADDRESS) { 5730 json_sp = DNBGetLoadedDynamicLibrariesInfos(pid, image_list_address, 5731 image_count); 5732 } 5733 } 5734 5735 if (json_sp.get()) { 5736 std::ostringstream json_str; 5737 json_sp->Dump(json_str); 5738 if (json_str.str().size() > 0) { 5739 std::string json_str_quoted = binary_encode_string(json_str.str()); 5740 return SendPacket(json_str_quoted.c_str()); 5741 } else { 5742 SendPacket("E84"); 5743 } 5744 } 5745 } 5746 return SendPacket("OK"); 5747 } 5748 5749 // This packet does not currently take any arguments. So the behavior is 5750 // jGetSharedCacheInfo:{} 5751 // send information about the inferior's shared cache 5752 // jGetSharedCacheInfo: 5753 // send "OK" to indicate that this packet is supported 5754 rnb_err_t RNBRemote::HandlePacket_jGetSharedCacheInfo(const char *p) { 5755 nub_process_t pid; 5756 // If we haven't run the process yet, return an error. 5757 if (!m_ctx.HasValidProcessID()) { 5758 return SendPacket("E85"); 5759 } 5760 5761 pid = m_ctx.ProcessID(); 5762 5763 const char get_shared_cache_info_str[] = {"jGetSharedCacheInfo:{"}; 5764 if (strncmp(p, get_shared_cache_info_str, 5765 sizeof(get_shared_cache_info_str) - 1) == 0) { 5766 JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo(pid); 5767 5768 if (json_sp.get()) { 5769 std::ostringstream json_str; 5770 json_sp->Dump(json_str); 5771 if (json_str.str().size() > 0) { 5772 std::string json_str_quoted = binary_encode_string(json_str.str()); 5773 return SendPacket(json_str_quoted.c_str()); 5774 } else { 5775 SendPacket("E86"); 5776 } 5777 } 5778 } 5779 return SendPacket("OK"); 5780 } 5781 5782 static bool MachHeaderIsMainExecutable(nub_process_t pid, uint32_t addr_size, 5783 nub_addr_t mach_header_addr, 5784 mach_header &mh) { 5785 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, " 5786 "addr_size = %u, mach_header_addr = " 5787 "0x%16.16llx)", 5788 pid, addr_size, mach_header_addr); 5789 const nub_size_t bytes_read = 5790 DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh); 5791 if (bytes_read == sizeof(mh)) { 5792 DNBLogThreadedIf( 5793 LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = " 5794 "%u, mach_header_addr = 0x%16.16llx): mh = {\n magic = " 5795 "0x%8.8x\n cpu = 0x%8.8x\n sub = 0x%8.8x\n filetype = " 5796 "%u\n ncmds = %u\n sizeofcmds = 0x%8.8x\n flags = " 5797 "0x%8.8x }", 5798 pid, addr_size, mach_header_addr, mh.magic, mh.cputype, mh.cpusubtype, 5799 mh.filetype, mh.ncmds, mh.sizeofcmds, mh.flags); 5800 if ((addr_size == 4 && mh.magic == MH_MAGIC) || 5801 (addr_size == 8 && mh.magic == MH_MAGIC_64)) { 5802 if (mh.filetype == MH_EXECUTE) { 5803 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = " 5804 "%u, addr_size = %u, mach_header_addr = " 5805 "0x%16.16llx) -> this is the " 5806 "executable!!!", 5807 pid, addr_size, mach_header_addr); 5808 return true; 5809 } 5810 } 5811 } 5812 return false; 5813 } 5814 5815 static nub_addr_t GetMachHeaderForMainExecutable(const nub_process_t pid, 5816 const uint32_t addr_size, 5817 mach_header &mh) { 5818 struct AllImageInfos { 5819 uint32_t version; 5820 uint32_t dylib_info_count; 5821 uint64_t dylib_info_addr; 5822 }; 5823 5824 uint64_t mach_header_addr = 0; 5825 5826 const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress(pid); 5827 uint8_t bytes[256]; 5828 nub_size_t bytes_read = 0; 5829 DNBDataRef data(bytes, sizeof(bytes), false); 5830 DNBDataRef::offset_t offset = 0; 5831 data.SetPointerSize(addr_size); 5832 5833 //---------------------------------------------------------------------- 5834 // When we are sitting at __dyld_start, the kernel has placed the 5835 // address of the mach header of the main executable on the stack. If we 5836 // read the SP and dereference a pointer, we might find the mach header 5837 // for the executable. We also just make sure there is only 1 thread 5838 // since if we are at __dyld_start we shouldn't have multiple threads. 5839 //---------------------------------------------------------------------- 5840 if (DNBProcessGetNumThreads(pid) == 1) { 5841 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0); 5842 if (tid != INVALID_NUB_THREAD) { 5843 DNBRegisterValue sp_value; 5844 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, 5845 GENERIC_REGNUM_SP, &sp_value)) { 5846 uint64_t sp = 5847 addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32; 5848 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes); 5849 if (bytes_read == addr_size) { 5850 offset = 0; 5851 mach_header_addr = data.GetPointer(&offset); 5852 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5853 return mach_header_addr; 5854 } 5855 } 5856 } 5857 } 5858 5859 //---------------------------------------------------------------------- 5860 // Check the dyld_all_image_info structure for a list of mach header 5861 // since it is a very easy thing to check 5862 //---------------------------------------------------------------------- 5863 if (shlib_addr != INVALID_NUB_ADDRESS) { 5864 bytes_read = 5865 DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes); 5866 if (bytes_read > 0) { 5867 AllImageInfos aii; 5868 offset = 0; 5869 aii.version = data.Get32(&offset); 5870 aii.dylib_info_count = data.Get32(&offset); 5871 if (aii.dylib_info_count > 0) { 5872 aii.dylib_info_addr = data.GetPointer(&offset); 5873 if (aii.dylib_info_addr != 0) { 5874 const size_t image_info_byte_size = 3 * addr_size; 5875 for (uint32_t i = 0; i < aii.dylib_info_count; ++i) { 5876 bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + 5877 i * image_info_byte_size, 5878 image_info_byte_size, bytes); 5879 if (bytes_read != image_info_byte_size) 5880 break; 5881 offset = 0; 5882 mach_header_addr = data.GetPointer(&offset); 5883 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, 5884 mh)) 5885 return mach_header_addr; 5886 } 5887 } 5888 } 5889 } 5890 } 5891 5892 //---------------------------------------------------------------------- 5893 // We failed to find the executable's mach header from the all image 5894 // infos and by dereferencing the stack pointer. Now we fall back to 5895 // enumerating the memory regions and looking for regions that are 5896 // executable. 5897 //---------------------------------------------------------------------- 5898 DNBRegionInfo region_info; 5899 mach_header_addr = 0; 5900 while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, ®ion_info)) { 5901 if (region_info.size == 0) 5902 break; 5903 5904 if (region_info.permissions & eMemoryPermissionsExecutable) { 5905 DNBLogThreadedIf( 5906 LOG_RNB_PROC, "[0x%16.16llx - 0x%16.16llx) permissions = %c%c%c: " 5907 "checking region for executable mach header", 5908 region_info.addr, region_info.addr + region_info.size, 5909 (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', 5910 (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', 5911 (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-'); 5912 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5913 return mach_header_addr; 5914 } else { 5915 DNBLogThreadedIf( 5916 LOG_RNB_PROC, 5917 "[0x%16.16llx - 0x%16.16llx): permissions = %c%c%c: skipping region", 5918 region_info.addr, region_info.addr + region_info.size, 5919 (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', 5920 (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', 5921 (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-'); 5922 } 5923 // Set the address to the next mapped region 5924 mach_header_addr = region_info.addr + region_info.size; 5925 } 5926 bzero(&mh, sizeof(mh)); 5927 return INVALID_NUB_ADDRESS; 5928 } 5929 5930 rnb_err_t RNBRemote::HandlePacket_qSymbol(const char *command) { 5931 const char *p = command; 5932 p += strlen("qSymbol:"); 5933 const char *sep = strchr(p, ':'); 5934 5935 std::string symbol_name; 5936 std::string symbol_value_str; 5937 // Extract the symbol value if there is one 5938 if (sep > p) 5939 symbol_value_str.assign(p, sep - p); 5940 p = sep + 1; 5941 5942 if (*p) { 5943 // We have a symbol name 5944 symbol_name = decode_hex_ascii_string(p); 5945 if (!symbol_value_str.empty()) { 5946 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5947 if (symbol_name == "dispatch_queue_offsets") 5948 m_dispatch_queue_offsets_addr = symbol_value; 5949 } 5950 ++m_qSymbol_index; 5951 } else { 5952 // No symbol name, set our symbol index to zero so we can 5953 // read any symbols that we need 5954 m_qSymbol_index = 0; 5955 } 5956 5957 symbol_name.clear(); 5958 5959 if (m_qSymbol_index == 0) { 5960 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5961 symbol_name = "dispatch_queue_offsets"; 5962 else 5963 ++m_qSymbol_index; 5964 } 5965 5966 // // Lookup next symbol when we have one... 5967 // if (m_qSymbol_index == 1) 5968 // { 5969 // } 5970 5971 if (symbol_name.empty()) { 5972 // Done with symbol lookups 5973 return SendPacket("OK"); 5974 } else { 5975 std::ostringstream reply; 5976 reply << "qSymbol:"; 5977 for (size_t i = 0; i < symbol_name.size(); ++i) 5978 reply << RAWHEX8(symbol_name[i]); 5979 return SendPacket(reply.str().c_str()); 5980 } 5981 } 5982 5983 // Note that all numeric values returned by qProcessInfo are hex encoded, 5984 // including the pid and the cpu type. 5985 5986 rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) { 5987 nub_process_t pid; 5988 std::ostringstream rep; 5989 5990 // If we haven't run the process yet, return an error. 5991 if (!m_ctx.HasValidProcessID()) 5992 return SendPacket("E68"); 5993 5994 pid = m_ctx.ProcessID(); 5995 5996 rep << "pid:" << std::hex << pid << ';'; 5997 5998 int procpid_mib[4]; 5999 procpid_mib[0] = CTL_KERN; 6000 procpid_mib[1] = KERN_PROC; 6001 procpid_mib[2] = KERN_PROC_PID; 6002 procpid_mib[3] = pid; 6003 struct kinfo_proc proc_kinfo; 6004 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 6005 6006 if (::sysctl(procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { 6007 if (proc_kinfo_size > 0) { 6008 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';'; 6009 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid 6010 << ';'; 6011 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid 6012 << ';'; 6013 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid 6014 << ';'; 6015 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 6016 rep << "effective-gid:" << std::hex 6017 << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';'; 6018 } 6019 } 6020 6021 cpu_type_t cputype = DNBProcessGetCPUType(pid); 6022 if (cputype == 0) { 6023 DNBLog("Unable to get the process cpu_type, making a best guess."); 6024 cputype = best_guess_cpu_type(); 6025 } 6026 6027 uint32_t addr_size = 0; 6028 if (cputype != 0) { 6029 rep << "cputype:" << std::hex << cputype << ";"; 6030 if (cputype & CPU_ARCH_ABI64) 6031 addr_size = 8; 6032 else 6033 addr_size = 4; 6034 } 6035 6036 bool host_cpu_is_64bit = false; 6037 uint32_t is64bit_capable; 6038 size_t is64bit_capable_len = sizeof(is64bit_capable); 6039 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, 6040 &is64bit_capable_len, NULL, 0) == 0) 6041 host_cpu_is_64bit = is64bit_capable != 0; 6042 6043 uint32_t cpusubtype; 6044 size_t cpusubtype_len = sizeof(cpusubtype); 6045 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 6046 0) { 6047 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 6048 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 6049 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu 6050 // subtype 6051 // for i386... 6052 if (host_cpu_is_64bit) { 6053 if (cputype == CPU_TYPE_X86) { 6054 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 6055 } else if (cputype == CPU_TYPE_ARM) { 6056 // We can query a process' cputype but we cannot query a process' 6057 // cpusubtype. 6058 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit 6059 // process) and we 6060 // need to override the host cpusubtype (which is in the 6061 // CPU_SUBTYPE_ARM64 subtype namespace) 6062 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 6063 cpusubtype = 12; // CPU_SUBTYPE_ARM_V7K 6064 } 6065 } 6066 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 6067 } 6068 6069 bool os_handled = false; 6070 if (addr_size > 0) { 6071 rep << "ptrsize:" << std::dec << addr_size << ';'; 6072 6073 #if (defined(__x86_64__) || defined(__i386__)) 6074 // Try and get the OS type by looking at the load commands in the main 6075 // executable and looking for a LC_VERSION_MIN load command. This is the 6076 // most reliable way to determine the "ostype" value when on desktop. 6077 6078 mach_header mh; 6079 nub_addr_t exe_mach_header_addr = 6080 GetMachHeaderForMainExecutable(pid, addr_size, mh); 6081 if (exe_mach_header_addr != INVALID_NUB_ADDRESS) { 6082 uint64_t load_command_addr = 6083 exe_mach_header_addr + 6084 ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header)); 6085 load_command lc; 6086 for (uint32_t i = 0; i < mh.ncmds && !os_handled; ++i) { 6087 const nub_size_t bytes_read = 6088 DNBProcessMemoryRead(pid, load_command_addr, sizeof(lc), &lc); 6089 (void)bytes_read; 6090 6091 uint32_t major_version, minor_version, patch_version; 6092 auto *platform = DNBGetDeploymentInfo(pid, lc, load_command_addr, 6093 major_version, minor_version, 6094 patch_version); 6095 if (platform) { 6096 os_handled = true; 6097 rep << "ostype:" << platform << ";"; 6098 break; 6099 } 6100 load_command_addr = load_command_addr + lc.cmdsize; 6101 } 6102 } 6103 #endif // when compiling this on x86 targets 6104 } 6105 6106 // If we weren't able to find the OS in a LC_VERSION_MIN load command, try 6107 // to set it correctly by using the cpu type and other tricks 6108 if (!os_handled) { 6109 // The OS in the triple should be "ios" or "macosx" which doesn't match our 6110 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 6111 // this for now. 6112 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) { 6113 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6114 rep << "ostype:tvos;"; 6115 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6116 rep << "ostype:watchos;"; 6117 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 6118 rep << "ostype:bridgeos;"; 6119 #else 6120 rep << "ostype:ios;"; 6121 #endif 6122 } else { 6123 bool is_ios_simulator = false; 6124 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) { 6125 // Check for iOS simulator binaries by getting the process argument 6126 // and environment and checking for SIMULATOR_UDID in the environment 6127 int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2, (int)pid}; 6128 6129 uint8_t arg_data[8192]; 6130 size_t arg_data_size = sizeof(arg_data); 6131 if (::sysctl(proc_args_mib, 3, arg_data, &arg_data_size, NULL, 0) == 6132 0) { 6133 DNBDataRef data(arg_data, arg_data_size, false); 6134 DNBDataRef::offset_t offset = 0; 6135 uint32_t argc = data.Get32(&offset); 6136 const char *cstr; 6137 6138 cstr = data.GetCStr(&offset); 6139 if (cstr) { 6140 // Skip NULLs 6141 while (1) { 6142 const char *p = data.PeekCStr(offset); 6143 if ((p == NULL) || (*p != '\0')) 6144 break; 6145 ++offset; 6146 } 6147 // Now skip all arguments 6148 for (uint32_t i = 0; i < argc; ++i) { 6149 data.GetCStr(&offset); 6150 } 6151 6152 // Now iterate across all environment variables 6153 while ((cstr = data.GetCStr(&offset))) { 6154 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 6155 0) { 6156 is_ios_simulator = true; 6157 break; 6158 } 6159 if (cstr[0] == '\0') 6160 break; 6161 } 6162 } 6163 } 6164 } 6165 if (is_ios_simulator) { 6166 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6167 rep << "ostype:tvos;"; 6168 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6169 rep << "ostype:watchos;"; 6170 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 6171 rep << "ostype:bridgeos;"; 6172 #else 6173 rep << "ostype:ios;"; 6174 #endif 6175 } else { 6176 rep << "ostype:macosx;"; 6177 } 6178 } 6179 } 6180 6181 rep << "vendor:apple;"; 6182 6183 #if defined(__LITTLE_ENDIAN__) 6184 rep << "endian:little;"; 6185 #elif defined(__BIG_ENDIAN__) 6186 rep << "endian:big;"; 6187 #elif defined(__PDP_ENDIAN__) 6188 rep << "endian:pdp;"; 6189 #endif 6190 6191 if (addr_size == 0) { 6192 #if (defined(__x86_64__) || defined(__i386__)) && defined(x86_THREAD_STATE) 6193 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6194 kern_return_t kr; 6195 x86_thread_state_t gp_regs; 6196 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 6197 kr = thread_get_state(static_cast<thread_act_t>(thread), x86_THREAD_STATE, 6198 (thread_state_t)&gp_regs, &gp_count); 6199 if (kr == KERN_SUCCESS) { 6200 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 6201 rep << "ptrsize:8;"; 6202 else 6203 rep << "ptrsize:4;"; 6204 } 6205 #elif defined(__arm__) 6206 rep << "ptrsize:4;"; 6207 #elif (defined(__arm64__) || defined(__aarch64__)) && \ 6208 defined(ARM_UNIFIED_THREAD_STATE) 6209 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6210 kern_return_t kr; 6211 arm_unified_thread_state_t gp_regs; 6212 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 6213 kr = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE, 6214 (thread_state_t)&gp_regs, &gp_count); 6215 if (kr == KERN_SUCCESS) { 6216 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 6217 rep << "ptrsize:8;"; 6218 else 6219 rep << "ptrsize:4;"; 6220 } 6221 #endif 6222 } 6223 6224 return SendPacket(rep.str()); 6225 } 6226 6227 const RNBRemote::DispatchQueueOffsets *RNBRemote::GetDispatchQueueOffsets() { 6228 if (!m_dispatch_queue_offsets.IsValid() && 6229 m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && 6230 m_ctx.HasValidProcessID()) { 6231 nub_process_t pid = m_ctx.ProcessID(); 6232 nub_size_t bytes_read = DNBProcessMemoryRead( 6233 pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), 6234 &m_dispatch_queue_offsets); 6235 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 6236 m_dispatch_queue_offsets.Clear(); 6237 } 6238 6239 if (m_dispatch_queue_offsets.IsValid()) 6240 return &m_dispatch_queue_offsets; 6241 else 6242 return nullptr; 6243 } 6244 6245 void RNBRemote::EnableCompressionNextSendPacket(compression_types type) { 6246 m_compression_mode = type; 6247 m_enable_compression_next_send_packet = true; 6248 } 6249 6250 compression_types RNBRemote::GetCompressionType() { 6251 // The first packet we send back to the debugger after a QEnableCompression 6252 // request 6253 // should be uncompressed -- so we can indicate whether the compression was 6254 // enabled 6255 // or not via OK / Enn returns. After that, all packets sent will be using 6256 // the 6257 // compression protocol. 6258 6259 if (m_enable_compression_next_send_packet) { 6260 // One time, we send back "None" as our compression type 6261 m_enable_compression_next_send_packet = false; 6262 return compression_types::none; 6263 } 6264 return m_compression_mode; 6265 } 6266