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