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