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 DNBLogThreaded ("RNBRemote::HandlePacket_stop_process() sending extra stop reply because DNBProcessInterrupt returned false"); 4437 HandlePacket_last_signal (NULL); 4438 } 4439 return rnb_success; 4440 #endif 4441 } 4442 4443 /* 's' 4444 Step the inferior process. */ 4445 4446 rnb_err_t 4447 RNBRemote::HandlePacket_s (const char *p) 4448 { 4449 const nub_process_t pid = m_ctx.ProcessID(); 4450 if (pid == INVALID_NUB_PROCESS) 4451 return SendPacket ("E32"); 4452 4453 // Hardware supported stepping not supported on arm 4454 nub_thread_t tid = GetContinueThread (); 4455 if (tid == 0 || tid == (nub_thread_t)-1) 4456 tid = GetCurrentThread(); 4457 4458 if (tid == INVALID_NUB_THREAD) 4459 return SendPacket ("E33"); 4460 4461 DNBThreadResumeActions thread_actions; 4462 thread_actions.AppendAction(tid, eStateStepping); 4463 4464 // Make all other threads stop when we are stepping 4465 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 4466 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4467 return SendPacket ("E49"); 4468 // Don't send an "OK" packet; response is the stopped/exited message. 4469 return rnb_success; 4470 } 4471 4472 /* 'S sig [;addr]' 4473 Step with signal sig, optionally at address addr. */ 4474 4475 rnb_err_t 4476 RNBRemote::HandlePacket_S (const char *p) 4477 { 4478 const nub_process_t pid = m_ctx.ProcessID(); 4479 if (pid == INVALID_NUB_PROCESS) 4480 return SendPacket ("E36"); 4481 4482 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 4483 4484 if (*(p + 1) != '\0') 4485 { 4486 char *end = NULL; 4487 errno = 0; 4488 action.signal = static_cast<int>(strtoul (p + 1, &end, 16)); 4489 if (errno != 0) 4490 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 4491 else if (*end == ';') 4492 { 4493 errno = 0; 4494 action.addr = strtoull (end + 1, NULL, 16); 4495 if (errno != 0 && action.addr == 0) 4496 { 4497 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 4498 } 4499 } 4500 } 4501 4502 action.tid = GetContinueThread (); 4503 if (action.tid == 0 || action.tid == (nub_thread_t)-1) 4504 return SendPacket ("E40"); 4505 4506 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 4507 if (tstate == eStateInvalid || tstate == eStateExited) 4508 return SendPacket ("E37"); 4509 4510 4511 DNBThreadResumeActions thread_actions; 4512 thread_actions.Append (action); 4513 4514 // Make all other threads stop when we are stepping 4515 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4516 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4517 return SendPacket ("E39"); 4518 4519 // Don't send an "OK" packet; response is the stopped/exited message. 4520 return rnb_success; 4521 } 4522 4523 static const char * 4524 GetArchName (const uint32_t cputype, const uint32_t cpusubtype) 4525 { 4526 switch (cputype) 4527 { 4528 case CPU_TYPE_ARM: 4529 switch (cpusubtype) 4530 { 4531 case 5: return "armv4"; 4532 case 6: return "armv6"; 4533 case 7: return "armv5t"; 4534 case 8: return "xscale"; 4535 case 9: return "armv7"; 4536 case 10: return "armv7f"; 4537 case 11: return "armv7s"; 4538 case 12: return "armv7k"; 4539 case 14: return "armv6m"; 4540 case 15: return "armv7m"; 4541 case 16: return "armv7em"; 4542 default: return "arm"; 4543 } 4544 break; 4545 case CPU_TYPE_ARM64: return "arm64"; 4546 case CPU_TYPE_I386: return "i386"; 4547 case CPU_TYPE_X86_64: 4548 switch (cpusubtype) 4549 { 4550 default: return "x86_64"; 4551 case 8: return "x86_64h"; 4552 } 4553 break; 4554 } 4555 return NULL; 4556 } 4557 4558 static bool 4559 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64) 4560 { 4561 static uint32_t g_host_cputype = 0; 4562 static uint32_t g_host_cpusubtype = 0; 4563 static uint32_t g_is_64_bit_capable = 0; 4564 static bool g_promoted_to_64 = false; 4565 4566 if (g_host_cputype == 0) 4567 { 4568 g_promoted_to_64 = false; 4569 size_t len = sizeof(uint32_t); 4570 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) 4571 { 4572 len = sizeof (uint32_t); 4573 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0) 4574 { 4575 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) 4576 { 4577 g_promoted_to_64 = true; 4578 g_host_cputype |= CPU_ARCH_ABI64; 4579 } 4580 } 4581 } 4582 4583 len = sizeof(uint32_t); 4584 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0) 4585 { 4586 if (g_promoted_to_64 && 4587 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486) 4588 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4589 } 4590 } 4591 4592 cputype = g_host_cputype; 4593 cpusubtype = g_host_cpusubtype; 4594 is_64_bit_capable = g_is_64_bit_capable; 4595 promoted_to_64 = g_promoted_to_64; 4596 return g_host_cputype != 0; 4597 } 4598 4599 rnb_err_t 4600 RNBRemote::HandlePacket_qHostInfo (const char *p) 4601 { 4602 std::ostringstream strm; 4603 4604 uint32_t cputype = 0; 4605 uint32_t cpusubtype = 0; 4606 uint32_t is_64_bit_capable = 0; 4607 bool promoted_to_64 = false; 4608 if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) 4609 { 4610 strm << "cputype:" << std::dec << cputype << ';'; 4611 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4612 } 4613 4614 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4615 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4616 // this for now. 4617 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 4618 { 4619 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 4620 strm << "ostype:tvos;"; 4621 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4622 strm << "ostype:watchos;"; 4623 #else 4624 strm << "ostype:ios;"; 4625 #endif 4626 4627 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 4628 strm << "watchpoint_exceptions_received:before;"; 4629 } 4630 else 4631 { 4632 strm << "ostype:macosx;"; 4633 strm << "watchpoint_exceptions_received:after;"; 4634 } 4635 // char ostype[64]; 4636 // len = sizeof(ostype); 4637 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4638 // { 4639 // len = strlen(ostype); 4640 // std::transform (ostype, ostype + len, ostype, tolower); 4641 // strm << "ostype:" << std::dec << ostype << ';'; 4642 // } 4643 4644 strm << "vendor:apple;"; 4645 4646 uint64_t major, minor, patch; 4647 if (DNBGetOSVersionNumbers (&major, &minor, &patch)) 4648 { 4649 strm << "os_version:" << major << "." << minor; 4650 if (patch != UINT64_MAX) 4651 strm << "." << patch; 4652 strm << ";"; 4653 } 4654 4655 #if defined (__LITTLE_ENDIAN__) 4656 strm << "endian:little;"; 4657 #elif defined (__BIG_ENDIAN__) 4658 strm << "endian:big;"; 4659 #elif defined (__PDP_ENDIAN__) 4660 strm << "endian:pdp;"; 4661 #endif 4662 4663 if (promoted_to_64) 4664 strm << "ptrsize:8;"; 4665 else 4666 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4667 4668 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4669 strm << "default_packet_timeout:10;"; 4670 #endif 4671 4672 return SendPacket (strm.str()); 4673 } 4674 4675 void 4676 XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes) 4677 { 4678 if (indent) 4679 s << INDENT_WITH_SPACES(indent); 4680 s << '<' << name; 4681 if (!has_attributes) 4682 s << '>' << std::endl; 4683 } 4684 4685 void 4686 XMLElementStartEndAttributes (std::ostringstream &s, bool empty) 4687 { 4688 if (empty) 4689 s << '/'; 4690 s << '>' << std::endl; 4691 } 4692 4693 void 4694 XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name) 4695 { 4696 if (indent) 4697 s << INDENT_WITH_SPACES(indent); 4698 s << '<' << '/' << name << '>' << std::endl; 4699 } 4700 4701 void 4702 XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true) 4703 { 4704 if (value) 4705 { 4706 if (indent) 4707 s << INDENT_WITH_SPACES(indent); 4708 s << '<' << name << '>' << value; 4709 if (close) 4710 XMLElementEnd(s, 0, name); 4711 } 4712 } 4713 4714 void 4715 XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true) 4716 { 4717 if (indent) 4718 s << INDENT_WITH_SPACES(indent); 4719 4720 s << '<' << name << '>' << DECIMAL << value; 4721 if (close) 4722 XMLElementEnd(s, 0, name); 4723 } 4724 4725 void 4726 XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL) 4727 { 4728 if (value) 4729 { 4730 if (default_value && strcmp(value, default_value) == 0) 4731 return; // No need to emit the attribute because it matches the default value 4732 s <<' ' << name << "=\"" << value << "\""; 4733 } 4734 } 4735 4736 void 4737 XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value) 4738 { 4739 s <<' ' << name << "=\"" << DECIMAL << value << "\""; 4740 } 4741 4742 void 4743 GenerateTargetXMLRegister (std::ostringstream &s, 4744 const uint32_t reg_num, 4745 nub_size_t num_reg_sets, 4746 const DNBRegisterSetInfo *reg_set_info, 4747 const register_map_entry_t ®) 4748 { 4749 const char *default_lldb_encoding = "uint"; 4750 const char *lldb_encoding = default_lldb_encoding; 4751 const char *gdb_group = "general"; 4752 const char *default_gdb_type = "int"; 4753 const char *gdb_type = default_gdb_type; 4754 const char *default_lldb_format = "hex"; 4755 const char *lldb_format = default_lldb_format; 4756 const char *lldb_set = NULL; 4757 4758 switch (reg.nub_info.type) 4759 { 4760 case Uint: lldb_encoding = "uint"; break; 4761 case Sint: lldb_encoding = "sint"; break; 4762 case IEEE754: lldb_encoding = "ieee754"; if (reg.nub_info.set > 0) gdb_group = "float"; break; 4763 case Vector: lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break; 4764 } 4765 4766 switch (reg.nub_info.format) 4767 { 4768 case Binary: lldb_format = "binary"; break; 4769 case Decimal: lldb_format = "decimal"; break; 4770 case Hex: lldb_format = "hex"; break; 4771 case Float: gdb_type = "float"; lldb_format = "float"; break; 4772 case VectorOfSInt8: gdb_type = "float"; lldb_format = "vector-sint8"; break; 4773 case VectorOfUInt8: gdb_type = "float"; lldb_format = "vector-uint8"; break; 4774 case VectorOfSInt16: gdb_type = "float"; lldb_format = "vector-sint16"; break; 4775 case VectorOfUInt16: gdb_type = "float"; lldb_format = "vector-uint16"; break; 4776 case VectorOfSInt32: gdb_type = "float"; lldb_format = "vector-sint32"; break; 4777 case VectorOfUInt32: gdb_type = "float"; lldb_format = "vector-uint32"; break; 4778 case VectorOfFloat32: gdb_type = "float"; lldb_format = "vector-float32"; break; 4779 case VectorOfUInt128: gdb_type = "float"; lldb_format = "vector-uint128"; break; 4780 }; 4781 if (reg_set_info && reg.nub_info.set < num_reg_sets) 4782 lldb_set = reg_set_info[reg.nub_info.set].name; 4783 4784 uint32_t indent = 2; 4785 4786 XMLElementStart(s, indent, "reg", true); 4787 XMLAttributeString(s, "name", reg.nub_info.name); 4788 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 4789 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 4790 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 4791 XMLAttributeString(s, "group", gdb_group); 4792 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 4793 XMLAttributeString (s, "altname", reg.nub_info.alt); 4794 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 4795 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 4796 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 4797 if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM) 4798 XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe); 4799 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 4800 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 4801 4802 const char *lldb_generic = NULL; 4803 switch (reg.nub_info.reg_generic) 4804 { 4805 case GENERIC_REGNUM_FP: lldb_generic = "fp"; break; 4806 case GENERIC_REGNUM_PC: lldb_generic = "pc"; break; 4807 case GENERIC_REGNUM_SP: lldb_generic = "sp"; break; 4808 case GENERIC_REGNUM_RA: lldb_generic = "ra"; break; 4809 case GENERIC_REGNUM_FLAGS: lldb_generic = "flags"; break; 4810 case GENERIC_REGNUM_ARG1: lldb_generic = "arg1"; break; 4811 case GENERIC_REGNUM_ARG2: lldb_generic = "arg2"; break; 4812 case GENERIC_REGNUM_ARG3: lldb_generic = "arg3"; break; 4813 case GENERIC_REGNUM_ARG4: lldb_generic = "arg4"; break; 4814 case GENERIC_REGNUM_ARG5: lldb_generic = "arg5"; break; 4815 case GENERIC_REGNUM_ARG6: lldb_generic = "arg6"; break; 4816 case GENERIC_REGNUM_ARG7: lldb_generic = "arg7"; break; 4817 case GENERIC_REGNUM_ARG8: lldb_generic = "arg8"; break; 4818 default: break; 4819 } 4820 XMLAttributeString(s, "generic", lldb_generic); 4821 4822 4823 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 4824 if (!empty) 4825 { 4826 if (!reg.value_regnums.empty()) 4827 { 4828 std::ostringstream regnums; 4829 bool first = true; 4830 regnums << DECIMAL; 4831 for (auto regnum : reg.value_regnums) 4832 { 4833 if (!first) 4834 regnums << ','; 4835 regnums << regnum; 4836 first = false; 4837 } 4838 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 4839 } 4840 4841 if (!reg.invalidate_regnums.empty()) 4842 { 4843 std::ostringstream regnums; 4844 bool first = true; 4845 regnums << DECIMAL; 4846 for (auto regnum : reg.invalidate_regnums) 4847 { 4848 if (!first) 4849 regnums << ','; 4850 regnums << regnum; 4851 first = false; 4852 } 4853 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 4854 } 4855 } 4856 XMLElementStartEndAttributes(s, true); 4857 } 4858 4859 void 4860 GenerateTargetXMLRegisters (std::ostringstream &s) 4861 { 4862 nub_size_t num_reg_sets = 0; 4863 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets); 4864 4865 4866 uint32_t cputype = DNBGetRegisterCPUType(); 4867 if (cputype) 4868 { 4869 XMLElementStart(s, 0, "feature", true); 4870 std::ostringstream name_strm; 4871 name_strm << "com.apple.debugserver." << GetArchName (cputype, 0); 4872 XMLAttributeString(s, "name", name_strm.str().c_str()); 4873 XMLElementStartEndAttributes(s, false); 4874 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 4875 // for (const auto ®: g_dynamic_register_map) 4876 { 4877 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]); 4878 } 4879 XMLElementEnd(s, 0, "feature"); 4880 4881 if (num_reg_sets > 0) 4882 { 4883 XMLElementStart(s, 0, "groups", false); 4884 for (uint32_t set=1; set<num_reg_sets; ++set) 4885 { 4886 XMLElementStart(s, 2, "group", true); 4887 XMLAttributeUnsignedDecimal(s, "id", set); 4888 XMLAttributeString(s, "name", reg_sets[set].name); 4889 XMLElementStartEndAttributes(s, true); 4890 } 4891 XMLElementEnd(s, 0, "groups"); 4892 } 4893 } 4894 } 4895 4896 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 4897 <target version="1.0">)"; 4898 4899 static const char *g_target_xml_footer = "</target>"; 4900 4901 static std::string g_target_xml; 4902 4903 void 4904 UpdateTargetXML () 4905 { 4906 std::ostringstream s; 4907 s << g_target_xml_header << std::endl; 4908 4909 // Set the architecture 4910 //s << "<architecture>" << arch "</architecture>" << std::endl; 4911 4912 // Set the OSABI 4913 //s << "<osabi>abi-name</osabi>" 4914 4915 GenerateTargetXMLRegisters(s); 4916 4917 s << g_target_xml_footer << std::endl; 4918 4919 // Save the XML output in case it gets retrieved in chunks 4920 g_target_xml = s.str(); 4921 } 4922 4923 rnb_err_t 4924 RNBRemote::HandlePacket_qXfer (const char *command) 4925 { 4926 const char *p = command; 4927 p += strlen ("qXfer:"); 4928 const char *sep = strchr(p, ':'); 4929 if (sep) 4930 { 4931 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 4932 p = sep + 1; 4933 sep = strchr(p, ':'); 4934 if (sep) 4935 { 4936 std::string rw(p, sep - p); // "read" or "write" 4937 p = sep + 1; 4938 sep = strchr(p, ':'); 4939 if (sep) 4940 { 4941 std::string annex(p, sep - p); // "read" or "write" 4942 4943 p = sep + 1; 4944 sep = strchr(p, ','); 4945 if (sep) 4946 { 4947 std::string offset_str(p, sep - p); // read the length as a string 4948 p = sep + 1; 4949 std::string length_str(p); // read the offset as a string 4950 char *end = nullptr; 4951 const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset 4952 if (*end == '\0') 4953 { 4954 const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length 4955 if (*end == '\0') 4956 { 4957 if (object == "features" && 4958 rw == "read" && 4959 annex == "target.xml") 4960 { 4961 std::ostringstream xml_out; 4962 4963 if (offset == 0) 4964 { 4965 InitializeRegisters (true); 4966 4967 UpdateTargetXML(); 4968 if (g_target_xml.empty()) 4969 return SendPacket("E83"); 4970 4971 if (length > g_target_xml.size()) 4972 { 4973 xml_out << 'l'; // No more data 4974 xml_out << binary_encode_string(g_target_xml); 4975 } 4976 else 4977 { 4978 xml_out << 'm'; // More data needs to be read with a subsequent call 4979 xml_out << binary_encode_string(std::string(g_target_xml, offset, length)); 4980 } 4981 } 4982 else 4983 { 4984 // Retrieving target XML in chunks 4985 if (offset < g_target_xml.size()) 4986 { 4987 std::string chunk(g_target_xml, offset, length); 4988 if (chunk.size() < length) 4989 xml_out << 'l'; // No more data 4990 else 4991 xml_out << 'm'; // More data needs to be read with a subsequent call 4992 xml_out << binary_encode_string(chunk.data()); 4993 } 4994 } 4995 return SendPacket(xml_out.str()); 4996 } 4997 // Well formed, put not supported 4998 return HandlePacket_UNIMPLEMENTED (command); 4999 } 5000 } 5001 } 5002 } 5003 else 5004 { 5005 SendPacket ("E85"); 5006 } 5007 } 5008 else 5009 { 5010 SendPacket ("E86"); 5011 } 5012 } 5013 return SendPacket ("E82"); 5014 } 5015 5016 5017 rnb_err_t 5018 RNBRemote::HandlePacket_qGDBServerVersion (const char *p) 5019 { 5020 std::ostringstream strm; 5021 5022 #if defined(DEBUGSERVER_PROGRAM_NAME) 5023 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 5024 #else 5025 strm << "name:debugserver;"; 5026 #endif 5027 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 5028 5029 return SendPacket (strm.str()); 5030 } 5031 5032 // A helper function that retrieves a single integer value from 5033 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5034 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 5035 // 5036 uint64_t 5037 get_integer_value_for_key_name_from_json (const char *key, const char *json_string) 5038 { 5039 uint64_t retval = INVALID_NUB_ADDRESS; 5040 std::string key_with_quotes = "\""; 5041 key_with_quotes += key; 5042 key_with_quotes += "\""; 5043 const char *c = strstr (json_string, key_with_quotes.c_str()); 5044 if (c) 5045 { 5046 c += key_with_quotes.size(); 5047 5048 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5049 c++; 5050 5051 if (*c == ':') 5052 { 5053 c++; 5054 5055 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5056 c++; 5057 5058 errno = 0; 5059 retval = strtoul (c, NULL, 10); 5060 if (errno != 0) 5061 { 5062 retval = INVALID_NUB_ADDRESS; 5063 } 5064 } 5065 } 5066 return retval; 5067 5068 } 5069 5070 JSONGenerator::ObjectSP 5071 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) 5072 { 5073 JSONGenerator::ArraySP threads_array_sp; 5074 if (m_ctx.HasValidProcessID()) 5075 { 5076 threads_array_sp.reset(new JSONGenerator::Array()); 5077 5078 nub_process_t pid = m_ctx.ProcessID(); 5079 5080 nub_size_t numthreads = DNBProcessGetNumThreads (pid); 5081 for (nub_size_t i = 0; i < numthreads; ++i) 5082 { 5083 nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i); 5084 5085 struct DNBThreadStopInfo tid_stop_info; 5086 5087 const bool stop_info_valid = DNBThreadGetStopReason (pid, tid, &tid_stop_info); 5088 5089 // If we are doing stop info only, then we only show threads that have a 5090 // valid stop reason 5091 if (threads_with_valid_stop_info_only) 5092 { 5093 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5094 continue; 5095 } 5096 5097 JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary()); 5098 thread_dict_sp->AddIntegerItem("tid", tid); 5099 5100 std::string reason_value("none"); 5101 5102 if (stop_info_valid) 5103 { 5104 switch (tid_stop_info.reason) 5105 { 5106 case eStopTypeInvalid: 5107 break; 5108 5109 case eStopTypeSignal: 5110 if (tid_stop_info.details.signal.signo != 0) 5111 { 5112 thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo); 5113 reason_value = "signal"; 5114 } 5115 break; 5116 5117 case eStopTypeException: 5118 if (tid_stop_info.details.exception.type != 0) 5119 { 5120 reason_value = "exception"; 5121 thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type); 5122 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5123 for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i) 5124 { 5125 medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i]))); 5126 } 5127 thread_dict_sp->AddItem("medata", medata_array_sp); 5128 } 5129 break; 5130 5131 case eStopTypeExec: 5132 reason_value = "exec"; 5133 break; 5134 } 5135 } 5136 5137 thread_dict_sp->AddStringItem("reason", reason_value); 5138 5139 if (threads_with_valid_stop_info_only == false) 5140 { 5141 const char *thread_name = DNBThreadGetName (pid, tid); 5142 if (thread_name && thread_name[0]) 5143 thread_dict_sp->AddStringItem("name", thread_name); 5144 5145 thread_identifier_info_data_t thread_ident_info; 5146 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 5147 { 5148 if (thread_ident_info.dispatch_qaddr != 0) 5149 { 5150 thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr); 5151 5152 const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets(); 5153 if (dispatch_queue_offsets) 5154 { 5155 std::string queue_name; 5156 uint64_t queue_width = 0; 5157 uint64_t queue_serialnum = 0; 5158 nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS; 5159 dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, queue_name, queue_width, queue_serialnum); 5160 if (dispatch_queue_t == 0 && queue_name.empty() && queue_serialnum == 0) 5161 { 5162 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", false); 5163 } 5164 else 5165 { 5166 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", true); 5167 } 5168 if (dispatch_queue_t != INVALID_NUB_ADDRESS && dispatch_queue_t != 0) 5169 thread_dict_sp->AddIntegerItem("dispatch_queue_t", dispatch_queue_t); 5170 if (!queue_name.empty()) 5171 thread_dict_sp->AddStringItem("qname", queue_name); 5172 if (queue_width == 1) 5173 thread_dict_sp->AddStringItem("qkind", "serial"); 5174 else if (queue_width > 1) 5175 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5176 if (queue_serialnum > 0) 5177 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum); 5178 } 5179 } 5180 } 5181 5182 DNBRegisterValue reg_value; 5183 5184 if (g_reg_entries != NULL) 5185 { 5186 JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary()); 5187 5188 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 5189 { 5190 // Expedite all registers in the first register set that aren't 5191 // contained in other registers 5192 if (g_reg_entries[reg].nub_info.set == 1 && 5193 g_reg_entries[reg].nub_info.value_regs == NULL) 5194 { 5195 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 5196 continue; 5197 5198 std::ostringstream reg_num; 5199 reg_num << std::dec << g_reg_entries[reg].debugserver_regnum; 5200 // Encode native byte ordered bytes as hex ascii 5201 registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size); 5202 } 5203 } 5204 thread_dict_sp->AddItem("registers", registers_dict_sp); 5205 } 5206 5207 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 5208 // frame pointer chain. 5209 StackMemoryMap stack_mmap; 5210 ReadStackMemory (pid, tid, stack_mmap); 5211 if (!stack_mmap.empty()) 5212 { 5213 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5214 5215 for (const auto &stack_memory : stack_mmap) 5216 { 5217 JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary()); 5218 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5219 stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length); 5220 memory_array_sp->AddItem(stack_memory_sp); 5221 } 5222 thread_dict_sp->AddItem("memory", memory_array_sp); 5223 } 5224 } 5225 5226 threads_array_sp->AddItem(thread_dict_sp); 5227 } 5228 } 5229 return threads_array_sp; 5230 } 5231 5232 rnb_err_t 5233 RNBRemote::HandlePacket_jThreadsInfo (const char *p) 5234 { 5235 JSONGenerator::ObjectSP threads_info_sp; 5236 std::ostringstream json; 5237 std::ostringstream reply_strm; 5238 // If we haven't run the process yet, return an error. 5239 if (m_ctx.HasValidProcessID()) 5240 { 5241 const bool threads_with_valid_stop_info_only = false; 5242 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5243 5244 if (threads_info_sp) 5245 { 5246 std::ostringstream strm; 5247 threads_info_sp->Dump (strm); 5248 std::string binary_packet = binary_encode_string (strm.str()); 5249 if (!binary_packet.empty()) 5250 return SendPacket (binary_packet.c_str()); 5251 } 5252 } 5253 return SendPacket ("E85"); 5254 5255 } 5256 5257 rnb_err_t 5258 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) 5259 { 5260 nub_process_t pid; 5261 std::ostringstream json; 5262 // If we haven't run the process yet, return an error. 5263 if (!m_ctx.HasValidProcessID()) 5264 { 5265 return SendPacket ("E81"); 5266 } 5267 5268 pid = m_ctx.ProcessID(); 5269 5270 const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" }; 5271 if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0) 5272 { 5273 p += strlen (thread_extended_info_str); 5274 5275 uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p); 5276 uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p); 5277 uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p); 5278 uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p); 5279 uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p); 5280 // Commented out the two variables below as they are not being used 5281 // uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p); 5282 // uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p); 5283 5284 if (tid != INVALID_NUB_ADDRESS) 5285 { 5286 nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid); 5287 5288 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5289 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS 5290 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS 5291 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) 5292 { 5293 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5294 } 5295 5296 bool timed_out = false; 5297 Genealogy::ThreadActivitySP thread_activity_sp; 5298 5299 // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base 5300 // and got an invalid value back, then we have a thread in early startup or shutdown and 5301 // it's possible that gathering the genealogy information for this thread go badly. 5302 // Ideally fetching this info for a thread in these odd states shouldn't matter - but 5303 // we've seen some problems with these new SPI and threads in edge-casey states. 5304 5305 double genealogy_fetch_time = 0; 5306 if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS) 5307 { 5308 DNBTimer timer(false); 5309 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out); 5310 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5311 } 5312 5313 std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen 5314 5315 json << "{"; 5316 5317 bool need_to_print_comma = false; 5318 5319 if (thread_activity_sp && timed_out == false) 5320 { 5321 const Genealogy::Activity *activity = &thread_activity_sp->current_activity; 5322 bool need_vouchers_comma_sep = false; 5323 json << "\"activity_query_timed_out\":false,"; 5324 if (genealogy_fetch_time != 0) 5325 { 5326 // If we append the floating point value with << we'll get it in scientific 5327 // notation. 5328 char floating_point_ascii_buffer[64]; 5329 floating_point_ascii_buffer[0] = '\0'; 5330 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5331 if (strlen (floating_point_ascii_buffer) > 0) 5332 { 5333 if (need_to_print_comma) 5334 json << ","; 5335 need_to_print_comma = true; 5336 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5337 } 5338 } 5339 if (activity->activity_id != 0) 5340 { 5341 if (need_to_print_comma) 5342 json << ","; 5343 need_to_print_comma = true; 5344 need_vouchers_comma_sep = true; 5345 json << "\"activity\":{"; 5346 json << "\"start\":" << activity->activity_start << ","; 5347 json << "\"id\":" << activity->activity_id << ","; 5348 json << "\"parent_id\":" << activity->parent_id << ","; 5349 json << "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\","; 5350 json << "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\""; 5351 json << "}"; 5352 } 5353 if (thread_activity_sp->messages.size() > 0) 5354 { 5355 need_to_print_comma = true; 5356 if (need_vouchers_comma_sep) 5357 json << ","; 5358 need_vouchers_comma_sep = true; 5359 json << "\"trace_messages\":["; 5360 bool printed_one_message = false; 5361 for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter) 5362 { 5363 if (printed_one_message) 5364 json << ","; 5365 else 5366 printed_one_message = true; 5367 json << "{"; 5368 json << "\"timestamp\":" << iter->timestamp << ","; 5369 json << "\"activity_id\":" << iter->activity_id << ","; 5370 json << "\"trace_id\":" << iter->trace_id << ","; 5371 json << "\"thread\":" << iter->thread << ","; 5372 json << "\"type\":" << (int) iter->type << ","; 5373 json << "\"process_info_index\":" << iter->process_info_index << ","; 5374 process_info_indexes.insert (iter->process_info_index); 5375 json << "\"message\":\"" << json_string_quote_metachars (iter->message) << "\""; 5376 json << "}"; 5377 } 5378 json << "]"; 5379 } 5380 if (thread_activity_sp->breadcrumbs.size() == 1) 5381 { 5382 need_to_print_comma = true; 5383 if (need_vouchers_comma_sep) 5384 json << ","; 5385 need_vouchers_comma_sep = true; 5386 json << "\"breadcrumb\":{"; 5387 for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter) 5388 { 5389 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5390 json << "\"activity_id\":" << iter->activity_id << ","; 5391 json << "\"timestamp\":" << iter->timestamp << ","; 5392 json << "\"name\":\"" << json_string_quote_metachars (iter->name) << "\""; 5393 } 5394 json << "}"; 5395 } 5396 if (process_info_indexes.size() > 0) 5397 { 5398 need_to_print_comma = true; 5399 if (need_vouchers_comma_sep) 5400 json << ","; 5401 need_vouchers_comma_sep = true; 5402 json << "\"process_infos\":["; 5403 bool printed_one_process_info = false; 5404 for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter) 5405 { 5406 if (printed_one_process_info) 5407 json << ","; 5408 else 5409 printed_one_process_info = true; 5410 Genealogy::ProcessExecutableInfoSP image_info_sp; 5411 uint32_t idx = *iter; 5412 image_info_sp = DNBGetGenealogyImageInfo (pid, idx); 5413 json << "{"; 5414 char uuid_buf[37]; 5415 uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf); 5416 json << "\"process_info_index\":" << idx << ","; 5417 json << "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\","; 5418 json << "\"image_uuid\":\"" << uuid_buf <<"\""; 5419 json << "}"; 5420 } 5421 json << "]"; 5422 } 5423 } 5424 else 5425 { 5426 if (timed_out) 5427 { 5428 if (need_to_print_comma) 5429 json << ","; 5430 need_to_print_comma = true; 5431 json << "\"activity_query_timed_out\":true"; 5432 if (genealogy_fetch_time != 0) 5433 { 5434 // If we append the floating point value with << we'll get it in scientific 5435 // notation. 5436 char floating_point_ascii_buffer[64]; 5437 floating_point_ascii_buffer[0] = '\0'; 5438 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5439 if (strlen (floating_point_ascii_buffer) > 0) 5440 { 5441 json << ","; 5442 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5443 } 5444 } 5445 } 5446 } 5447 5448 if (tsd_address != INVALID_NUB_ADDRESS) 5449 { 5450 if (need_to_print_comma) 5451 json << ","; 5452 need_to_print_comma = true; 5453 json << "\"tsd_address\":" << tsd_address; 5454 5455 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) 5456 { 5457 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index); 5458 if (requested_qos.IsValid()) 5459 { 5460 if (need_to_print_comma) 5461 json << ","; 5462 need_to_print_comma = true; 5463 json << "\"requested_qos\":{"; 5464 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5465 json << "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\","; 5466 json << "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\""; 5467 json << "}"; 5468 } 5469 } 5470 } 5471 5472 if (pthread_t_value != INVALID_NUB_ADDRESS) 5473 { 5474 if (need_to_print_comma) 5475 json << ","; 5476 need_to_print_comma = true; 5477 json << "\"pthread_t\":" << pthread_t_value; 5478 } 5479 5480 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid); 5481 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) 5482 { 5483 if (need_to_print_comma) 5484 json << ","; 5485 need_to_print_comma = true; 5486 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5487 } 5488 5489 json << "}"; 5490 std::string json_quoted = binary_encode_string (json.str()); 5491 return SendPacket (json_quoted); 5492 } 5493 } 5494 return SendPacket ("OK"); 5495 } 5496 5497 rnb_err_t 5498 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p) 5499 { 5500 nub_process_t pid; 5501 // If we haven't run the process yet, return an error. 5502 if (!m_ctx.HasValidProcessID()) 5503 { 5504 return SendPacket ("E83"); 5505 } 5506 5507 pid = m_ctx.ProcessID(); 5508 5509 const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" }; 5510 if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0) 5511 { 5512 p += strlen (get_loaded_dynamic_libraries_infos_str); 5513 5514 nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p); 5515 nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p); 5516 5517 if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS) 5518 { 5519 JSONGenerator::ObjectSP json_sp; 5520 5521 json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count); 5522 5523 if (json_sp.get()) 5524 { 5525 std::ostringstream json_str; 5526 json_sp->Dump (json_str); 5527 if (json_str.str().size() > 0) 5528 { 5529 std::string json_str_quoted = binary_encode_string (json_str.str()); 5530 return SendPacket (json_str_quoted.c_str()); 5531 } 5532 else 5533 { 5534 SendPacket ("E84"); 5535 } 5536 } 5537 } 5538 } 5539 return SendPacket ("OK"); 5540 } 5541 5542 static bool 5543 MachHeaderIsMainExecutable (nub_process_t pid, uint32_t addr_size, nub_addr_t mach_header_addr, mach_header &mh) 5544 { 5545 DNBLogThreadedIf (LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = %u, mach_header_addr = 0x%16.16llx)", pid, addr_size, mach_header_addr); 5546 const nub_size_t bytes_read = DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh); 5547 if (bytes_read == sizeof(mh)) 5548 { 5549 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); 5550 if ((addr_size == 4 && mh.magic == MH_MAGIC) || 5551 (addr_size == 8 && mh.magic == MH_MAGIC_64)) 5552 { 5553 if (mh.filetype == MH_EXECUTE) 5554 { 5555 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); 5556 return true; 5557 } 5558 } 5559 } 5560 return false; 5561 } 5562 5563 static nub_addr_t 5564 GetMachHeaderForMainExecutable (const nub_process_t pid, const uint32_t addr_size, mach_header &mh) 5565 { 5566 struct AllImageInfos 5567 { 5568 uint32_t version; 5569 uint32_t dylib_info_count; 5570 uint64_t dylib_info_addr; 5571 }; 5572 5573 uint64_t mach_header_addr = 0; 5574 5575 const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress (pid); 5576 uint8_t bytes[256]; 5577 nub_size_t bytes_read = 0; 5578 DNBDataRef data (bytes, sizeof(bytes), false); 5579 DNBDataRef::offset_t offset = 0; 5580 data.SetPointerSize(addr_size); 5581 5582 //---------------------------------------------------------------------- 5583 // When we are sitting at __dyld_start, the kernel has placed the 5584 // address of the mach header of the main executable on the stack. If we 5585 // read the SP and dereference a pointer, we might find the mach header 5586 // for the executable. We also just make sure there is only 1 thread 5587 // since if we are at __dyld_start we shouldn't have multiple threads. 5588 //---------------------------------------------------------------------- 5589 if (DNBProcessGetNumThreads(pid) == 1) 5590 { 5591 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0); 5592 if (tid != INVALID_NUB_THREAD) 5593 { 5594 DNBRegisterValue sp_value; 5595 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_SP, &sp_value)) 5596 { 5597 uint64_t sp = addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32; 5598 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes); 5599 if (bytes_read == addr_size) 5600 { 5601 offset = 0; 5602 mach_header_addr = data.GetPointer(&offset); 5603 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5604 return mach_header_addr; 5605 } 5606 } 5607 } 5608 } 5609 5610 //---------------------------------------------------------------------- 5611 // Check the dyld_all_image_info structure for a list of mach header 5612 // since it is a very easy thing to check 5613 //---------------------------------------------------------------------- 5614 if (shlib_addr != INVALID_NUB_ADDRESS) 5615 { 5616 bytes_read = DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes); 5617 if (bytes_read > 0) 5618 { 5619 AllImageInfos aii; 5620 offset = 0; 5621 aii.version = data.Get32(&offset); 5622 aii.dylib_info_count = data.Get32(&offset); 5623 if (aii.dylib_info_count > 0) 5624 { 5625 aii.dylib_info_addr = data.GetPointer(&offset); 5626 if (aii.dylib_info_addr != 0) 5627 { 5628 const size_t image_info_byte_size = 3 * addr_size; 5629 for (uint32_t i=0; i<aii.dylib_info_count; ++i) 5630 { 5631 bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + i * image_info_byte_size, image_info_byte_size, bytes); 5632 if (bytes_read != image_info_byte_size) 5633 break; 5634 offset = 0; 5635 mach_header_addr = data.GetPointer(&offset); 5636 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5637 return mach_header_addr; 5638 } 5639 } 5640 } 5641 } 5642 } 5643 5644 //---------------------------------------------------------------------- 5645 // We failed to find the executable's mach header from the all image 5646 // infos and by dereferencing the stack pointer. Now we fall back to 5647 // enumerating the memory regions and looking for regions that are 5648 // executable. 5649 //---------------------------------------------------------------------- 5650 DNBRegionInfo region_info; 5651 mach_header_addr = 0; 5652 while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, ®ion_info)) 5653 { 5654 if (region_info.size == 0) 5655 break; 5656 5657 if (region_info.permissions & eMemoryPermissionsExecutable) 5658 { 5659 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' : '-'); 5660 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5661 return mach_header_addr; 5662 } 5663 else 5664 { 5665 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' : '-'); 5666 } 5667 // Set the address to the next mapped region 5668 mach_header_addr = region_info.addr + region_info.size; 5669 } 5670 bzero (&mh, sizeof(mh)); 5671 return INVALID_NUB_ADDRESS; 5672 } 5673 5674 rnb_err_t 5675 RNBRemote::HandlePacket_qSymbol (const char *command) 5676 { 5677 const char *p = command; 5678 p += strlen ("qSymbol:"); 5679 const char *sep = strchr(p, ':'); 5680 5681 std::string symbol_name; 5682 std::string symbol_value_str; 5683 // Extract the symbol value if there is one 5684 if (sep > p) 5685 symbol_value_str.assign(p, sep - p); 5686 p = sep + 1; 5687 5688 if (*p) 5689 { 5690 // We have a symbol name 5691 symbol_name = std::move(decode_hex_ascii_string(p)); 5692 if (!symbol_value_str.empty()) 5693 { 5694 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5695 if (symbol_name == "dispatch_queue_offsets") 5696 m_dispatch_queue_offsets_addr = symbol_value; 5697 } 5698 ++m_qSymbol_index; 5699 } 5700 else 5701 { 5702 // No symbol name, set our symbol index to zero so we can 5703 // read any symbols that we need 5704 m_qSymbol_index = 0; 5705 } 5706 5707 symbol_name.clear(); 5708 5709 if (m_qSymbol_index == 0) 5710 { 5711 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5712 symbol_name = "dispatch_queue_offsets"; 5713 else 5714 ++m_qSymbol_index; 5715 } 5716 5717 // // Lookup next symbol when we have one... 5718 // if (m_qSymbol_index == 1) 5719 // { 5720 // } 5721 5722 5723 if (symbol_name.empty()) 5724 { 5725 // Done with symbol lookups 5726 return SendPacket ("OK"); 5727 } 5728 else 5729 { 5730 std::ostringstream reply; 5731 reply << "qSymbol:"; 5732 for (size_t i = 0; i < symbol_name.size(); ++i) 5733 reply << RAWHEX8(symbol_name[i]); 5734 return SendPacket (reply.str().c_str()); 5735 } 5736 } 5737 5738 // Note that all numeric values returned by qProcessInfo are hex encoded, 5739 // including the pid and the cpu type. 5740 5741 rnb_err_t 5742 RNBRemote::HandlePacket_qProcessInfo (const char *p) 5743 { 5744 nub_process_t pid; 5745 std::ostringstream rep; 5746 5747 // If we haven't run the process yet, return an error. 5748 if (!m_ctx.HasValidProcessID()) 5749 return SendPacket ("E68"); 5750 5751 pid = m_ctx.ProcessID(); 5752 5753 rep << "pid:" << std::hex << pid << ';'; 5754 5755 int procpid_mib[4]; 5756 procpid_mib[0] = CTL_KERN; 5757 procpid_mib[1] = KERN_PROC; 5758 procpid_mib[2] = KERN_PROC_PID; 5759 procpid_mib[3] = pid; 5760 struct kinfo_proc proc_kinfo; 5761 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 5762 5763 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 5764 { 5765 if (proc_kinfo_size > 0) 5766 { 5767 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';'; 5768 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ';'; 5769 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ';'; 5770 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ';'; 5771 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 5772 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';'; 5773 } 5774 } 5775 5776 cpu_type_t cputype = DNBProcessGetCPUType (pid); 5777 if (cputype == 0) 5778 { 5779 DNBLog ("Unable to get the process cpu_type, making a best guess."); 5780 cputype = best_guess_cpu_type(); 5781 } 5782 5783 uint32_t addr_size = 0; 5784 if (cputype != 0) 5785 { 5786 rep << "cputype:" << std::hex << cputype << ";"; 5787 if (cputype & CPU_ARCH_ABI64) 5788 addr_size = 8; 5789 else 5790 addr_size = 4; 5791 } 5792 5793 bool host_cpu_is_64bit = false; 5794 uint32_t is64bit_capable; 5795 size_t is64bit_capable_len = sizeof (is64bit_capable); 5796 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0) 5797 host_cpu_is_64bit = is64bit_capable != 0; 5798 5799 uint32_t cpusubtype; 5800 size_t cpusubtype_len = sizeof(cpusubtype); 5801 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 5802 { 5803 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 5804 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 5805 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype 5806 // for i386... 5807 if (host_cpu_is_64bit) 5808 { 5809 if (cputype == CPU_TYPE_X86) 5810 { 5811 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 5812 } 5813 else if (cputype == CPU_TYPE_ARM) 5814 { 5815 // We can query a process' cputype but we cannot query a process' cpusubtype. 5816 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we 5817 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace) 5818 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 5819 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S 5820 } 5821 } 5822 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 5823 } 5824 5825 bool os_handled = false; 5826 if (addr_size > 0) 5827 { 5828 rep << "ptrsize:" << std::dec << addr_size << ';'; 5829 5830 #if (defined (__x86_64__) || defined (__i386__)) 5831 // Try and get the OS type by looking at the load commands in the main 5832 // executable and looking for a LC_VERSION_MIN load command. This is the 5833 // most reliable way to determine the "ostype" value when on desktop. 5834 5835 mach_header mh; 5836 nub_addr_t exe_mach_header_addr = GetMachHeaderForMainExecutable (pid, addr_size, mh); 5837 if (exe_mach_header_addr != INVALID_NUB_ADDRESS) 5838 { 5839 uint64_t load_command_addr = exe_mach_header_addr + ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header)); 5840 load_command lc; 5841 for (uint32_t i=0; i<mh.ncmds && !os_handled; ++i) 5842 { 5843 const nub_size_t bytes_read = DNBProcessMemoryRead (pid, load_command_addr, sizeof(lc), &lc); 5844 uint32_t raw_cmd = lc.cmd & ~LC_REQ_DYLD; 5845 if (bytes_read != sizeof(lc)) 5846 break; 5847 switch (raw_cmd) 5848 { 5849 case LC_VERSION_MIN_IPHONEOS: 5850 os_handled = true; 5851 rep << "ostype:ios;"; 5852 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_IPHONEOS -> 'ostype:ios;'"); 5853 break; 5854 5855 case LC_VERSION_MIN_MACOSX: 5856 os_handled = true; 5857 rep << "ostype:macosx;"; 5858 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'"); 5859 break; 5860 5861 #if defined (LC_VERSION_MIN_TVOS) 5862 case LC_VERSION_MIN_TVOS: 5863 os_handled = true; 5864 rep << "ostype:tvos;"; 5865 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_TVOS -> 'ostype:tvos;'"); 5866 break; 5867 #endif 5868 5869 #if defined (LC_VERSION_MIN_WATCHOS) 5870 case LC_VERSION_MIN_WATCHOS: 5871 os_handled = true; 5872 rep << "ostype:watchos;"; 5873 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_WATCHOS -> 'ostype:watchos;'"); 5874 break; 5875 #endif 5876 5877 default: 5878 break; 5879 } 5880 load_command_addr = load_command_addr + lc.cmdsize; 5881 } 5882 } 5883 #endif 5884 } 5885 5886 // If we weren't able to find the OS in a LC_VERSION_MIN load command, try 5887 // to set it correctly by using the cpu type and other tricks 5888 if (!os_handled) 5889 { 5890 // The OS in the triple should be "ios" or "macosx" which doesn't match our 5891 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 5892 // this for now. 5893 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 5894 { 5895 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 5896 rep << "ostype:tvos;"; 5897 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 5898 rep << "ostype:watchos;"; 5899 #else 5900 rep << "ostype:ios;"; 5901 #endif 5902 } 5903 else 5904 { 5905 bool is_ios_simulator = false; 5906 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) 5907 { 5908 // Check for iOS simulator binaries by getting the process argument 5909 // and environment and checking for SIMULATOR_UDID in the environment 5910 int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid }; 5911 5912 uint8_t arg_data[8192]; 5913 size_t arg_data_size = sizeof(arg_data); 5914 if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) 5915 { 5916 DNBDataRef data (arg_data, arg_data_size, false); 5917 DNBDataRef::offset_t offset = 0; 5918 uint32_t argc = data.Get32 (&offset); 5919 const char *cstr; 5920 5921 cstr = data.GetCStr (&offset); 5922 if (cstr) 5923 { 5924 // Skip NULLs 5925 while (1) 5926 { 5927 const char *p = data.PeekCStr(offset); 5928 if ((p == NULL) || (*p != '\0')) 5929 break; 5930 ++offset; 5931 } 5932 // Now skip all arguments 5933 for (uint32_t i = 0; i < argc; ++i) 5934 { 5935 data.GetCStr(&offset); 5936 } 5937 5938 // Now iterate across all environment variables 5939 while ((cstr = data.GetCStr(&offset))) 5940 { 5941 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) 5942 { 5943 is_ios_simulator = true; 5944 break; 5945 } 5946 if (cstr[0] == '\0') 5947 break; 5948 5949 } 5950 } 5951 } 5952 } 5953 if (is_ios_simulator) 5954 { 5955 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 5956 rep << "ostype:tvos;"; 5957 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 5958 rep << "ostype:watchos;"; 5959 #else 5960 rep << "ostype:ios;"; 5961 #endif 5962 } 5963 else 5964 { 5965 rep << "ostype:macosx;"; 5966 } 5967 } 5968 } 5969 5970 rep << "vendor:apple;"; 5971 5972 #if defined (__LITTLE_ENDIAN__) 5973 rep << "endian:little;"; 5974 #elif defined (__BIG_ENDIAN__) 5975 rep << "endian:big;"; 5976 #elif defined (__PDP_ENDIAN__) 5977 rep << "endian:pdp;"; 5978 #endif 5979 5980 if (addr_size == 0) 5981 { 5982 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 5983 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5984 kern_return_t kr; 5985 x86_thread_state_t gp_regs; 5986 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 5987 kr = thread_get_state (static_cast<thread_act_t>(thread), 5988 x86_THREAD_STATE, 5989 (thread_state_t) &gp_regs, 5990 &gp_count); 5991 if (kr == KERN_SUCCESS) 5992 { 5993 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 5994 rep << "ptrsize:8;"; 5995 else 5996 rep << "ptrsize:4;"; 5997 } 5998 #elif defined (__arm__) 5999 rep << "ptrsize:4;"; 6000 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE) 6001 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 6002 kern_return_t kr; 6003 arm_unified_thread_state_t gp_regs; 6004 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 6005 kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE, 6006 (thread_state_t) &gp_regs, &gp_count); 6007 if (kr == KERN_SUCCESS) 6008 { 6009 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 6010 rep << "ptrsize:8;"; 6011 else 6012 rep << "ptrsize:4;"; 6013 } 6014 #endif 6015 } 6016 6017 return SendPacket (rep.str()); 6018 } 6019 6020 const RNBRemote::DispatchQueueOffsets * 6021 RNBRemote::GetDispatchQueueOffsets() 6022 { 6023 if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID()) 6024 { 6025 nub_process_t pid = m_ctx.ProcessID(); 6026 nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets); 6027 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 6028 m_dispatch_queue_offsets.Clear(); 6029 } 6030 6031 if (m_dispatch_queue_offsets.IsValid()) 6032 return &m_dispatch_queue_offsets; 6033 else 6034 return nullptr; 6035 } 6036 6037 void 6038 RNBRemote::EnableCompressionNextSendPacket (compression_types type) 6039 { 6040 m_compression_mode = type; 6041 m_enable_compression_next_send_packet = true; 6042 } 6043 6044 compression_types 6045 RNBRemote::GetCompressionType () 6046 { 6047 // The first packet we send back to the debugger after a QEnableCompression request 6048 // should be uncompressed -- so we can indicate whether the compression was enabled 6049 // or not via OK / Enn returns. After that, all packets sent will be using the 6050 // compression protocol. 6051 6052 if (m_enable_compression_next_send_packet) 6053 { 6054 // One time, we send back "None" as our compression type 6055 m_enable_compression_next_send_packet = false; 6056 return compression_types::none; 6057 } 6058 return m_compression_mode; 6059 } 6060