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