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