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