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