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