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