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 #else 4655 strm << "ostype:ios;"; 4656 #endif 4657 4658 // On armv7 we use "synchronous" watchpoints which means the exception is 4659 // delivered before the instruction executes. 4660 strm << "watchpoint_exceptions_received:before;"; 4661 } else { 4662 strm << "ostype:macosx;"; 4663 strm << "watchpoint_exceptions_received:after;"; 4664 } 4665 // char ostype[64]; 4666 // len = sizeof(ostype); 4667 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4668 // { 4669 // len = strlen(ostype); 4670 // std::transform (ostype, ostype + len, ostype, tolower); 4671 // strm << "ostype:" << std::dec << ostype << ';'; 4672 // } 4673 4674 strm << "vendor:apple;"; 4675 4676 uint64_t major, minor, patch; 4677 if (DNBGetOSVersionNumbers(&major, &minor, &patch)) { 4678 strm << "os_version:" << major << "." << minor; 4679 if (patch != UINT64_MAX) 4680 strm << "." << patch; 4681 strm << ";"; 4682 } 4683 4684 #if defined(__LITTLE_ENDIAN__) 4685 strm << "endian:little;"; 4686 #elif defined(__BIG_ENDIAN__) 4687 strm << "endian:big;"; 4688 #elif defined(__PDP_ENDIAN__) 4689 strm << "endian:pdp;"; 4690 #endif 4691 4692 if (promoted_to_64) 4693 strm << "ptrsize:8;"; 4694 else 4695 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4696 4697 #if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4698 strm << "default_packet_timeout:10;"; 4699 #endif 4700 4701 return SendPacket(strm.str()); 4702 } 4703 4704 void XMLElementStart(std::ostringstream &s, uint32_t indent, const char *name, 4705 bool has_attributes) { 4706 if (indent) 4707 s << INDENT_WITH_SPACES(indent); 4708 s << '<' << name; 4709 if (!has_attributes) 4710 s << '>' << std::endl; 4711 } 4712 4713 void XMLElementStartEndAttributes(std::ostringstream &s, bool empty) { 4714 if (empty) 4715 s << '/'; 4716 s << '>' << std::endl; 4717 } 4718 4719 void XMLElementEnd(std::ostringstream &s, uint32_t indent, const char *name) { 4720 if (indent) 4721 s << INDENT_WITH_SPACES(indent); 4722 s << '<' << '/' << name << '>' << std::endl; 4723 } 4724 4725 void XMLElementWithStringValue(std::ostringstream &s, uint32_t indent, 4726 const char *name, const char *value, 4727 bool close = true) { 4728 if (value) { 4729 if (indent) 4730 s << INDENT_WITH_SPACES(indent); 4731 s << '<' << name << '>' << value; 4732 if (close) 4733 XMLElementEnd(s, 0, name); 4734 } 4735 } 4736 4737 void XMLElementWithUnsignedValue(std::ostringstream &s, uint32_t indent, 4738 const char *name, uint64_t value, 4739 bool close = true) { 4740 if (indent) 4741 s << INDENT_WITH_SPACES(indent); 4742 4743 s << '<' << name << '>' << DECIMAL << value; 4744 if (close) 4745 XMLElementEnd(s, 0, name); 4746 } 4747 4748 void XMLAttributeString(std::ostringstream &s, const char *name, 4749 const char *value, const char *default_value = NULL) { 4750 if (value) { 4751 if (default_value && strcmp(value, default_value) == 0) 4752 return; // No need to emit the attribute because it matches the default 4753 // value 4754 s << ' ' << name << "=\"" << value << "\""; 4755 } 4756 } 4757 4758 void XMLAttributeUnsignedDecimal(std::ostringstream &s, const char *name, 4759 uint64_t value) { 4760 s << ' ' << name << "=\"" << DECIMAL << value << "\""; 4761 } 4762 4763 void GenerateTargetXMLRegister(std::ostringstream &s, const uint32_t reg_num, 4764 nub_size_t num_reg_sets, 4765 const DNBRegisterSetInfo *reg_set_info, 4766 const register_map_entry_t ®) { 4767 const char *default_lldb_encoding = "uint"; 4768 const char *lldb_encoding = default_lldb_encoding; 4769 const char *gdb_group = "general"; 4770 const char *default_gdb_type = "int"; 4771 const char *gdb_type = default_gdb_type; 4772 const char *default_lldb_format = "hex"; 4773 const char *lldb_format = default_lldb_format; 4774 const char *lldb_set = NULL; 4775 4776 switch (reg.nub_info.type) { 4777 case Uint: 4778 lldb_encoding = "uint"; 4779 break; 4780 case Sint: 4781 lldb_encoding = "sint"; 4782 break; 4783 case IEEE754: 4784 lldb_encoding = "ieee754"; 4785 if (reg.nub_info.set > 0) 4786 gdb_group = "float"; 4787 break; 4788 case Vector: 4789 lldb_encoding = "vector"; 4790 if (reg.nub_info.set > 0) 4791 gdb_group = "vector"; 4792 break; 4793 } 4794 4795 switch (reg.nub_info.format) { 4796 case Binary: 4797 lldb_format = "binary"; 4798 break; 4799 case Decimal: 4800 lldb_format = "decimal"; 4801 break; 4802 case Hex: 4803 lldb_format = "hex"; 4804 break; 4805 case Float: 4806 gdb_type = "float"; 4807 lldb_format = "float"; 4808 break; 4809 case VectorOfSInt8: 4810 gdb_type = "float"; 4811 lldb_format = "vector-sint8"; 4812 break; 4813 case VectorOfUInt8: 4814 gdb_type = "float"; 4815 lldb_format = "vector-uint8"; 4816 break; 4817 case VectorOfSInt16: 4818 gdb_type = "float"; 4819 lldb_format = "vector-sint16"; 4820 break; 4821 case VectorOfUInt16: 4822 gdb_type = "float"; 4823 lldb_format = "vector-uint16"; 4824 break; 4825 case VectorOfSInt32: 4826 gdb_type = "float"; 4827 lldb_format = "vector-sint32"; 4828 break; 4829 case VectorOfUInt32: 4830 gdb_type = "float"; 4831 lldb_format = "vector-uint32"; 4832 break; 4833 case VectorOfFloat32: 4834 gdb_type = "float"; 4835 lldb_format = "vector-float32"; 4836 break; 4837 case VectorOfUInt128: 4838 gdb_type = "float"; 4839 lldb_format = "vector-uint128"; 4840 break; 4841 }; 4842 if (reg_set_info && reg.nub_info.set < num_reg_sets) 4843 lldb_set = reg_set_info[reg.nub_info.set].name; 4844 4845 uint32_t indent = 2; 4846 4847 XMLElementStart(s, indent, "reg", true); 4848 XMLAttributeString(s, "name", reg.nub_info.name); 4849 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 4850 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 4851 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 4852 XMLAttributeString(s, "group", gdb_group); 4853 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 4854 XMLAttributeString(s, "altname", reg.nub_info.alt); 4855 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 4856 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 4857 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 4858 if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM) 4859 XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe); 4860 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 4861 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 4862 4863 const char *lldb_generic = NULL; 4864 switch (reg.nub_info.reg_generic) { 4865 case GENERIC_REGNUM_FP: 4866 lldb_generic = "fp"; 4867 break; 4868 case GENERIC_REGNUM_PC: 4869 lldb_generic = "pc"; 4870 break; 4871 case GENERIC_REGNUM_SP: 4872 lldb_generic = "sp"; 4873 break; 4874 case GENERIC_REGNUM_RA: 4875 lldb_generic = "ra"; 4876 break; 4877 case GENERIC_REGNUM_FLAGS: 4878 lldb_generic = "flags"; 4879 break; 4880 case GENERIC_REGNUM_ARG1: 4881 lldb_generic = "arg1"; 4882 break; 4883 case GENERIC_REGNUM_ARG2: 4884 lldb_generic = "arg2"; 4885 break; 4886 case GENERIC_REGNUM_ARG3: 4887 lldb_generic = "arg3"; 4888 break; 4889 case GENERIC_REGNUM_ARG4: 4890 lldb_generic = "arg4"; 4891 break; 4892 case GENERIC_REGNUM_ARG5: 4893 lldb_generic = "arg5"; 4894 break; 4895 case GENERIC_REGNUM_ARG6: 4896 lldb_generic = "arg6"; 4897 break; 4898 case GENERIC_REGNUM_ARG7: 4899 lldb_generic = "arg7"; 4900 break; 4901 case GENERIC_REGNUM_ARG8: 4902 lldb_generic = "arg8"; 4903 break; 4904 default: 4905 break; 4906 } 4907 XMLAttributeString(s, "generic", lldb_generic); 4908 4909 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 4910 if (!empty) { 4911 if (!reg.value_regnums.empty()) { 4912 std::ostringstream regnums; 4913 bool first = true; 4914 regnums << DECIMAL; 4915 for (auto regnum : reg.value_regnums) { 4916 if (!first) 4917 regnums << ','; 4918 regnums << regnum; 4919 first = false; 4920 } 4921 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 4922 } 4923 4924 if (!reg.invalidate_regnums.empty()) { 4925 std::ostringstream regnums; 4926 bool first = true; 4927 regnums << DECIMAL; 4928 for (auto regnum : reg.invalidate_regnums) { 4929 if (!first) 4930 regnums << ','; 4931 regnums << regnum; 4932 first = false; 4933 } 4934 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 4935 } 4936 } 4937 XMLElementStartEndAttributes(s, true); 4938 } 4939 4940 void GenerateTargetXMLRegisters(std::ostringstream &s) { 4941 nub_size_t num_reg_sets = 0; 4942 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo(&num_reg_sets); 4943 4944 uint32_t cputype = DNBGetRegisterCPUType(); 4945 if (cputype) { 4946 XMLElementStart(s, 0, "feature", true); 4947 std::ostringstream name_strm; 4948 name_strm << "com.apple.debugserver." << GetArchName(cputype, 0); 4949 XMLAttributeString(s, "name", name_strm.str().c_str()); 4950 XMLElementStartEndAttributes(s, false); 4951 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 4952 // for (const auto ®: g_dynamic_register_map) 4953 { 4954 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, 4955 g_reg_entries[reg_num]); 4956 } 4957 XMLElementEnd(s, 0, "feature"); 4958 4959 if (num_reg_sets > 0) { 4960 XMLElementStart(s, 0, "groups", false); 4961 for (uint32_t set = 1; set < num_reg_sets; ++set) { 4962 XMLElementStart(s, 2, "group", true); 4963 XMLAttributeUnsignedDecimal(s, "id", set); 4964 XMLAttributeString(s, "name", reg_sets[set].name); 4965 XMLElementStartEndAttributes(s, true); 4966 } 4967 XMLElementEnd(s, 0, "groups"); 4968 } 4969 } 4970 } 4971 4972 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 4973 <target version="1.0">)"; 4974 4975 static const char *g_target_xml_footer = "</target>"; 4976 4977 static std::string g_target_xml; 4978 4979 void UpdateTargetXML() { 4980 std::ostringstream s; 4981 s << g_target_xml_header << std::endl; 4982 4983 // Set the architecture 4984 // s << "<architecture>" << arch "</architecture>" << std::endl; 4985 4986 // Set the OSABI 4987 // s << "<osabi>abi-name</osabi>" 4988 4989 GenerateTargetXMLRegisters(s); 4990 4991 s << g_target_xml_footer << std::endl; 4992 4993 // Save the XML output in case it gets retrieved in chunks 4994 g_target_xml = s.str(); 4995 } 4996 4997 rnb_err_t RNBRemote::HandlePacket_qXfer(const char *command) { 4998 const char *p = command; 4999 p += strlen("qXfer:"); 5000 const char *sep = strchr(p, ':'); 5001 if (sep) { 5002 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 5003 p = sep + 1; 5004 sep = strchr(p, ':'); 5005 if (sep) { 5006 std::string rw(p, sep - p); // "read" or "write" 5007 p = sep + 1; 5008 sep = strchr(p, ':'); 5009 if (sep) { 5010 std::string annex(p, sep - p); // "read" or "write" 5011 5012 p = sep + 1; 5013 sep = strchr(p, ','); 5014 if (sep) { 5015 std::string offset_str(p, sep - p); // read the length as a string 5016 p = sep + 1; 5017 std::string length_str(p); // read the offset as a string 5018 char *end = nullptr; 5019 const uint64_t offset = strtoul(offset_str.c_str(), &end, 5020 16); // convert offset_str to a offset 5021 if (*end == '\0') { 5022 const uint64_t length = strtoul( 5023 length_str.c_str(), &end, 16); // convert length_str to a length 5024 if (*end == '\0') { 5025 if (object == "features" && rw == "read" && 5026 annex == "target.xml") { 5027 std::ostringstream xml_out; 5028 5029 if (offset == 0) { 5030 InitializeRegisters(true); 5031 5032 UpdateTargetXML(); 5033 if (g_target_xml.empty()) 5034 return SendPacket("E83"); 5035 5036 if (length > g_target_xml.size()) { 5037 xml_out << 'l'; // No more data 5038 xml_out << binary_encode_string(g_target_xml); 5039 } else { 5040 xml_out << 'm'; // More data needs to be read with a 5041 // subsequent call 5042 xml_out << binary_encode_string( 5043 std::string(g_target_xml, offset, length)); 5044 } 5045 } else { 5046 // Retrieving target XML in chunks 5047 if (offset < g_target_xml.size()) { 5048 std::string chunk(g_target_xml, offset, length); 5049 if (chunk.size() < length) 5050 xml_out << 'l'; // No more data 5051 else 5052 xml_out << 'm'; // More data needs to be read with a 5053 // subsequent call 5054 xml_out << binary_encode_string(chunk.data()); 5055 } 5056 } 5057 return SendPacket(xml_out.str()); 5058 } 5059 // Well formed, put not supported 5060 return HandlePacket_UNIMPLEMENTED(command); 5061 } 5062 } 5063 } 5064 } else { 5065 SendPacket("E85"); 5066 } 5067 } else { 5068 SendPacket("E86"); 5069 } 5070 } 5071 return SendPacket("E82"); 5072 } 5073 5074 rnb_err_t RNBRemote::HandlePacket_qGDBServerVersion(const char *p) { 5075 std::ostringstream strm; 5076 5077 #if defined(DEBUGSERVER_PROGRAM_NAME) 5078 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 5079 #else 5080 strm << "name:debugserver;"; 5081 #endif 5082 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 5083 5084 return SendPacket(strm.str()); 5085 } 5086 5087 // A helper function that retrieves a single integer value from 5088 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5089 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 5090 // 5091 uint64_t get_integer_value_for_key_name_from_json(const char *key, 5092 const char *json_string) { 5093 uint64_t retval = INVALID_NUB_ADDRESS; 5094 std::string key_with_quotes = "\""; 5095 key_with_quotes += key; 5096 key_with_quotes += "\""; 5097 const char *c = strstr(json_string, key_with_quotes.c_str()); 5098 if (c) { 5099 c += key_with_quotes.size(); 5100 5101 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5102 c++; 5103 5104 if (*c == ':') { 5105 c++; 5106 5107 while (*c != '\0' && 5108 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5109 c++; 5110 5111 errno = 0; 5112 retval = strtoul(c, NULL, 10); 5113 if (errno != 0) { 5114 retval = INVALID_NUB_ADDRESS; 5115 } 5116 } 5117 } 5118 return retval; 5119 } 5120 5121 // A helper function that retrieves a boolean value from 5122 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5123 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}] 5124 5125 // Returns true if it was able to find the key name, and sets the 'value' 5126 // argument to the value found. 5127 5128 bool get_boolean_value_for_key_name_from_json(const char *key, 5129 const char *json_string, 5130 bool &value) { 5131 std::string key_with_quotes = "\""; 5132 key_with_quotes += key; 5133 key_with_quotes += "\""; 5134 const char *c = strstr(json_string, key_with_quotes.c_str()); 5135 if (c) { 5136 c += key_with_quotes.size(); 5137 5138 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5139 c++; 5140 5141 if (*c == ':') { 5142 c++; 5143 5144 while (*c != '\0' && 5145 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5146 c++; 5147 5148 if (strncmp(c, "true", 4) == 0) { 5149 value = true; 5150 return true; 5151 } else if (strncmp(c, "false", 5) == 0) { 5152 value = false; 5153 return true; 5154 } 5155 } 5156 } 5157 return false; 5158 } 5159 5160 // A helper function that reads an array of uint64_t's from 5161 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5162 // jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}] 5163 5164 // Returns true if it was able to find the key name, false if it did not. 5165 // "ints" will have all integers found in the array appended to it. 5166 5167 bool get_array_of_ints_value_for_key_name_from_json( 5168 const char *key, const char *json_string, std::vector<uint64_t> &ints) { 5169 std::string key_with_quotes = "\""; 5170 key_with_quotes += key; 5171 key_with_quotes += "\""; 5172 const char *c = strstr(json_string, key_with_quotes.c_str()); 5173 if (c) { 5174 c += key_with_quotes.size(); 5175 5176 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5177 c++; 5178 5179 if (*c == ':') { 5180 c++; 5181 5182 while (*c != '\0' && 5183 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5184 c++; 5185 5186 if (*c == '[') { 5187 c++; 5188 while (*c != '\0' && 5189 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5190 c++; 5191 while (1) { 5192 if (!isdigit(*c)) { 5193 return true; 5194 } 5195 5196 errno = 0; 5197 char *endptr; 5198 uint64_t value = strtoul(c, &endptr, 10); 5199 if (errno == 0) { 5200 ints.push_back(value); 5201 } else { 5202 break; 5203 } 5204 if (endptr == c || endptr == nullptr || *endptr == '\0') { 5205 break; 5206 } 5207 c = endptr; 5208 5209 while (*c != '\0' && 5210 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5211 c++; 5212 if (*c == ',') 5213 c++; 5214 while (*c != '\0' && 5215 (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5216 c++; 5217 if (*c == ']') { 5218 return true; 5219 } 5220 } 5221 } 5222 } 5223 } 5224 return false; 5225 } 5226 5227 JSONGenerator::ObjectSP 5228 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) { 5229 JSONGenerator::ArraySP threads_array_sp; 5230 if (m_ctx.HasValidProcessID()) { 5231 threads_array_sp.reset(new JSONGenerator::Array()); 5232 5233 nub_process_t pid = m_ctx.ProcessID(); 5234 5235 nub_size_t numthreads = DNBProcessGetNumThreads(pid); 5236 for (nub_size_t i = 0; i < numthreads; ++i) { 5237 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, i); 5238 5239 struct DNBThreadStopInfo tid_stop_info; 5240 5241 const bool stop_info_valid = 5242 DNBThreadGetStopReason(pid, tid, &tid_stop_info); 5243 5244 // If we are doing stop info only, then we only show threads that have a 5245 // valid stop reason 5246 if (threads_with_valid_stop_info_only) { 5247 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5248 continue; 5249 } 5250 5251 JSONGenerator::DictionarySP thread_dict_sp( 5252 new JSONGenerator::Dictionary()); 5253 thread_dict_sp->AddIntegerItem("tid", tid); 5254 5255 std::string reason_value("none"); 5256 5257 if (stop_info_valid) { 5258 switch (tid_stop_info.reason) { 5259 case eStopTypeInvalid: 5260 break; 5261 5262 case eStopTypeSignal: 5263 if (tid_stop_info.details.signal.signo != 0) { 5264 thread_dict_sp->AddIntegerItem("signal", 5265 tid_stop_info.details.signal.signo); 5266 reason_value = "signal"; 5267 } 5268 break; 5269 5270 case eStopTypeException: 5271 if (tid_stop_info.details.exception.type != 0) { 5272 reason_value = "exception"; 5273 thread_dict_sp->AddIntegerItem( 5274 "metype", tid_stop_info.details.exception.type); 5275 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5276 for (nub_size_t i = 0; 5277 i < tid_stop_info.details.exception.data_count; ++i) { 5278 medata_array_sp->AddItem( 5279 JSONGenerator::IntegerSP(new JSONGenerator::Integer( 5280 tid_stop_info.details.exception.data[i]))); 5281 } 5282 thread_dict_sp->AddItem("medata", medata_array_sp); 5283 } 5284 break; 5285 5286 case eStopTypeExec: 5287 reason_value = "exec"; 5288 break; 5289 } 5290 } 5291 5292 thread_dict_sp->AddStringItem("reason", reason_value); 5293 5294 if (threads_with_valid_stop_info_only == false) { 5295 const char *thread_name = DNBThreadGetName(pid, tid); 5296 if (thread_name && thread_name[0]) 5297 thread_dict_sp->AddStringItem("name", thread_name); 5298 5299 thread_identifier_info_data_t thread_ident_info; 5300 if (DNBThreadGetIdentifierInfo(pid, tid, &thread_ident_info)) { 5301 if (thread_ident_info.dispatch_qaddr != 0) { 5302 thread_dict_sp->AddIntegerItem("qaddr", 5303 thread_ident_info.dispatch_qaddr); 5304 5305 const DispatchQueueOffsets *dispatch_queue_offsets = 5306 GetDispatchQueueOffsets(); 5307 if (dispatch_queue_offsets) { 5308 std::string queue_name; 5309 uint64_t queue_width = 0; 5310 uint64_t queue_serialnum = 0; 5311 nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS; 5312 dispatch_queue_offsets->GetThreadQueueInfo( 5313 pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, 5314 queue_name, queue_width, queue_serialnum); 5315 if (dispatch_queue_t == 0 && queue_name.empty() && 5316 queue_serialnum == 0) { 5317 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5318 false); 5319 } else { 5320 thread_dict_sp->AddBooleanItem("associated_with_dispatch_queue", 5321 true); 5322 } 5323 if (dispatch_queue_t != INVALID_NUB_ADDRESS && 5324 dispatch_queue_t != 0) 5325 thread_dict_sp->AddIntegerItem("dispatch_queue_t", 5326 dispatch_queue_t); 5327 if (!queue_name.empty()) 5328 thread_dict_sp->AddStringItem("qname", queue_name); 5329 if (queue_width == 1) 5330 thread_dict_sp->AddStringItem("qkind", "serial"); 5331 else if (queue_width > 1) 5332 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5333 if (queue_serialnum > 0) 5334 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum); 5335 } 5336 } 5337 } 5338 5339 DNBRegisterValue reg_value; 5340 5341 if (g_reg_entries != NULL) { 5342 JSONGenerator::DictionarySP registers_dict_sp( 5343 new JSONGenerator::Dictionary()); 5344 5345 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) { 5346 // Expedite all registers in the first register set that aren't 5347 // contained in other registers 5348 if (g_reg_entries[reg].nub_info.set == 1 && 5349 g_reg_entries[reg].nub_info.value_regs == NULL) { 5350 if (!DNBThreadGetRegisterValueByID( 5351 pid, tid, g_reg_entries[reg].nub_info.set, 5352 g_reg_entries[reg].nub_info.reg, ®_value)) 5353 continue; 5354 5355 std::ostringstream reg_num; 5356 reg_num << std::dec << g_reg_entries[reg].debugserver_regnum; 5357 // Encode native byte ordered bytes as hex ascii 5358 registers_dict_sp->AddBytesAsHexASCIIString( 5359 reg_num.str(), reg_value.value.v_uint8, 5360 g_reg_entries[reg].nub_info.size); 5361 } 5362 } 5363 thread_dict_sp->AddItem("registers", registers_dict_sp); 5364 } 5365 5366 // Add expedited stack memory so stack backtracing doesn't need to read 5367 // anything from the 5368 // frame pointer chain. 5369 StackMemoryMap stack_mmap; 5370 ReadStackMemory(pid, tid, stack_mmap); 5371 if (!stack_mmap.empty()) { 5372 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5373 5374 for (const auto &stack_memory : stack_mmap) { 5375 JSONGenerator::DictionarySP stack_memory_sp( 5376 new JSONGenerator::Dictionary()); 5377 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5378 stack_memory_sp->AddBytesAsHexASCIIString( 5379 "bytes", stack_memory.second.bytes, stack_memory.second.length); 5380 memory_array_sp->AddItem(stack_memory_sp); 5381 } 5382 thread_dict_sp->AddItem("memory", memory_array_sp); 5383 } 5384 } 5385 5386 threads_array_sp->AddItem(thread_dict_sp); 5387 } 5388 } 5389 return threads_array_sp; 5390 } 5391 5392 rnb_err_t RNBRemote::HandlePacket_jThreadsInfo(const char *p) { 5393 JSONGenerator::ObjectSP threads_info_sp; 5394 std::ostringstream json; 5395 std::ostringstream reply_strm; 5396 // If we haven't run the process yet, return an error. 5397 if (m_ctx.HasValidProcessID()) { 5398 const bool threads_with_valid_stop_info_only = false; 5399 JSONGenerator::ObjectSP threads_info_sp = 5400 GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5401 5402 if (threads_info_sp) { 5403 std::ostringstream strm; 5404 threads_info_sp->Dump(strm); 5405 std::string binary_packet = binary_encode_string(strm.str()); 5406 if (!binary_packet.empty()) 5407 return SendPacket(binary_packet.c_str()); 5408 } 5409 } 5410 return SendPacket("E85"); 5411 } 5412 5413 rnb_err_t RNBRemote::HandlePacket_jThreadExtendedInfo(const char *p) { 5414 nub_process_t pid; 5415 std::ostringstream json; 5416 // If we haven't run the process yet, return an error. 5417 if (!m_ctx.HasValidProcessID()) { 5418 return SendPacket("E81"); 5419 } 5420 5421 pid = m_ctx.ProcessID(); 5422 5423 const char thread_extended_info_str[] = {"jThreadExtendedInfo:{"}; 5424 if (strncmp(p, thread_extended_info_str, 5425 sizeof(thread_extended_info_str) - 1) == 0) { 5426 p += strlen(thread_extended_info_str); 5427 5428 uint64_t tid = get_integer_value_for_key_name_from_json("thread", p); 5429 uint64_t plo_pthread_tsd_base_address_offset = 5430 get_integer_value_for_key_name_from_json( 5431 "plo_pthread_tsd_base_address_offset", p); 5432 uint64_t plo_pthread_tsd_base_offset = 5433 get_integer_value_for_key_name_from_json("plo_pthread_tsd_base_offset", 5434 p); 5435 uint64_t plo_pthread_tsd_entry_size = 5436 get_integer_value_for_key_name_from_json("plo_pthread_tsd_entry_size", 5437 p); 5438 uint64_t dti_qos_class_index = 5439 get_integer_value_for_key_name_from_json("dti_qos_class_index", p); 5440 // Commented out the two variables below as they are not being used 5441 // uint64_t dti_queue_index = 5442 // get_integer_value_for_key_name_from_json ("dti_queue_index", p); 5443 // uint64_t dti_voucher_index = 5444 // get_integer_value_for_key_name_from_json ("dti_voucher_index", p); 5445 5446 if (tid != INVALID_NUB_ADDRESS) { 5447 nub_addr_t pthread_t_value = DNBGetPThreadT(pid, tid); 5448 5449 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5450 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS && 5451 plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS && 5452 plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) { 5453 tsd_address = DNBGetTSDAddressForThread( 5454 pid, tid, plo_pthread_tsd_base_address_offset, 5455 plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5456 } 5457 5458 bool timed_out = false; 5459 Genealogy::ThreadActivitySP thread_activity_sp; 5460 5461 // If the pthread_t value is invalid, or if we were able to fetch the 5462 // thread's TSD base 5463 // and got an invalid value back, then we have a thread in early startup 5464 // or shutdown and 5465 // it's possible that gathering the genealogy information for this thread 5466 // go badly. 5467 // Ideally fetching this info for a thread in these odd states shouldn't 5468 // matter - but 5469 // we've seen some problems with these new SPI and threads in edge-casey 5470 // states. 5471 5472 double genealogy_fetch_time = 0; 5473 if (pthread_t_value != INVALID_NUB_ADDRESS && 5474 tsd_address != INVALID_NUB_ADDRESS) { 5475 DNBTimer timer(false); 5476 thread_activity_sp = DNBGetGenealogyInfoForThread(pid, tid, timed_out); 5477 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5478 } 5479 5480 std::unordered_set<uint32_t> 5481 process_info_indexes; // an array of the process info #'s seen 5482 5483 json << "{"; 5484 5485 bool need_to_print_comma = false; 5486 5487 if (thread_activity_sp && timed_out == false) { 5488 const Genealogy::Activity *activity = 5489 &thread_activity_sp->current_activity; 5490 bool need_vouchers_comma_sep = false; 5491 json << "\"activity_query_timed_out\":false,"; 5492 if (genealogy_fetch_time != 0) { 5493 // If we append the floating point value with << we'll get it in 5494 // scientific 5495 // notation. 5496 char floating_point_ascii_buffer[64]; 5497 floating_point_ascii_buffer[0] = '\0'; 5498 snprintf(floating_point_ascii_buffer, 5499 sizeof(floating_point_ascii_buffer), "%f", 5500 genealogy_fetch_time); 5501 if (strlen(floating_point_ascii_buffer) > 0) { 5502 if (need_to_print_comma) 5503 json << ","; 5504 need_to_print_comma = true; 5505 json << "\"activity_query_duration\":" 5506 << floating_point_ascii_buffer; 5507 } 5508 } 5509 if (activity->activity_id != 0) { 5510 if (need_to_print_comma) 5511 json << ","; 5512 need_to_print_comma = true; 5513 need_vouchers_comma_sep = true; 5514 json << "\"activity\":{"; 5515 json << "\"start\":" << activity->activity_start << ","; 5516 json << "\"id\":" << activity->activity_id << ","; 5517 json << "\"parent_id\":" << activity->parent_id << ","; 5518 json << "\"name\":\"" 5519 << json_string_quote_metachars(activity->activity_name) << "\","; 5520 json << "\"reason\":\"" 5521 << json_string_quote_metachars(activity->reason) << "\""; 5522 json << "}"; 5523 } 5524 if (thread_activity_sp->messages.size() > 0) { 5525 need_to_print_comma = true; 5526 if (need_vouchers_comma_sep) 5527 json << ","; 5528 need_vouchers_comma_sep = true; 5529 json << "\"trace_messages\":["; 5530 bool printed_one_message = false; 5531 for (auto iter = thread_activity_sp->messages.begin(); 5532 iter != thread_activity_sp->messages.end(); ++iter) { 5533 if (printed_one_message) 5534 json << ","; 5535 else 5536 printed_one_message = true; 5537 json << "{"; 5538 json << "\"timestamp\":" << iter->timestamp << ","; 5539 json << "\"activity_id\":" << iter->activity_id << ","; 5540 json << "\"trace_id\":" << iter->trace_id << ","; 5541 json << "\"thread\":" << iter->thread << ","; 5542 json << "\"type\":" << (int)iter->type << ","; 5543 json << "\"process_info_index\":" << iter->process_info_index 5544 << ","; 5545 process_info_indexes.insert(iter->process_info_index); 5546 json << "\"message\":\"" 5547 << json_string_quote_metachars(iter->message) << "\""; 5548 json << "}"; 5549 } 5550 json << "]"; 5551 } 5552 if (thread_activity_sp->breadcrumbs.size() == 1) { 5553 need_to_print_comma = true; 5554 if (need_vouchers_comma_sep) 5555 json << ","; 5556 need_vouchers_comma_sep = true; 5557 json << "\"breadcrumb\":{"; 5558 for (auto iter = thread_activity_sp->breadcrumbs.begin(); 5559 iter != thread_activity_sp->breadcrumbs.end(); ++iter) { 5560 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5561 json << "\"activity_id\":" << iter->activity_id << ","; 5562 json << "\"timestamp\":" << iter->timestamp << ","; 5563 json << "\"name\":\"" << json_string_quote_metachars(iter->name) 5564 << "\""; 5565 } 5566 json << "}"; 5567 } 5568 if (process_info_indexes.size() > 0) { 5569 need_to_print_comma = true; 5570 if (need_vouchers_comma_sep) 5571 json << ","; 5572 need_vouchers_comma_sep = true; 5573 bool printed_one_process_info = false; 5574 for (auto iter = process_info_indexes.begin(); 5575 iter != process_info_indexes.end(); ++iter) { 5576 if (printed_one_process_info) 5577 json << ","; 5578 Genealogy::ProcessExecutableInfoSP image_info_sp; 5579 uint32_t idx = *iter; 5580 image_info_sp = DNBGetGenealogyImageInfo(pid, idx); 5581 if (image_info_sp) { 5582 if (!printed_one_process_info) { 5583 json << "\"process_infos\":["; 5584 printed_one_process_info = true; 5585 } 5586 5587 json << "{"; 5588 char uuid_buf[37]; 5589 uuid_unparse_upper(image_info_sp->image_uuid, uuid_buf); 5590 json << "\"process_info_index\":" << idx << ","; 5591 json << "\"image_path\":\"" 5592 << json_string_quote_metachars(image_info_sp->image_path) 5593 << "\","; 5594 json << "\"image_uuid\":\"" << uuid_buf << "\""; 5595 json << "}"; 5596 } 5597 } 5598 if (printed_one_process_info) 5599 json << "]"; 5600 } 5601 } else { 5602 if (timed_out) { 5603 if (need_to_print_comma) 5604 json << ","; 5605 need_to_print_comma = true; 5606 json << "\"activity_query_timed_out\":true"; 5607 if (genealogy_fetch_time != 0) { 5608 // If we append the floating point value with << we'll get it in 5609 // scientific 5610 // notation. 5611 char floating_point_ascii_buffer[64]; 5612 floating_point_ascii_buffer[0] = '\0'; 5613 snprintf(floating_point_ascii_buffer, 5614 sizeof(floating_point_ascii_buffer), "%f", 5615 genealogy_fetch_time); 5616 if (strlen(floating_point_ascii_buffer) > 0) { 5617 json << ","; 5618 json << "\"activity_query_duration\":" 5619 << floating_point_ascii_buffer; 5620 } 5621 } 5622 } 5623 } 5624 5625 if (tsd_address != INVALID_NUB_ADDRESS) { 5626 if (need_to_print_comma) 5627 json << ","; 5628 need_to_print_comma = true; 5629 json << "\"tsd_address\":" << tsd_address; 5630 5631 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) { 5632 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread( 5633 pid, tid, tsd_address, dti_qos_class_index); 5634 if (requested_qos.IsValid()) { 5635 if (need_to_print_comma) 5636 json << ","; 5637 need_to_print_comma = true; 5638 json << "\"requested_qos\":{"; 5639 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5640 json << "\"constant_name\":\"" 5641 << json_string_quote_metachars(requested_qos.constant_name) 5642 << "\","; 5643 json << "\"printable_name\":\"" 5644 << json_string_quote_metachars(requested_qos.printable_name) 5645 << "\""; 5646 json << "}"; 5647 } 5648 } 5649 } 5650 5651 if (pthread_t_value != INVALID_NUB_ADDRESS) { 5652 if (need_to_print_comma) 5653 json << ","; 5654 need_to_print_comma = true; 5655 json << "\"pthread_t\":" << pthread_t_value; 5656 } 5657 5658 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT(pid, tid); 5659 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) { 5660 if (need_to_print_comma) 5661 json << ","; 5662 need_to_print_comma = true; 5663 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5664 } 5665 5666 json << "}"; 5667 std::string json_quoted = binary_encode_string(json.str()); 5668 return SendPacket(json_quoted); 5669 } 5670 } 5671 return SendPacket("OK"); 5672 } 5673 5674 // This packet may be called in one of three ways: 5675 // 5676 // jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704} 5677 // Look for an array of the old dyld_all_image_infos style of binary infos 5678 // at the image_list_address. 5679 // This an array of {void* load_addr, void* mod_date, void* pathname} 5680 // 5681 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} 5682 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5683 // get a list of all the 5684 // libraries loaded 5685 // 5686 // jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} 5687 // Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to 5688 // get the information 5689 // about the libraries loaded at these addresses. 5690 // 5691 rnb_err_t 5692 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p) { 5693 nub_process_t pid; 5694 // If we haven't run the process yet, return an error. 5695 if (!m_ctx.HasValidProcessID()) { 5696 return SendPacket("E83"); 5697 } 5698 5699 pid = m_ctx.ProcessID(); 5700 5701 const char get_loaded_dynamic_libraries_infos_str[] = { 5702 "jGetLoadedDynamicLibrariesInfos:{"}; 5703 if (strncmp(p, get_loaded_dynamic_libraries_infos_str, 5704 sizeof(get_loaded_dynamic_libraries_infos_str) - 1) == 0) { 5705 p += strlen(get_loaded_dynamic_libraries_infos_str); 5706 5707 JSONGenerator::ObjectSP json_sp; 5708 5709 std::vector<uint64_t> macho_addresses; 5710 bool fetch_all_solibs = false; 5711 if (get_boolean_value_for_key_name_from_json("fetch_all_solibs", p, 5712 fetch_all_solibs) && 5713 fetch_all_solibs) { 5714 json_sp = DNBGetAllLoadedLibrariesInfos(pid); 5715 } else if (get_array_of_ints_value_for_key_name_from_json( 5716 "solib_addresses", p, macho_addresses)) { 5717 json_sp = DNBGetLibrariesInfoForAddresses(pid, macho_addresses); 5718 } else { 5719 nub_addr_t image_list_address = 5720 get_integer_value_for_key_name_from_json("image_list_address", p); 5721 nub_addr_t image_count = 5722 get_integer_value_for_key_name_from_json("image_count", p); 5723 5724 if (image_list_address != INVALID_NUB_ADDRESS && 5725 image_count != INVALID_NUB_ADDRESS) { 5726 json_sp = DNBGetLoadedDynamicLibrariesInfos(pid, image_list_address, 5727 image_count); 5728 } 5729 } 5730 5731 if (json_sp.get()) { 5732 std::ostringstream json_str; 5733 json_sp->Dump(json_str); 5734 if (json_str.str().size() > 0) { 5735 std::string json_str_quoted = binary_encode_string(json_str.str()); 5736 return SendPacket(json_str_quoted.c_str()); 5737 } else { 5738 SendPacket("E84"); 5739 } 5740 } 5741 } 5742 return SendPacket("OK"); 5743 } 5744 5745 // This packet does not currently take any arguments. So the behavior is 5746 // jGetSharedCacheInfo:{} 5747 // send information about the inferior's shared cache 5748 // jGetSharedCacheInfo: 5749 // send "OK" to indicate that this packet is supported 5750 rnb_err_t RNBRemote::HandlePacket_jGetSharedCacheInfo(const char *p) { 5751 nub_process_t pid; 5752 // If we haven't run the process yet, return an error. 5753 if (!m_ctx.HasValidProcessID()) { 5754 return SendPacket("E85"); 5755 } 5756 5757 pid = m_ctx.ProcessID(); 5758 5759 const char get_shared_cache_info_str[] = {"jGetSharedCacheInfo:{"}; 5760 if (strncmp(p, get_shared_cache_info_str, 5761 sizeof(get_shared_cache_info_str) - 1) == 0) { 5762 JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo(pid); 5763 5764 if (json_sp.get()) { 5765 std::ostringstream json_str; 5766 json_sp->Dump(json_str); 5767 if (json_str.str().size() > 0) { 5768 std::string json_str_quoted = binary_encode_string(json_str.str()); 5769 return SendPacket(json_str_quoted.c_str()); 5770 } else { 5771 SendPacket("E86"); 5772 } 5773 } 5774 } 5775 return SendPacket("OK"); 5776 } 5777 5778 static bool MachHeaderIsMainExecutable(nub_process_t pid, uint32_t addr_size, 5779 nub_addr_t mach_header_addr, 5780 mach_header &mh) { 5781 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, " 5782 "addr_size = %u, mach_header_addr = " 5783 "0x%16.16llx)", 5784 pid, addr_size, mach_header_addr); 5785 const nub_size_t bytes_read = 5786 DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh); 5787 if (bytes_read == sizeof(mh)) { 5788 DNBLogThreadedIf( 5789 LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = " 5790 "%u, mach_header_addr = 0x%16.16llx): mh = {\n magic = " 5791 "0x%8.8x\n cpu = 0x%8.8x\n sub = 0x%8.8x\n filetype = " 5792 "%u\n ncmds = %u\n sizeofcmds = 0x%8.8x\n flags = " 5793 "0x%8.8x }", 5794 pid, addr_size, mach_header_addr, mh.magic, mh.cputype, mh.cpusubtype, 5795 mh.filetype, mh.ncmds, mh.sizeofcmds, mh.flags); 5796 if ((addr_size == 4 && mh.magic == MH_MAGIC) || 5797 (addr_size == 8 && mh.magic == MH_MAGIC_64)) { 5798 if (mh.filetype == MH_EXECUTE) { 5799 DNBLogThreadedIf(LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = " 5800 "%u, addr_size = %u, mach_header_addr = " 5801 "0x%16.16llx) -> this is the " 5802 "executable!!!", 5803 pid, addr_size, mach_header_addr); 5804 return true; 5805 } 5806 } 5807 } 5808 return false; 5809 } 5810 5811 static nub_addr_t GetMachHeaderForMainExecutable(const nub_process_t pid, 5812 const uint32_t addr_size, 5813 mach_header &mh) { 5814 struct AllImageInfos { 5815 uint32_t version; 5816 uint32_t dylib_info_count; 5817 uint64_t dylib_info_addr; 5818 }; 5819 5820 uint64_t mach_header_addr = 0; 5821 5822 const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress(pid); 5823 uint8_t bytes[256]; 5824 nub_size_t bytes_read = 0; 5825 DNBDataRef data(bytes, sizeof(bytes), false); 5826 DNBDataRef::offset_t offset = 0; 5827 data.SetPointerSize(addr_size); 5828 5829 //---------------------------------------------------------------------- 5830 // When we are sitting at __dyld_start, the kernel has placed the 5831 // address of the mach header of the main executable on the stack. If we 5832 // read the SP and dereference a pointer, we might find the mach header 5833 // for the executable. We also just make sure there is only 1 thread 5834 // since if we are at __dyld_start we shouldn't have multiple threads. 5835 //---------------------------------------------------------------------- 5836 if (DNBProcessGetNumThreads(pid) == 1) { 5837 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0); 5838 if (tid != INVALID_NUB_THREAD) { 5839 DNBRegisterValue sp_value; 5840 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, 5841 GENERIC_REGNUM_SP, &sp_value)) { 5842 uint64_t sp = 5843 addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32; 5844 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes); 5845 if (bytes_read == addr_size) { 5846 offset = 0; 5847 mach_header_addr = data.GetPointer(&offset); 5848 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5849 return mach_header_addr; 5850 } 5851 } 5852 } 5853 } 5854 5855 //---------------------------------------------------------------------- 5856 // Check the dyld_all_image_info structure for a list of mach header 5857 // since it is a very easy thing to check 5858 //---------------------------------------------------------------------- 5859 if (shlib_addr != INVALID_NUB_ADDRESS) { 5860 bytes_read = 5861 DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes); 5862 if (bytes_read > 0) { 5863 AllImageInfos aii; 5864 offset = 0; 5865 aii.version = data.Get32(&offset); 5866 aii.dylib_info_count = data.Get32(&offset); 5867 if (aii.dylib_info_count > 0) { 5868 aii.dylib_info_addr = data.GetPointer(&offset); 5869 if (aii.dylib_info_addr != 0) { 5870 const size_t image_info_byte_size = 3 * addr_size; 5871 for (uint32_t i = 0; i < aii.dylib_info_count; ++i) { 5872 bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + 5873 i * image_info_byte_size, 5874 image_info_byte_size, bytes); 5875 if (bytes_read != image_info_byte_size) 5876 break; 5877 offset = 0; 5878 mach_header_addr = data.GetPointer(&offset); 5879 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, 5880 mh)) 5881 return mach_header_addr; 5882 } 5883 } 5884 } 5885 } 5886 } 5887 5888 //---------------------------------------------------------------------- 5889 // We failed to find the executable's mach header from the all image 5890 // infos and by dereferencing the stack pointer. Now we fall back to 5891 // enumerating the memory regions and looking for regions that are 5892 // executable. 5893 //---------------------------------------------------------------------- 5894 DNBRegionInfo region_info; 5895 mach_header_addr = 0; 5896 while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, ®ion_info)) { 5897 if (region_info.size == 0) 5898 break; 5899 5900 if (region_info.permissions & eMemoryPermissionsExecutable) { 5901 DNBLogThreadedIf( 5902 LOG_RNB_PROC, "[0x%16.16llx - 0x%16.16llx) permissions = %c%c%c: " 5903 "checking region for executable mach header", 5904 region_info.addr, region_info.addr + region_info.size, 5905 (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', 5906 (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', 5907 (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-'); 5908 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5909 return mach_header_addr; 5910 } else { 5911 DNBLogThreadedIf( 5912 LOG_RNB_PROC, 5913 "[0x%16.16llx - 0x%16.16llx): permissions = %c%c%c: skipping region", 5914 region_info.addr, region_info.addr + region_info.size, 5915 (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', 5916 (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', 5917 (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-'); 5918 } 5919 // Set the address to the next mapped region 5920 mach_header_addr = region_info.addr + region_info.size; 5921 } 5922 bzero(&mh, sizeof(mh)); 5923 return INVALID_NUB_ADDRESS; 5924 } 5925 5926 rnb_err_t RNBRemote::HandlePacket_qSymbol(const char *command) { 5927 const char *p = command; 5928 p += strlen("qSymbol:"); 5929 const char *sep = strchr(p, ':'); 5930 5931 std::string symbol_name; 5932 std::string symbol_value_str; 5933 // Extract the symbol value if there is one 5934 if (sep > p) 5935 symbol_value_str.assign(p, sep - p); 5936 p = sep + 1; 5937 5938 if (*p) { 5939 // We have a symbol name 5940 symbol_name = decode_hex_ascii_string(p); 5941 if (!symbol_value_str.empty()) { 5942 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5943 if (symbol_name == "dispatch_queue_offsets") 5944 m_dispatch_queue_offsets_addr = symbol_value; 5945 } 5946 ++m_qSymbol_index; 5947 } else { 5948 // No symbol name, set our symbol index to zero so we can 5949 // read any symbols that we need 5950 m_qSymbol_index = 0; 5951 } 5952 5953 symbol_name.clear(); 5954 5955 if (m_qSymbol_index == 0) { 5956 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5957 symbol_name = "dispatch_queue_offsets"; 5958 else 5959 ++m_qSymbol_index; 5960 } 5961 5962 // // Lookup next symbol when we have one... 5963 // if (m_qSymbol_index == 1) 5964 // { 5965 // } 5966 5967 if (symbol_name.empty()) { 5968 // Done with symbol lookups 5969 return SendPacket("OK"); 5970 } else { 5971 std::ostringstream reply; 5972 reply << "qSymbol:"; 5973 for (size_t i = 0; i < symbol_name.size(); ++i) 5974 reply << RAWHEX8(symbol_name[i]); 5975 return SendPacket(reply.str().c_str()); 5976 } 5977 } 5978 5979 // Note that all numeric values returned by qProcessInfo are hex encoded, 5980 // including the pid and the cpu type. 5981 5982 rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) { 5983 nub_process_t pid; 5984 std::ostringstream rep; 5985 5986 // If we haven't run the process yet, return an error. 5987 if (!m_ctx.HasValidProcessID()) 5988 return SendPacket("E68"); 5989 5990 pid = m_ctx.ProcessID(); 5991 5992 rep << "pid:" << std::hex << pid << ';'; 5993 5994 int procpid_mib[4]; 5995 procpid_mib[0] = CTL_KERN; 5996 procpid_mib[1] = KERN_PROC; 5997 procpid_mib[2] = KERN_PROC_PID; 5998 procpid_mib[3] = pid; 5999 struct kinfo_proc proc_kinfo; 6000 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 6001 6002 if (::sysctl(procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { 6003 if (proc_kinfo_size > 0) { 6004 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';'; 6005 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid 6006 << ';'; 6007 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid 6008 << ';'; 6009 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid 6010 << ';'; 6011 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 6012 rep << "effective-gid:" << std::hex 6013 << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';'; 6014 } 6015 } 6016 6017 cpu_type_t cputype = DNBProcessGetCPUType(pid); 6018 if (cputype == 0) { 6019 DNBLog("Unable to get the process cpu_type, making a best guess."); 6020 cputype = best_guess_cpu_type(); 6021 } 6022 6023 uint32_t addr_size = 0; 6024 if (cputype != 0) { 6025 rep << "cputype:" << std::hex << cputype << ";"; 6026 if (cputype & CPU_ARCH_ABI64) 6027 addr_size = 8; 6028 else 6029 addr_size = 4; 6030 } 6031 6032 bool host_cpu_is_64bit = false; 6033 uint32_t is64bit_capable; 6034 size_t is64bit_capable_len = sizeof(is64bit_capable); 6035 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, 6036 &is64bit_capable_len, NULL, 0) == 0) 6037 host_cpu_is_64bit = is64bit_capable != 0; 6038 6039 uint32_t cpusubtype; 6040 size_t cpusubtype_len = sizeof(cpusubtype); 6041 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 6042 0) { 6043 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 6044 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 6045 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu 6046 // subtype 6047 // for i386... 6048 if (host_cpu_is_64bit) { 6049 if (cputype == CPU_TYPE_X86) { 6050 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 6051 } else if (cputype == CPU_TYPE_ARM) { 6052 // We can query a process' cputype but we cannot query a process' 6053 // cpusubtype. 6054 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit 6055 // process) and we 6056 // need to override the host cpusubtype (which is in the 6057 // CPU_SUBTYPE_ARM64 subtype namespace) 6058 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 6059 cpusubtype = 12; // CPU_SUBTYPE_ARM_V7K 6060 } 6061 } 6062 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 6063 } 6064 6065 bool os_handled = false; 6066 if (addr_size > 0) { 6067 rep << "ptrsize:" << std::dec << addr_size << ';'; 6068 6069 #if (defined(__x86_64__) || defined(__i386__)) 6070 // Try and get the OS type by looking at the load commands in the main 6071 // executable and looking for a LC_VERSION_MIN load command. This is the 6072 // most reliable way to determine the "ostype" value when on desktop. 6073 6074 mach_header mh; 6075 nub_addr_t exe_mach_header_addr = 6076 GetMachHeaderForMainExecutable(pid, addr_size, mh); 6077 if (exe_mach_header_addr != INVALID_NUB_ADDRESS) { 6078 uint64_t load_command_addr = 6079 exe_mach_header_addr + 6080 ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header)); 6081 load_command lc; 6082 for (uint32_t i = 0; i < mh.ncmds && !os_handled; ++i) { 6083 const nub_size_t bytes_read = 6084 DNBProcessMemoryRead(pid, load_command_addr, sizeof(lc), &lc); 6085 uint32_t raw_cmd = lc.cmd & ~LC_REQ_DYLD; 6086 if (bytes_read != sizeof(lc)) 6087 break; 6088 switch (raw_cmd) { 6089 case LC_VERSION_MIN_IPHONEOS: 6090 os_handled = true; 6091 rep << "ostype:ios;"; 6092 DNBLogThreadedIf(LOG_RNB_PROC, 6093 "LC_VERSION_MIN_IPHONEOS -> 'ostype:ios;'"); 6094 break; 6095 6096 case LC_VERSION_MIN_MACOSX: 6097 os_handled = true; 6098 rep << "ostype:macosx;"; 6099 DNBLogThreadedIf(LOG_RNB_PROC, 6100 "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'"); 6101 break; 6102 6103 #if defined(LC_VERSION_MIN_TVOS) 6104 case LC_VERSION_MIN_TVOS: 6105 os_handled = true; 6106 rep << "ostype:tvos;"; 6107 DNBLogThreadedIf(LOG_RNB_PROC, 6108 "LC_VERSION_MIN_TVOS -> 'ostype:tvos;'"); 6109 break; 6110 #endif 6111 6112 #if defined(LC_VERSION_MIN_WATCHOS) 6113 case LC_VERSION_MIN_WATCHOS: 6114 os_handled = true; 6115 rep << "ostype:watchos;"; 6116 DNBLogThreadedIf(LOG_RNB_PROC, 6117 "LC_VERSION_MIN_WATCHOS -> 'ostype:watchos;'"); 6118 break; 6119 #endif 6120 6121 default: 6122 break; 6123 } 6124 load_command_addr = load_command_addr + lc.cmdsize; 6125 } 6126 } 6127 #endif 6128 } 6129 6130 // If we weren't able to find the OS in a LC_VERSION_MIN load command, try 6131 // to set it correctly by using the cpu type and other tricks 6132 if (!os_handled) { 6133 // The OS in the triple should be "ios" or "macosx" which doesn't match our 6134 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 6135 // this for now. 6136 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) { 6137 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6138 rep << "ostype:tvos;"; 6139 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6140 rep << "ostype:watchos;"; 6141 #else 6142 rep << "ostype:ios;"; 6143 #endif 6144 } else { 6145 bool is_ios_simulator = false; 6146 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) { 6147 // Check for iOS simulator binaries by getting the process argument 6148 // and environment and checking for SIMULATOR_UDID in the environment 6149 int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2, (int)pid}; 6150 6151 uint8_t arg_data[8192]; 6152 size_t arg_data_size = sizeof(arg_data); 6153 if (::sysctl(proc_args_mib, 3, arg_data, &arg_data_size, NULL, 0) == 6154 0) { 6155 DNBDataRef data(arg_data, arg_data_size, false); 6156 DNBDataRef::offset_t offset = 0; 6157 uint32_t argc = data.Get32(&offset); 6158 const char *cstr; 6159 6160 cstr = data.GetCStr(&offset); 6161 if (cstr) { 6162 // Skip NULLs 6163 while (1) { 6164 const char *p = data.PeekCStr(offset); 6165 if ((p == NULL) || (*p != '\0')) 6166 break; 6167 ++offset; 6168 } 6169 // Now skip all arguments 6170 for (uint32_t i = 0; i < argc; ++i) { 6171 data.GetCStr(&offset); 6172 } 6173 6174 // Now iterate across all environment variables 6175 while ((cstr = data.GetCStr(&offset))) { 6176 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 6177 0) { 6178 is_ios_simulator = true; 6179 break; 6180 } 6181 if (cstr[0] == '\0') 6182 break; 6183 } 6184 } 6185 } 6186 } 6187 if (is_ios_simulator) { 6188 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 6189 rep << "ostype:tvos;"; 6190 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 6191 rep << "ostype:watchos;"; 6192 #else 6193 rep << "ostype:ios;"; 6194 #endif 6195 } else { 6196 rep << "ostype:macosx;"; 6197 } 6198 } 6199 } 6200 6201 rep << "vendor:apple;"; 6202 6203 #if defined(__LITTLE_ENDIAN__) 6204 rep << "endian:little;"; 6205 #elif defined(__BIG_ENDIAN__) 6206 rep << "endian:big;"; 6207 #elif defined(__PDP_ENDIAN__) 6208 rep << "endian:pdp;"; 6209 #endif 6210 6211 if (addr_size == 0) { 6212 #if (defined(__x86_64__) || defined(__i386__)) && defined(x86_THREAD_STATE) 6213 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6214 kern_return_t kr; 6215 x86_thread_state_t gp_regs; 6216 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 6217 kr = thread_get_state(static_cast<thread_act_t>(thread), x86_THREAD_STATE, 6218 (thread_state_t)&gp_regs, &gp_count); 6219 if (kr == KERN_SUCCESS) { 6220 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 6221 rep << "ptrsize:8;"; 6222 else 6223 rep << "ptrsize:4;"; 6224 } 6225 #elif defined(__arm__) 6226 rep << "ptrsize:4;"; 6227 #elif (defined(__arm64__) || defined(__aarch64__)) && \ 6228 defined(ARM_UNIFIED_THREAD_STATE) 6229 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort(pid); 6230 kern_return_t kr; 6231 arm_unified_thread_state_t gp_regs; 6232 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 6233 kr = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE, 6234 (thread_state_t)&gp_regs, &gp_count); 6235 if (kr == KERN_SUCCESS) { 6236 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 6237 rep << "ptrsize:8;"; 6238 else 6239 rep << "ptrsize:4;"; 6240 } 6241 #endif 6242 } 6243 6244 return SendPacket(rep.str()); 6245 } 6246 6247 const RNBRemote::DispatchQueueOffsets *RNBRemote::GetDispatchQueueOffsets() { 6248 if (!m_dispatch_queue_offsets.IsValid() && 6249 m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && 6250 m_ctx.HasValidProcessID()) { 6251 nub_process_t pid = m_ctx.ProcessID(); 6252 nub_size_t bytes_read = DNBProcessMemoryRead( 6253 pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), 6254 &m_dispatch_queue_offsets); 6255 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 6256 m_dispatch_queue_offsets.Clear(); 6257 } 6258 6259 if (m_dispatch_queue_offsets.IsValid()) 6260 return &m_dispatch_queue_offsets; 6261 else 6262 return nullptr; 6263 } 6264 6265 void RNBRemote::EnableCompressionNextSendPacket(compression_types type) { 6266 m_compression_mode = type; 6267 m_enable_compression_next_send_packet = true; 6268 } 6269 6270 compression_types RNBRemote::GetCompressionType() { 6271 // The first packet we send back to the debugger after a QEnableCompression 6272 // request 6273 // should be uncompressed -- so we can indicate whether the compression was 6274 // enabled 6275 // or not via OK / Enn returns. After that, all packets sent will be using 6276 // the 6277 // compression protocol. 6278 6279 if (m_enable_compression_next_send_packet) { 6280 // One time, we send back "None" as our compression type 6281 m_enable_compression_next_send_packet = false; 6282 return compression_types::none; 6283 } 6284 return m_compression_mode; 6285 } 6286