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