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 std::string &queue_name, 2551 uint64_t &queue_width, 2552 uint64_t &queue_serialnum) const 2553 { 2554 queue_name.clear(); 2555 queue_width = 0; 2556 queue_serialnum = 0; 2557 2558 if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS && dispatch_qaddr != 0) 2559 { 2560 nub_addr_t dispatch_queue_addr = DNBProcessMemoryReadPointer (pid, dispatch_qaddr); 2561 if (dispatch_queue_addr) 2562 { 2563 queue_width = DNBProcessMemoryReadInteger (pid, dispatch_queue_addr + dqo_width, dqo_width_size, 0); 2564 queue_serialnum = DNBProcessMemoryReadInteger (pid, dispatch_queue_addr + dqo_serialnum, dqo_serialnum_size, 0); 2565 2566 if (dqo_version >= 4) 2567 { 2568 // libdispatch versions 4+, pointer to dispatch name is in the 2569 // queue structure. 2570 nub_addr_t pointer_to_label_address = dispatch_queue_addr + dqo_label; 2571 nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address); 2572 if (label_addr) 2573 queue_name = std::move(DNBProcessMemoryReadCString (pid, label_addr)); 2574 } 2575 else 2576 { 2577 // libdispatch versions 1-3, dispatch name is a fixed width char array 2578 // in the queue structure. 2579 queue_name = std::move(DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_addr + dqo_label, dqo_label_size)); 2580 } 2581 } 2582 } 2583 } 2584 2585 struct StackMemory 2586 { 2587 uint8_t bytes[2*sizeof(nub_addr_t)]; 2588 nub_size_t length; 2589 }; 2590 typedef std::map<nub_addr_t, StackMemory> StackMemoryMap; 2591 2592 2593 static void 2594 ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap, uint32_t backtrace_limit = 256) 2595 { 2596 DNBRegisterValue reg_value; 2597 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, ®_value)) 2598 { 2599 uint32_t frame_count = 0; 2600 uint64_t fp = 0; 2601 if (reg_value.info.size == 4) 2602 fp = reg_value.value.uint32; 2603 else 2604 fp = reg_value.value.uint64; 2605 while (fp != 0) 2606 { 2607 // Make sure we never recurse more than 256 times so we don't recurse too far or 2608 // store up too much memory in the expedited cache 2609 if (++frame_count > backtrace_limit) 2610 break; 2611 2612 const nub_size_t read_size = reg_value.info.size*2; 2613 StackMemory stack_memory; 2614 stack_memory.length = read_size; 2615 if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size) 2616 break; 2617 // Make sure we don't try to put the same stack memory in more than once 2618 if (stack_mmap.find(fp) != stack_mmap.end()) 2619 break; 2620 // Put the entry into the cache 2621 stack_mmap[fp] = stack_memory; 2622 // Dereference the frame pointer to get to the previous frame pointer 2623 if (reg_value.info.size == 4) 2624 fp = ((uint32_t *)stack_memory.bytes)[0]; 2625 else 2626 fp = ((uint64_t *)stack_memory.bytes)[0]; 2627 } 2628 } 2629 } 2630 2631 rnb_err_t 2632 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) 2633 { 2634 const nub_process_t pid = m_ctx.ProcessID(); 2635 if (pid == INVALID_NUB_PROCESS) 2636 return SendPacket("E50"); 2637 2638 struct DNBThreadStopInfo tid_stop_info; 2639 2640 /* Fill the remaining space in this packet with as many registers 2641 as we can stuff in there. */ 2642 2643 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) 2644 { 2645 const bool did_exec = tid_stop_info.reason == eStopTypeExec; 2646 if (did_exec) 2647 { 2648 RNBRemote::InitializeRegisters(true); 2649 2650 // Reset any symbols that need resetting when we exec 2651 m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS; 2652 m_dispatch_queue_offsets.Clear(); 2653 } 2654 2655 std::ostringstream ostrm; 2656 // Output the T packet with the thread 2657 ostrm << 'T'; 2658 int signum = tid_stop_info.details.signal.signo; 2659 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); 2660 2661 // Translate any mach exceptions to gdb versions, unless they are 2662 // common exceptions like a breakpoint or a soft signal. 2663 switch (tid_stop_info.details.exception.type) 2664 { 2665 default: signum = 0; break; 2666 case EXC_BREAKPOINT: signum = SIGTRAP; break; 2667 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break; 2668 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break; 2669 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break; 2670 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break; 2671 case EXC_SOFTWARE: 2672 if (tid_stop_info.details.exception.data_count == 2 && 2673 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2674 signum = static_cast<int>(tid_stop_info.details.exception.data[1]); 2675 else 2676 signum = TARGET_EXC_SOFTWARE; 2677 break; 2678 } 2679 2680 ostrm << RAWHEX8(signum & 0xff); 2681 2682 ostrm << std::hex << "thread:" << tid << ';'; 2683 2684 const char *thread_name = DNBThreadGetName (pid, tid); 2685 if (thread_name && thread_name[0]) 2686 { 2687 size_t thread_name_len = strlen(thread_name); 2688 2689 2690 if (::strcspn (thread_name, "$#+-;:") == thread_name_len) 2691 ostrm << std::hex << "name:" << thread_name << ';'; 2692 else 2693 { 2694 // the thread name contains special chars, send as hex bytes 2695 ostrm << std::hex << "hexname:"; 2696 uint8_t *u_thread_name = (uint8_t *)thread_name; 2697 for (size_t i = 0; i < thread_name_len; i++) 2698 ostrm << RAWHEX8(u_thread_name[i]); 2699 ostrm << ';'; 2700 } 2701 } 2702 2703 thread_identifier_info_data_t thread_ident_info; 2704 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 2705 { 2706 if (thread_ident_info.dispatch_qaddr != 0) 2707 { 2708 ostrm << "qaddr:" << std::hex << thread_ident_info.dispatch_qaddr << ';'; 2709 const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets(); 2710 if (dispatch_queue_offsets) 2711 { 2712 std::string queue_name; 2713 uint64_t queue_width = 0; 2714 uint64_t queue_serialnum = 0; 2715 dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum); 2716 if (!queue_name.empty()) 2717 { 2718 ostrm << "qname:"; 2719 append_hex_value(ostrm, queue_name.data(), queue_name.size(), false); 2720 ostrm << ';'; 2721 } 2722 if (queue_width == 1) 2723 ostrm << "qkind:serial;"; 2724 else if (queue_width > 1) 2725 ostrm << "qkind:concurrent;"; 2726 2727 if (queue_serialnum > 0) 2728 ostrm << "qserial:" << DECIMAL << queue_serialnum << ';'; 2729 } 2730 } 2731 } 2732 2733 // If a 'QListThreadsInStopReply' was sent to enable this feature, we 2734 // will send all thread IDs back in the "threads" key whose value is 2735 // a list of hex thread IDs separated by commas: 2736 // "threads:10a,10b,10c;" 2737 // This will save the debugger from having to send a pair of qfThreadInfo 2738 // and qsThreadInfo packets, but it also might take a lot of room in the 2739 // stop reply packet, so it must be enabled only on systems where there 2740 // are no limits on packet lengths. 2741 if (m_list_threads_in_stop_reply) 2742 { 2743 const nub_size_t numthreads = DNBProcessGetNumThreads (pid); 2744 if (numthreads > 0) 2745 { 2746 ostrm << std::hex << "threads:"; 2747 for (nub_size_t i = 0; i < numthreads; ++i) 2748 { 2749 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 2750 if (i > 0) 2751 ostrm << ','; 2752 ostrm << std::hex << th; 2753 } 2754 ostrm << ';'; 2755 } 2756 2757 // Include JSON info that describes the stop reason for any threads 2758 // that actually have stop reasons. We use the new "jstopinfo" key 2759 // whose values is hex ascii JSON that contains the thread IDs 2760 // thread stop info only for threads that have stop reasons. Only send 2761 // this if we have more than one thread otherwise this packet has all 2762 // the info it needs. 2763 if (numthreads > 1) 2764 { 2765 const bool threads_with_valid_stop_info_only = true; 2766 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 2767 if (threads_info_sp) 2768 { 2769 ostrm << std::hex << "jstopinfo:"; 2770 std::ostringstream json_strm; 2771 threads_info_sp->Dump (json_strm); 2772 append_hexified_string (ostrm, json_strm.str()); 2773 ostrm << ';'; 2774 } 2775 } 2776 } 2777 2778 2779 if (g_num_reg_entries == 0) 2780 InitializeRegisters (); 2781 2782 if (g_reg_entries != NULL) 2783 { 2784 DNBRegisterValue reg_value; 2785 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2786 { 2787 // Expedite all registers in the first register set that aren't 2788 // contained in other registers 2789 if (g_reg_entries[reg].nub_info.set == 1 && 2790 g_reg_entries[reg].nub_info.value_regs == NULL) 2791 { 2792 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 2793 continue; 2794 2795 debugserver_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], ®_value); 2796 } 2797 } 2798 } 2799 2800 if (did_exec) 2801 { 2802 ostrm << "reason:exec;"; 2803 } 2804 else if (tid_stop_info.details.exception.type) 2805 { 2806 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';'; 2807 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';'; 2808 for (nub_size_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) 2809 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';'; 2810 } 2811 2812 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 2813 // frame pointer chain. 2814 StackMemoryMap stack_mmap; 2815 ReadStackMemory (pid, tid, stack_mmap, 1); 2816 if (!stack_mmap.empty()) 2817 { 2818 for (const auto &stack_memory : stack_mmap) 2819 { 2820 ostrm << "memory:" << HEXBASE << stack_memory.first << '='; 2821 append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false); 2822 ostrm << ';'; 2823 } 2824 } 2825 2826 return SendPacket (ostrm.str ()); 2827 } 2828 return SendPacket("E51"); 2829 } 2830 2831 /* '?' 2832 The stop reply packet - tell gdb what the status of the inferior is. 2833 Often called the questionmark_packet. */ 2834 2835 rnb_err_t 2836 RNBRemote::HandlePacket_last_signal (const char *unused) 2837 { 2838 if (!m_ctx.HasValidProcessID()) 2839 { 2840 // Inferior is not yet specified/running 2841 return SendPacket ("E02"); 2842 } 2843 2844 nub_process_t pid = m_ctx.ProcessID(); 2845 nub_state_t pid_state = DNBProcessGetState (pid); 2846 2847 switch (pid_state) 2848 { 2849 case eStateAttaching: 2850 case eStateLaunching: 2851 case eStateRunning: 2852 case eStateStepping: 2853 case eStateDetached: 2854 return rnb_success; // Ignore 2855 2856 case eStateSuspended: 2857 case eStateStopped: 2858 case eStateCrashed: 2859 { 2860 nub_thread_t tid = DNBProcessGetCurrentThread (pid); 2861 // Make sure we set the current thread so g and p packets return 2862 // the data the gdb will expect. 2863 SetCurrentThread (tid); 2864 2865 SendStopReplyPacketForThread (tid); 2866 } 2867 break; 2868 2869 case eStateInvalid: 2870 case eStateUnloaded: 2871 case eStateExited: 2872 { 2873 char pid_exited_packet[16] = ""; 2874 int pid_status = 0; 2875 // Process exited with exit status 2876 if (!DNBProcessGetExitStatus(pid, &pid_status)) 2877 pid_status = 0; 2878 2879 if (pid_status) 2880 { 2881 if (WIFEXITED (pid_status)) 2882 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status)); 2883 else if (WIFSIGNALED (pid_status)) 2884 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status)); 2885 else if (WIFSTOPPED (pid_status)) 2886 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status)); 2887 } 2888 2889 // If we have an empty exit packet, lets fill one in to be safe. 2890 if (!pid_exited_packet[0]) 2891 { 2892 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1); 2893 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0'; 2894 } 2895 2896 const char *exit_info = DNBProcessGetExitInfo (pid); 2897 if (exit_info != NULL && *exit_info != '\0') 2898 { 2899 std::ostringstream exit_packet; 2900 exit_packet << pid_exited_packet; 2901 exit_packet << ';'; 2902 exit_packet << RAW_HEXBASE << "description"; 2903 exit_packet << ':'; 2904 for (size_t i = 0; exit_info[i] != '\0'; i++) 2905 exit_packet << RAWHEX8(exit_info[i]); 2906 exit_packet << ';'; 2907 return SendPacket (exit_packet.str()); 2908 } 2909 else 2910 return SendPacket (pid_exited_packet); 2911 } 2912 break; 2913 } 2914 return rnb_success; 2915 } 2916 2917 rnb_err_t 2918 RNBRemote::HandlePacket_M (const char *p) 2919 { 2920 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2921 { 2922 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet"); 2923 } 2924 2925 char *c; 2926 p++; 2927 errno = 0; 2928 nub_addr_t addr = strtoull (p, &c, 16); 2929 if (errno != 0 && addr == 0) 2930 { 2931 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet"); 2932 } 2933 if (*c != ',') 2934 { 2935 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet"); 2936 } 2937 2938 /* Advance 'p' to the length part of the packet. */ 2939 p += (c - p) + 1; 2940 2941 errno = 0; 2942 unsigned long length = strtoul (p, &c, 16); 2943 if (errno != 0 && length == 0) 2944 { 2945 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet"); 2946 } 2947 if (length == 0) 2948 { 2949 return SendPacket ("OK"); 2950 } 2951 2952 if (*c != ':') 2953 { 2954 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet"); 2955 } 2956 /* Advance 'p' to the data part of the packet. */ 2957 p += (c - p) + 1; 2958 2959 size_t datalen = strlen (p); 2960 if (datalen & 0x1) 2961 { 2962 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet"); 2963 } 2964 if (datalen == 0) 2965 { 2966 return SendPacket ("OK"); 2967 } 2968 2969 uint8_t *buf = (uint8_t *) alloca (datalen / 2); 2970 uint8_t *i = buf; 2971 2972 while (*p != '\0' && *(p + 1) != '\0') 2973 { 2974 char hexbuf[3]; 2975 hexbuf[0] = *p; 2976 hexbuf[1] = *(p + 1); 2977 hexbuf[2] = '\0'; 2978 errno = 0; 2979 uint8_t byte = strtoul (hexbuf, NULL, 16); 2980 if (errno != 0 && byte == 0) 2981 { 2982 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet"); 2983 } 2984 *i++ = byte; 2985 p += 2; 2986 } 2987 2988 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf); 2989 if (wrote != length) 2990 return SendPacket ("E09"); 2991 else 2992 return SendPacket ("OK"); 2993 } 2994 2995 2996 rnb_err_t 2997 RNBRemote::HandlePacket_m (const char *p) 2998 { 2999 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3000 { 3001 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet"); 3002 } 3003 3004 char *c; 3005 p++; 3006 errno = 0; 3007 nub_addr_t addr = strtoull (p, &c, 16); 3008 if (errno != 0 && addr == 0) 3009 { 3010 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet"); 3011 } 3012 if (*c != ',') 3013 { 3014 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet"); 3015 } 3016 3017 /* Advance 'p' to the length part of the packet. */ 3018 p += (c - p) + 1; 3019 3020 errno = 0; 3021 auto length = strtoul (p, NULL, 16); 3022 if (errno != 0 && length == 0) 3023 { 3024 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 3025 } 3026 if (length == 0) 3027 { 3028 return SendPacket (""); 3029 } 3030 3031 std::string buf(length, '\0'); 3032 if (buf.empty()) 3033 { 3034 return SendPacket ("E78"); 3035 } 3036 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3037 if (bytes_read == 0) 3038 { 3039 return SendPacket ("E08"); 3040 } 3041 3042 // "The reply may contain fewer bytes than requested if the server was able 3043 // to read only part of the region of memory." 3044 length = bytes_read; 3045 3046 std::ostringstream ostrm; 3047 for (unsigned long i = 0; i < length; i++) 3048 ostrm << RAWHEX8(buf[i]); 3049 return SendPacket (ostrm.str ()); 3050 } 3051 3052 // Read memory, sent it up as binary data. 3053 // Usage: xADDR,LEN 3054 // ADDR and LEN are both base 16. 3055 3056 // Responds with 'OK' for zero-length request 3057 // or 3058 // 3059 // DATA 3060 // 3061 // where DATA is the binary data payload. 3062 3063 rnb_err_t 3064 RNBRemote::HandlePacket_x (const char *p) 3065 { 3066 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3067 { 3068 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 3069 } 3070 3071 char *c; 3072 p++; 3073 errno = 0; 3074 nub_addr_t addr = strtoull (p, &c, 16); 3075 if (errno != 0) 3076 { 3077 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 3078 } 3079 if (*c != ',') 3080 { 3081 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 3082 } 3083 3084 /* Advance 'p' to the number of bytes to be read. */ 3085 p += (c - p) + 1; 3086 3087 errno = 0; 3088 auto length = strtoul (p, NULL, 16); 3089 if (errno != 0) 3090 { 3091 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in x packet"); 3092 } 3093 3094 // zero length read means this is a test of whether that packet is implemented or not. 3095 if (length == 0) 3096 { 3097 return SendPacket ("OK"); 3098 } 3099 3100 std::vector<uint8_t> buf (length); 3101 3102 if (buf.capacity() != length) 3103 { 3104 return SendPacket ("E79"); 3105 } 3106 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3107 if (bytes_read == 0) 3108 { 3109 return SendPacket ("E80"); 3110 } 3111 3112 std::vector<uint8_t> buf_quoted; 3113 buf_quoted.reserve (bytes_read + 30); 3114 for (nub_size_t i = 0; i < bytes_read; i++) 3115 { 3116 if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*') 3117 { 3118 buf_quoted.push_back(0x7d); 3119 buf_quoted.push_back(buf[i] ^ 0x20); 3120 } 3121 else 3122 { 3123 buf_quoted.push_back(buf[i]); 3124 } 3125 } 3126 length = buf_quoted.size(); 3127 3128 std::ostringstream ostrm; 3129 for (unsigned long i = 0; i < length; i++) 3130 ostrm << buf_quoted[i]; 3131 3132 return SendPacket (ostrm.str ()); 3133 } 3134 3135 rnb_err_t 3136 RNBRemote::HandlePacket_X (const char *p) 3137 { 3138 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3139 { 3140 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 3141 } 3142 3143 char *c; 3144 p++; 3145 errno = 0; 3146 nub_addr_t addr = strtoull (p, &c, 16); 3147 if (errno != 0 && addr == 0) 3148 { 3149 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 3150 } 3151 if (*c != ',') 3152 { 3153 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 3154 } 3155 3156 /* Advance 'p' to the length part of the packet. NB this is the length of the packet 3157 including any escaped chars. The data payload may be a little bit smaller after 3158 decoding. */ 3159 p += (c - p) + 1; 3160 3161 errno = 0; 3162 auto length = strtoul (p, NULL, 16); 3163 if (errno != 0 && length == 0) 3164 { 3165 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in X packet"); 3166 } 3167 3168 // I think gdb sends a zero length write request to test whether this 3169 // packet is accepted. 3170 if (length == 0) 3171 { 3172 return SendPacket ("OK"); 3173 } 3174 3175 std::vector<uint8_t> data = decode_binary_data (c, -1); 3176 std::vector<uint8_t>::const_iterator it; 3177 uint8_t *buf = (uint8_t *) alloca (data.size ()); 3178 uint8_t *i = buf; 3179 for (it = data.begin (); it != data.end (); ++it) 3180 { 3181 *i++ = *it; 3182 } 3183 3184 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf); 3185 if (wrote != data.size ()) 3186 return SendPacket ("E08"); 3187 return SendPacket ("OK"); 3188 } 3189 3190 /* 'g' -- read registers 3191 Get the contents of the registers for the current thread, 3192 send them to gdb. 3193 Should the setting of the Hg packet determine which thread's registers 3194 are returned? */ 3195 3196 rnb_err_t 3197 RNBRemote::HandlePacket_g (const char *p) 3198 { 3199 std::ostringstream ostrm; 3200 if (!m_ctx.HasValidProcessID()) 3201 { 3202 return SendPacket ("E11"); 3203 } 3204 3205 if (g_num_reg_entries == 0) 3206 InitializeRegisters (); 3207 3208 nub_process_t pid = m_ctx.ProcessID (); 3209 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1); 3210 if (tid == INVALID_NUB_THREAD) 3211 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3212 3213 // Get the register context size first by calling with NULL buffer 3214 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3215 if (reg_ctx_size) 3216 { 3217 // Now allocate enough space for the entire register context 3218 std::vector<uint8_t> reg_ctx; 3219 reg_ctx.resize(reg_ctx_size); 3220 // Now read the register context 3221 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 3222 if (reg_ctx_size) 3223 { 3224 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false); 3225 return SendPacket (ostrm.str ()); 3226 } 3227 } 3228 return SendPacket ("E74"); 3229 } 3230 3231 /* 'G XXX...' -- write registers 3232 How is the thread for these specified, beyond "the current thread"? 3233 Does gdb actually use the Hg packet to set this? */ 3234 3235 rnb_err_t 3236 RNBRemote::HandlePacket_G (const char *p) 3237 { 3238 if (!m_ctx.HasValidProcessID()) 3239 { 3240 return SendPacket ("E11"); 3241 } 3242 3243 if (g_num_reg_entries == 0) 3244 InitializeRegisters (); 3245 3246 StringExtractor packet(p); 3247 packet.SetFilePos(1); // Skip the 'G' 3248 3249 nub_process_t pid = m_ctx.ProcessID(); 3250 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3251 if (tid == INVALID_NUB_THREAD) 3252 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3253 3254 // Get the register context size first by calling with NULL buffer 3255 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3256 if (reg_ctx_size) 3257 { 3258 // Now allocate enough space for the entire register context 3259 std::vector<uint8_t> reg_ctx; 3260 reg_ctx.resize(reg_ctx_size); 3261 3262 const nub_size_t bytes_extracted = packet.GetHexBytes (®_ctx[0], reg_ctx.size(), 0xcc); 3263 if (bytes_extracted == reg_ctx.size()) 3264 { 3265 // Now write the register context 3266 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 3267 if (reg_ctx_size == reg_ctx.size()) 3268 return SendPacket ("OK"); 3269 else 3270 return SendPacket ("E55"); 3271 } 3272 else 3273 { 3274 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); 3275 return SendPacket ("E64"); 3276 } 3277 } 3278 return SendPacket ("E65"); 3279 } 3280 3281 static bool 3282 RNBRemoteShouldCancelCallback (void *not_used) 3283 { 3284 RNBRemoteSP remoteSP(g_remoteSP); 3285 if (remoteSP.get() != NULL) 3286 { 3287 RNBRemote* remote = remoteSP.get(); 3288 if (remote->Comm().IsConnected()) 3289 return false; 3290 else 3291 return true; 3292 } 3293 return true; 3294 } 3295 3296 3297 // FORMAT: _MXXXXXX,PPP 3298 // XXXXXX: big endian hex chars 3299 // PPP: permissions can be any combo of r w x chars 3300 // 3301 // RESPONSE: XXXXXX 3302 // XXXXXX: hex address of the newly allocated memory 3303 // EXX: error code 3304 // 3305 // EXAMPLES: 3306 // _M123000,rw 3307 // _M123000,rwx 3308 // _M123000,xw 3309 3310 rnb_err_t 3311 RNBRemote::HandlePacket_AllocateMemory (const char *p) 3312 { 3313 StringExtractor packet (p); 3314 packet.SetFilePos(2); // Skip the "_M" 3315 3316 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0); 3317 if (size != 0) 3318 { 3319 if (packet.GetChar() == ',') 3320 { 3321 uint32_t permissions = 0; 3322 char ch; 3323 bool success = true; 3324 while (success && (ch = packet.GetChar()) != '\0') 3325 { 3326 switch (ch) 3327 { 3328 case 'r': permissions |= eMemoryPermissionsReadable; break; 3329 case 'w': permissions |= eMemoryPermissionsWritable; break; 3330 case 'x': permissions |= eMemoryPermissionsExecutable; break; 3331 default: success = false; break; 3332 } 3333 } 3334 3335 if (success) 3336 { 3337 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions); 3338 if (addr != INVALID_NUB_ADDRESS) 3339 { 3340 std::ostringstream ostrm; 3341 ostrm << RAW_HEXBASE << addr; 3342 return SendPacket (ostrm.str ()); 3343 } 3344 } 3345 } 3346 } 3347 return SendPacket ("E53"); 3348 } 3349 3350 // FORMAT: _mXXXXXX 3351 // XXXXXX: address that was previously allocated 3352 // 3353 // RESPONSE: XXXXXX 3354 // OK: address was deallocated 3355 // EXX: error code 3356 // 3357 // EXAMPLES: 3358 // _m123000 3359 3360 rnb_err_t 3361 RNBRemote::HandlePacket_DeallocateMemory (const char *p) 3362 { 3363 StringExtractor packet (p); 3364 packet.SetFilePos(2); // Skip the "_m" 3365 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS); 3366 3367 if (addr != INVALID_NUB_ADDRESS) 3368 { 3369 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr)) 3370 return SendPacket ("OK"); 3371 } 3372 return SendPacket ("E54"); 3373 } 3374 3375 3376 // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) 3377 // FORMAT: QSaveRegisterState (when thread suffix is NOT supported) 3378 // TTTT: thread ID in hex 3379 // 3380 // RESPONSE: 3381 // SAVEID: Where SAVEID is a decimal number that represents the save ID 3382 // that can be passed back into a "QRestoreRegisterState" packet 3383 // EXX: error code 3384 // 3385 // EXAMPLES: 3386 // QSaveRegisterState;thread:1E34; (when thread suffix is supported) 3387 // QSaveRegisterState (when thread suffix is NOT supported) 3388 3389 rnb_err_t 3390 RNBRemote::HandlePacket_SaveRegisterState (const char *p) 3391 { 3392 nub_process_t pid = m_ctx.ProcessID (); 3393 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3394 if (tid == INVALID_NUB_THREAD) 3395 { 3396 if (m_thread_suffix_supported) 3397 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 3398 else 3399 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 3400 } 3401 3402 // Get the register context size first by calling with NULL buffer 3403 const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid); 3404 if (save_id != 0) 3405 { 3406 char response[64]; 3407 snprintf (response, sizeof(response), "%u", save_id); 3408 return SendPacket (response); 3409 } 3410 else 3411 { 3412 return SendPacket ("E75"); 3413 } 3414 } 3415 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is supported) 3416 // FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT supported) 3417 // TTTT: thread ID in hex 3418 // SAVEID: a decimal number that represents the save ID that was 3419 // returned from a call to "QSaveRegisterState" 3420 // 3421 // RESPONSE: 3422 // OK: successfully restored registers for the specified thread 3423 // EXX: error code 3424 // 3425 // EXAMPLES: 3426 // QRestoreRegisterState:1;thread:1E34; (when thread suffix is supported) 3427 // QRestoreRegisterState:1 (when thread suffix is NOT supported) 3428 3429 rnb_err_t 3430 RNBRemote::HandlePacket_RestoreRegisterState (const char *p) 3431 { 3432 nub_process_t pid = m_ctx.ProcessID (); 3433 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3434 if (tid == INVALID_NUB_THREAD) 3435 { 3436 if (m_thread_suffix_supported) 3437 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 3438 else 3439 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 3440 } 3441 3442 StringExtractor packet (p); 3443 packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:" 3444 const uint32_t save_id = packet.GetU32(0); 3445 3446 if (save_id != 0) 3447 { 3448 // Get the register context size first by calling with NULL buffer 3449 if (DNBThreadRestoreRegisterState(pid, tid, save_id)) 3450 return SendPacket ("OK"); 3451 else 3452 return SendPacket ("E77"); 3453 } 3454 return SendPacket ("E76"); 3455 } 3456 3457 static bool 3458 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name) 3459 { 3460 bool return_val = true; 3461 while (*p != '\0') 3462 { 3463 char smallbuf[3]; 3464 smallbuf[0] = *p; 3465 smallbuf[1] = *(p + 1); 3466 smallbuf[2] = '\0'; 3467 3468 errno = 0; 3469 int ch = static_cast<int>(strtoul (smallbuf, NULL, 16)); 3470 if (errno != 0 && ch == 0) 3471 { 3472 return_val = false; 3473 break; 3474 } 3475 3476 attach_name.push_back(ch); 3477 p += 2; 3478 } 3479 return return_val; 3480 } 3481 3482 rnb_err_t 3483 RNBRemote::HandlePacket_qSupported (const char *p) 3484 { 3485 uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less 3486 char buf[256]; 3487 snprintf (buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", max_packet_size); 3488 3489 // By default, don't enable compression. It's only worth doing when we are working 3490 // with a low speed communication channel. 3491 bool enable_compression = false; 3492 (void)enable_compression; 3493 3494 // Enable compression when debugserver is running on a watchOS device where communication may be over Bluetooth. 3495 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 3496 enable_compression = true; 3497 #endif 3498 3499 #if defined (HAVE_LIBCOMPRESSION) 3500 // libcompression is weak linked so test if compression_decode_buffer() is available 3501 if (enable_compression && compression_decode_buffer != NULL) 3502 { 3503 strcat (buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;DefaultCompressionMinSize="); 3504 char numbuf[16]; 3505 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3506 numbuf[sizeof (numbuf) - 1] = '\0'; 3507 strcat (buf, numbuf); 3508 } 3509 #elif defined (HAVE_LIBZ) 3510 if (enable_compression) 3511 { 3512 strcat (buf, ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize="); 3513 char numbuf[16]; 3514 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3515 numbuf[sizeof (numbuf) - 1] = '\0'; 3516 strcat (buf, numbuf); 3517 } 3518 #endif 3519 3520 return SendPacket (buf); 3521 } 3522 3523 /* 3524 vAttach;pid 3525 3526 Attach to a new process with the specified process ID. pid is a hexadecimal integer 3527 identifying the process. If the stub is currently controlling a process, it is 3528 killed. The attached process is stopped.This packet is only available in extended 3529 mode (see extended mode). 3530 3531 Reply: 3532 "ENN" for an error 3533 "Any Stop Reply Packet" for success 3534 */ 3535 3536 rnb_err_t 3537 RNBRemote::HandlePacket_v (const char *p) 3538 { 3539 if (strcmp (p, "vCont;c") == 0) 3540 { 3541 // Simple continue 3542 return RNBRemote::HandlePacket_c("c"); 3543 } 3544 else if (strcmp (p, "vCont;s") == 0) 3545 { 3546 // Simple step 3547 return RNBRemote::HandlePacket_s("s"); 3548 } 3549 else if (strstr (p, "vCont") == p) 3550 { 3551 typedef struct 3552 { 3553 nub_thread_t tid; 3554 char action; 3555 int signal; 3556 } vcont_action_t; 3557 3558 DNBThreadResumeActions thread_actions; 3559 char *c = (char *)(p += strlen("vCont")); 3560 char *c_end = c + strlen(c); 3561 if (*c == '?') 3562 return SendPacket ("vCont;c;C;s;S"); 3563 3564 while (c < c_end && *c == ';') 3565 { 3566 ++c; // Skip the semi-colon 3567 DNBThreadResumeAction thread_action; 3568 thread_action.tid = INVALID_NUB_THREAD; 3569 thread_action.state = eStateInvalid; 3570 thread_action.signal = 0; 3571 thread_action.addr = INVALID_NUB_ADDRESS; 3572 3573 char action = *c++; 3574 3575 switch (action) 3576 { 3577 case 'C': 3578 errno = 0; 3579 thread_action.signal = static_cast<int>(strtoul (c, &c, 16)); 3580 if (errno != 0) 3581 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3582 // Fall through to next case... 3583 3584 case 'c': 3585 // Continue 3586 thread_action.state = eStateRunning; 3587 break; 3588 3589 case 'S': 3590 errno = 0; 3591 thread_action.signal = static_cast<int>(strtoul (c, &c, 16)); 3592 if (errno != 0) 3593 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3594 // Fall through to next case... 3595 3596 case 's': 3597 // Step 3598 thread_action.state = eStateStepping; 3599 break; 3600 3601 default: 3602 HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet"); 3603 break; 3604 } 3605 if (*c == ':') 3606 { 3607 errno = 0; 3608 thread_action.tid = strtoul (++c, &c, 16); 3609 if (errno != 0) 3610 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet"); 3611 } 3612 3613 thread_actions.Append (thread_action); 3614 } 3615 3616 // If a default action for all other threads wasn't mentioned 3617 // then we should stop the threads 3618 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3619 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize()); 3620 return rnb_success; 3621 } 3622 else if (strstr (p, "vAttach") == p) 3623 { 3624 nub_process_t attach_pid = INVALID_NUB_PROCESS; // attach_pid will be set to 0 if the attach fails 3625 nub_process_t pid_attaching_to = INVALID_NUB_PROCESS; // pid_attaching_to is the original pid specified 3626 char err_str[1024]={'\0'}; 3627 std::string attach_name; 3628 3629 if (strstr (p, "vAttachWait;") == p) 3630 { 3631 p += strlen("vAttachWait;"); 3632 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3633 { 3634 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 3635 } 3636 const bool ignore_existing = true; 3637 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3638 3639 } 3640 else if (strstr (p, "vAttachOrWait;") == p) 3641 { 3642 p += strlen("vAttachOrWait;"); 3643 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3644 { 3645 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt"); 3646 } 3647 const bool ignore_existing = false; 3648 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3649 } 3650 else if (strstr (p, "vAttachName;") == p) 3651 { 3652 p += strlen("vAttachName;"); 3653 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3654 { 3655 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 3656 } 3657 3658 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str)); 3659 3660 } 3661 else if (strstr (p, "vAttach;") == p) 3662 { 3663 p += strlen("vAttach;"); 3664 char *end = NULL; 3665 pid_attaching_to = static_cast<int>(strtoul (p, &end, 16)); // PID will be in hex, so use base 16 to decode 3666 if (p != end && *end == '\0') 3667 { 3668 // Wait at most 30 second for attach 3669 struct timespec attach_timeout_abstime; 3670 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 3671 attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime, err_str, sizeof(err_str)); 3672 } 3673 } 3674 else 3675 { 3676 return HandlePacket_UNIMPLEMENTED(p); 3677 } 3678 3679 3680 if (attach_pid != INVALID_NUB_PROCESS) 3681 { 3682 if (m_ctx.ProcessID() != attach_pid) 3683 m_ctx.SetProcessID(attach_pid); 3684 // Send a stop reply packet to indicate we successfully attached! 3685 NotifyThatProcessStopped (); 3686 return rnb_success; 3687 } 3688 else 3689 { 3690 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3691 if (err_str[0]) 3692 m_ctx.LaunchStatus().SetErrorString(err_str); 3693 else 3694 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3695 3696 #if defined (__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000) 3697 if (pid_attaching_to == INVALID_NUB_PROCESS && !attach_name.empty()) 3698 { 3699 pid_attaching_to = DNBProcessGetPIDByName (attach_name.c_str()); 3700 } 3701 if (pid_attaching_to != INVALID_NUB_PROCESS && strcmp (err_str, "No such process") != 0) 3702 { 3703 // csr_check(CSR_ALLOW_TASK_FOR_PID) will be nonzero if System Integrity Protection is in effect. 3704 if (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0) 3705 { 3706 bool attach_failed_due_to_sip = false; 3707 3708 if (rootless_allows_task_for_pid (pid_attaching_to) == 0) 3709 { 3710 attach_failed_due_to_sip = true; 3711 } 3712 3713 if (attach_failed_due_to_sip == false) 3714 { 3715 int csops_flags = 0; 3716 int retval = ::csops (pid_attaching_to, CS_OPS_STATUS, &csops_flags, sizeof (csops_flags)); 3717 if (retval != -1 && (csops_flags & CS_RESTRICT)) 3718 { 3719 attach_failed_due_to_sip = true; 3720 } 3721 } 3722 if (attach_failed_due_to_sip) 3723 { 3724 SendPacket ("E87"); // E87 is the magic value which says that we are not allowed to attach 3725 DNBLogError ("Attach failed because process does not allow attaching: \"%s\".", err_str); 3726 return rnb_err; 3727 } 3728 } 3729 } 3730 3731 #endif 3732 3733 SendPacket ("E01"); // E01 is our magic error value for attach failed. 3734 DNBLogError ("Attach failed: \"%s\".", err_str); 3735 return rnb_err; 3736 } 3737 } 3738 3739 // All other failures come through here 3740 return HandlePacket_UNIMPLEMENTED(p); 3741 } 3742 3743 /* 'T XX' -- status of thread 3744 Check if the specified thread is alive. 3745 The thread number is in hex? */ 3746 3747 rnb_err_t 3748 RNBRemote::HandlePacket_T (const char *p) 3749 { 3750 p++; 3751 if (p == NULL || *p == '\0') 3752 { 3753 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet"); 3754 } 3755 if (!m_ctx.HasValidProcessID()) 3756 { 3757 return SendPacket ("E15"); 3758 } 3759 errno = 0; 3760 nub_thread_t tid = strtoul (p, NULL, 16); 3761 if (errno != 0 && tid == 0) 3762 { 3763 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet"); 3764 } 3765 3766 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid); 3767 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) 3768 { 3769 return SendPacket ("E16"); 3770 } 3771 3772 return SendPacket ("OK"); 3773 } 3774 3775 3776 rnb_err_t 3777 RNBRemote::HandlePacket_z (const char *p) 3778 { 3779 if (p == NULL || *p == '\0') 3780 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet"); 3781 3782 if (!m_ctx.HasValidProcessID()) 3783 return SendPacket ("E15"); 3784 3785 char packet_cmd = *p++; 3786 char break_type = *p++; 3787 3788 if (*p++ != ',') 3789 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3790 3791 char *c = NULL; 3792 nub_process_t pid = m_ctx.ProcessID(); 3793 errno = 0; 3794 nub_addr_t addr = strtoull (p, &c, 16); 3795 if (errno != 0 && addr == 0) 3796 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet"); 3797 p = c; 3798 if (*p++ != ',') 3799 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3800 3801 errno = 0; 3802 auto byte_size = strtoul (p, &c, 16); 3803 if (errno != 0 && byte_size == 0) 3804 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet"); 3805 3806 if (packet_cmd == 'Z') 3807 { 3808 // set 3809 switch (break_type) 3810 { 3811 case '0': // set software breakpoint 3812 case '1': // set hardware breakpoint 3813 { 3814 // gdb can send multiple Z packets for the same address and 3815 // these calls must be ref counted. 3816 bool hardware = (break_type == '1'); 3817 3818 if (DNBBreakpointSet (pid, addr, byte_size, hardware)) 3819 { 3820 // We successfully created a breakpoint, now lets full out 3821 // a ref count structure with the breakID and add it to our 3822 // map. 3823 return SendPacket ("OK"); 3824 } 3825 else 3826 { 3827 // We failed to set the software breakpoint 3828 return SendPacket ("E09"); 3829 } 3830 } 3831 break; 3832 3833 case '2': // set write watchpoint 3834 case '3': // set read watchpoint 3835 case '4': // set access watchpoint 3836 { 3837 bool hardware = true; 3838 uint32_t watch_flags = 0; 3839 if (break_type == '2') 3840 watch_flags = WATCH_TYPE_WRITE; 3841 else if (break_type == '3') 3842 watch_flags = WATCH_TYPE_READ; 3843 else 3844 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3845 3846 if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware)) 3847 { 3848 return SendPacket ("OK"); 3849 } 3850 else 3851 { 3852 // We failed to set the watchpoint 3853 return SendPacket ("E09"); 3854 } 3855 } 3856 break; 3857 3858 default: 3859 break; 3860 } 3861 } 3862 else if (packet_cmd == 'z') 3863 { 3864 // remove 3865 switch (break_type) 3866 { 3867 case '0': // remove software breakpoint 3868 case '1': // remove hardware breakpoint 3869 if (DNBBreakpointClear (pid, addr)) 3870 { 3871 return SendPacket ("OK"); 3872 } 3873 else 3874 { 3875 return SendPacket ("E08"); 3876 } 3877 break; 3878 3879 case '2': // remove write watchpoint 3880 case '3': // remove read watchpoint 3881 case '4': // remove access watchpoint 3882 if (DNBWatchpointClear (pid, addr)) 3883 { 3884 return SendPacket ("OK"); 3885 } 3886 else 3887 { 3888 return SendPacket ("E08"); 3889 } 3890 break; 3891 3892 default: 3893 break; 3894 } 3895 } 3896 return HandlePacket_UNIMPLEMENTED(p); 3897 } 3898 3899 // Extract the thread number from the thread suffix that might be appended to 3900 // thread specific packets. This will only be enabled if m_thread_suffix_supported 3901 // is true. 3902 nub_thread_t 3903 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p) 3904 { 3905 if (m_thread_suffix_supported) 3906 { 3907 nub_thread_t tid = INVALID_NUB_THREAD; 3908 if (p) 3909 { 3910 const char *tid_cstr = strstr (p, "thread:"); 3911 if (tid_cstr) 3912 { 3913 tid_cstr += strlen ("thread:"); 3914 tid = strtoul(tid_cstr, NULL, 16); 3915 } 3916 } 3917 return tid; 3918 } 3919 return GetCurrentThread(); 3920 3921 } 3922 3923 /* 'p XX' 3924 print the contents of register X */ 3925 3926 rnb_err_t 3927 RNBRemote::HandlePacket_p (const char *p) 3928 { 3929 if (g_num_reg_entries == 0) 3930 InitializeRegisters (); 3931 3932 if (p == NULL || *p == '\0') 3933 { 3934 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3935 } 3936 if (!m_ctx.HasValidProcessID()) 3937 { 3938 return SendPacket ("E15"); 3939 } 3940 nub_process_t pid = m_ctx.ProcessID(); 3941 errno = 0; 3942 char *tid_cstr = NULL; 3943 uint32_t reg = static_cast<uint32_t>(strtoul (p + 1, &tid_cstr, 16)); 3944 if (errno != 0 && reg == 0) 3945 { 3946 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet"); 3947 } 3948 3949 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr); 3950 if (tid == INVALID_NUB_THREAD) 3951 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3952 3953 const register_map_entry_t *reg_entry; 3954 3955 if (reg < g_num_reg_entries) 3956 reg_entry = &g_reg_entries[reg]; 3957 else 3958 reg_entry = NULL; 3959 3960 std::ostringstream ostrm; 3961 if (reg_entry == NULL) 3962 { 3963 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg); 3964 ostrm << "00000000"; 3965 } 3966 else if (reg_entry->nub_info.reg == (uint32_t)-1) 3967 { 3968 if (reg_entry->nub_info.size > 0) 3969 { 3970 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 3971 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 3972 } 3973 } 3974 else 3975 { 3976 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL); 3977 } 3978 return SendPacket (ostrm.str()); 3979 } 3980 3981 /* 'Pnn=rrrrr' 3982 Set register number n to value r. 3983 n and r are hex strings. */ 3984 3985 rnb_err_t 3986 RNBRemote::HandlePacket_P (const char *p) 3987 { 3988 if (g_num_reg_entries == 0) 3989 InitializeRegisters (); 3990 3991 if (p == NULL || *p == '\0') 3992 { 3993 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet"); 3994 } 3995 if (!m_ctx.HasValidProcessID()) 3996 { 3997 return SendPacket ("E28"); 3998 } 3999 4000 nub_process_t pid = m_ctx.ProcessID(); 4001 4002 StringExtractor packet (p); 4003 4004 const char cmd_char = packet.GetChar(); 4005 // Register ID is always in big endian 4006 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX); 4007 const char equal_char = packet.GetChar(); 4008 4009 if (cmd_char != 'P') 4010 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet"); 4011 4012 if (reg == UINT32_MAX) 4013 return SendPacket ("E29"); 4014 4015 if (equal_char != '=') 4016 return SendPacket ("E30"); 4017 4018 const register_map_entry_t *reg_entry; 4019 4020 if (reg >= g_num_reg_entries) 4021 return SendPacket("E47"); 4022 4023 reg_entry = &g_reg_entries[reg]; 4024 4025 if (reg_entry->nub_info.set == (uint32_t)-1 && reg_entry->nub_info.reg == (uint32_t)-1) 4026 { 4027 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); 4028 return SendPacket("E48"); 4029 } 4030 4031 DNBRegisterValue reg_value; 4032 reg_value.info = reg_entry->nub_info; 4033 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 4034 4035 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 4036 if (tid == INVALID_NUB_THREAD) 4037 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 4038 4039 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 4040 { 4041 return SendPacket ("E32"); 4042 } 4043 return SendPacket ("OK"); 4044 } 4045 4046 /* 'c [addr]' 4047 Continue, optionally from a specified address. */ 4048 4049 rnb_err_t 4050 RNBRemote::HandlePacket_c (const char *p) 4051 { 4052 const nub_process_t pid = m_ctx.ProcessID(); 4053 4054 if (pid == INVALID_NUB_PROCESS) 4055 return SendPacket ("E23"); 4056 4057 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 4058 4059 if (*(p + 1) != '\0') 4060 { 4061 action.tid = GetContinueThread(); 4062 errno = 0; 4063 action.addr = strtoull (p + 1, NULL, 16); 4064 if (errno != 0 && action.addr == 0) 4065 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet"); 4066 } 4067 4068 DNBThreadResumeActions thread_actions; 4069 thread_actions.Append(action); 4070 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 4071 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4072 return SendPacket ("E25"); 4073 // Don't send an "OK" packet; response is the stopped/exited message. 4074 return rnb_success; 4075 } 4076 4077 rnb_err_t 4078 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) 4079 { 4080 /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code) 4081 for the memory region containing a given address and return that information. 4082 4083 Users of this packet must be prepared for three results: 4084 4085 Region information is returned 4086 Region information is unavailable for this address because the address is in unmapped memory 4087 Region lookup cannot be performed on this platform or process is not yet launched 4088 This packet isn't implemented 4089 4090 Examples of use: 4091 qMemoryRegionInfo:3a55140 4092 start:3a50000,size:100000,permissions:rwx 4093 4094 qMemoryRegionInfo:0 4095 error:address in unmapped region 4096 4097 qMemoryRegionInfo:3a551140 (on a different platform) 4098 error:region lookup cannot be performed 4099 4100 qMemoryRegionInfo 4101 OK // this packet is implemented by the remote nub 4102 */ 4103 4104 p += sizeof ("qMemoryRegionInfo") - 1; 4105 if (*p == '\0') 4106 return SendPacket ("OK"); 4107 if (*p++ != ':') 4108 return SendPacket ("E67"); 4109 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 4110 p += 2; 4111 4112 errno = 0; 4113 uint64_t address = strtoul (p, NULL, 16); 4114 if (errno != 0 && address == 0) 4115 { 4116 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 4117 } 4118 4119 DNBRegionInfo region_info = { 0, 0, 0 }; 4120 DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); 4121 std::ostringstream ostrm; 4122 4123 // start:3a50000,size:100000,permissions:rwx 4124 ostrm << "start:" << std::hex << region_info.addr << ';'; 4125 4126 if (region_info.size > 0) 4127 ostrm << "size:" << std::hex << region_info.size << ';'; 4128 4129 if (region_info.permissions) 4130 { 4131 ostrm << "permissions:"; 4132 4133 if (region_info.permissions & eMemoryPermissionsReadable) 4134 ostrm << 'r'; 4135 if (region_info.permissions & eMemoryPermissionsWritable) 4136 ostrm << 'w'; 4137 if (region_info.permissions & eMemoryPermissionsExecutable) 4138 ostrm << 'x'; 4139 ostrm << ';'; 4140 } 4141 return SendPacket (ostrm.str()); 4142 } 4143 4144 // qGetProfileData;scan_type:0xYYYYYYY 4145 rnb_err_t 4146 RNBRemote::HandlePacket_GetProfileData (const char *p) 4147 { 4148 nub_process_t pid = m_ctx.ProcessID(); 4149 if (pid == INVALID_NUB_PROCESS) 4150 return SendPacket ("OK"); 4151 4152 StringExtractor packet(p += sizeof ("qGetProfileData")); 4153 DNBProfileDataScanType scan_type = eProfileAll; 4154 std::string name; 4155 std::string value; 4156 while (packet.GetNameColonValue(name, value)) 4157 { 4158 if (name.compare ("scan_type") == 0) 4159 { 4160 std::istringstream iss(value); 4161 uint32_t int_value = 0; 4162 if (iss >> std::hex >> int_value) 4163 { 4164 scan_type = (DNBProfileDataScanType)int_value; 4165 } 4166 } 4167 } 4168 4169 std::string data = DNBProcessGetProfileData(pid, scan_type); 4170 if (!data.empty()) 4171 { 4172 return SendPacket (data.c_str()); 4173 } 4174 else 4175 { 4176 return SendPacket ("OK"); 4177 } 4178 } 4179 4180 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 4181 rnb_err_t 4182 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p) 4183 { 4184 nub_process_t pid = m_ctx.ProcessID(); 4185 if (pid == INVALID_NUB_PROCESS) 4186 return SendPacket ("OK"); 4187 4188 StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling")); 4189 bool enable = false; 4190 uint64_t interval_usec = 0; 4191 DNBProfileDataScanType scan_type = eProfileAll; 4192 std::string name; 4193 std::string value; 4194 while (packet.GetNameColonValue(name, value)) 4195 { 4196 if (name.compare ("enable") == 0) 4197 { 4198 enable = strtoul(value.c_str(), NULL, 10) > 0; 4199 } 4200 else if (name.compare ("interval_usec") == 0) 4201 { 4202 interval_usec = strtoul(value.c_str(), NULL, 10); 4203 } 4204 else if (name.compare ("scan_type") == 0) 4205 { 4206 std::istringstream iss(value); 4207 uint32_t int_value = 0; 4208 if (iss >> std::hex >> int_value) 4209 { 4210 scan_type = (DNBProfileDataScanType)int_value; 4211 } 4212 } 4213 } 4214 4215 if (interval_usec == 0) 4216 { 4217 enable = 0; 4218 } 4219 4220 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 4221 return SendPacket ("OK"); 4222 } 4223 4224 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO COMPRESS>; 4225 // 4226 // type: must be a type previously reported by the qXfer:features: SupportedCompressions list 4227 // 4228 // minsize: is optional; by default the qXfer:features: DefaultCompressionMinSize value is used 4229 // debugserver may have a better idea of what a good minimum packet size to compress is than lldb. 4230 4231 rnb_err_t 4232 RNBRemote::HandlePacket_QEnableCompression (const char *p) 4233 { 4234 p += sizeof ("QEnableCompression:") - 1; 4235 4236 size_t new_compression_minsize = m_compression_minsize; 4237 const char *new_compression_minsize_str = strstr (p, "minsize:"); 4238 if (new_compression_minsize_str) 4239 { 4240 new_compression_minsize_str += strlen ("minsize:"); 4241 errno = 0; 4242 new_compression_minsize = strtoul (new_compression_minsize_str, NULL, 10); 4243 if (errno != 0 || new_compression_minsize == ULONG_MAX) 4244 { 4245 new_compression_minsize = m_compression_minsize; 4246 } 4247 } 4248 4249 #if defined (HAVE_LIBCOMPRESSION) 4250 if (compression_decode_buffer != NULL) 4251 { 4252 if (strstr (p, "type:zlib-deflate;") != nullptr) 4253 { 4254 EnableCompressionNextSendPacket (compression_types::zlib_deflate); 4255 m_compression_minsize = new_compression_minsize; 4256 return SendPacket ("OK"); 4257 } 4258 else if (strstr (p, "type:lz4;") != nullptr) 4259 { 4260 EnableCompressionNextSendPacket (compression_types::lz4); 4261 m_compression_minsize = new_compression_minsize; 4262 return SendPacket ("OK"); 4263 } 4264 else if (strstr (p, "type:lzma;") != nullptr) 4265 { 4266 EnableCompressionNextSendPacket (compression_types::lzma); 4267 m_compression_minsize = new_compression_minsize; 4268 return SendPacket ("OK"); 4269 } 4270 else if (strstr (p, "type:lzfse;") != nullptr) 4271 { 4272 EnableCompressionNextSendPacket (compression_types::lzfse); 4273 m_compression_minsize = new_compression_minsize; 4274 return SendPacket ("OK"); 4275 } 4276 } 4277 #endif 4278 4279 #if defined (HAVE_LIBZ) 4280 if (strstr (p, "type:zlib-deflate;") != nullptr) 4281 { 4282 EnableCompressionNextSendPacket (compression_types::zlib_deflate); 4283 m_compression_minsize = new_compression_minsize; 4284 return SendPacket ("OK"); 4285 } 4286 #endif 4287 4288 return SendPacket ("E88"); 4289 } 4290 4291 rnb_err_t 4292 RNBRemote::HandlePacket_qSpeedTest (const char *p) 4293 { 4294 p += strlen ("qSpeedTest:response_size:"); 4295 char *end = NULL; 4296 errno = 0; 4297 uint64_t response_size = ::strtoul (p, &end, 16); 4298 if (errno != 0) 4299 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Didn't find response_size value at right offset"); 4300 else if (*end == ';') 4301 { 4302 static char g_data[4*1024*1024+16] = "data:"; 4303 memset(g_data + 5, 'a', response_size); 4304 g_data[response_size + 5] = '\0'; 4305 return SendPacket (g_data); 4306 } 4307 else 4308 { 4309 return SendPacket ("E79"); 4310 } 4311 } 4312 4313 rnb_err_t 4314 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p) 4315 { 4316 /* This packet simply returns the number of supported hardware watchpoints. 4317 4318 Examples of use: 4319 qWatchpointSupportInfo: 4320 num:4 4321 4322 qWatchpointSupportInfo 4323 OK // this packet is implemented by the remote nub 4324 */ 4325 4326 p += sizeof ("qWatchpointSupportInfo") - 1; 4327 if (*p == '\0') 4328 return SendPacket ("OK"); 4329 if (*p++ != ':') 4330 return SendPacket ("E67"); 4331 4332 errno = 0; 4333 uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID()); 4334 std::ostringstream ostrm; 4335 4336 // size:4 4337 ostrm << "num:" << std::dec << num << ';'; 4338 return SendPacket (ostrm.str()); 4339 } 4340 4341 /* 'C sig [;addr]' 4342 Resume with signal sig, optionally at address addr. */ 4343 4344 rnb_err_t 4345 RNBRemote::HandlePacket_C (const char *p) 4346 { 4347 const nub_process_t pid = m_ctx.ProcessID(); 4348 4349 if (pid == INVALID_NUB_PROCESS) 4350 return SendPacket ("E36"); 4351 4352 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 4353 int process_signo = -1; 4354 if (*(p + 1) != '\0') 4355 { 4356 action.tid = GetContinueThread(); 4357 char *end = NULL; 4358 errno = 0; 4359 process_signo = static_cast<int>(strtoul (p + 1, &end, 16)); 4360 if (errno != 0) 4361 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet"); 4362 else if (*end == ';') 4363 { 4364 errno = 0; 4365 action.addr = strtoull (end + 1, NULL, 16); 4366 if (errno != 0 && action.addr == 0) 4367 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet"); 4368 } 4369 } 4370 4371 DNBThreadResumeActions thread_actions; 4372 thread_actions.Append (action); 4373 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal); 4374 if (!DNBProcessSignal(pid, process_signo)) 4375 return SendPacket ("E52"); 4376 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4377 return SendPacket ("E38"); 4378 /* Don't send an "OK" packet; response is the stopped/exited message. */ 4379 return rnb_success; 4380 } 4381 4382 //---------------------------------------------------------------------- 4383 // 'D' packet 4384 // Detach from gdb. 4385 //---------------------------------------------------------------------- 4386 rnb_err_t 4387 RNBRemote::HandlePacket_D (const char *p) 4388 { 4389 if (m_ctx.HasValidProcessID()) 4390 { 4391 if (DNBProcessDetach(m_ctx.ProcessID())) 4392 SendPacket ("OK"); 4393 else 4394 SendPacket ("E"); 4395 } 4396 else 4397 { 4398 SendPacket ("E"); 4399 } 4400 return rnb_success; 4401 } 4402 4403 /* 'k' 4404 Kill the inferior process. */ 4405 4406 rnb_err_t 4407 RNBRemote::HandlePacket_k (const char *p) 4408 { 4409 DNBLog ("Got a 'k' packet, killing the inferior process."); 4410 // No response to should be sent to the kill packet 4411 if (m_ctx.HasValidProcessID()) 4412 DNBProcessKill (m_ctx.ProcessID()); 4413 SendPacket ("X09"); 4414 return rnb_success; 4415 } 4416 4417 rnb_err_t 4418 RNBRemote::HandlePacket_stop_process (const char *p) 4419 { 4420 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt 4421 #if defined(TEST_EXIT_ON_INTERRUPT) 4422 rnb_err_t err = HandlePacket_k (p); 4423 m_comm.Disconnect(true); 4424 return err; 4425 #else 4426 if (!DNBProcessInterrupt(m_ctx.ProcessID())) 4427 { 4428 // If we failed to interrupt the process, then send a stop 4429 // reply packet as the process was probably already stopped 4430 HandlePacket_last_signal (NULL); 4431 } 4432 return rnb_success; 4433 #endif 4434 } 4435 4436 /* 's' 4437 Step the inferior process. */ 4438 4439 rnb_err_t 4440 RNBRemote::HandlePacket_s (const char *p) 4441 { 4442 const nub_process_t pid = m_ctx.ProcessID(); 4443 if (pid == INVALID_NUB_PROCESS) 4444 return SendPacket ("E32"); 4445 4446 // Hardware supported stepping not supported on arm 4447 nub_thread_t tid = GetContinueThread (); 4448 if (tid == 0 || tid == (nub_thread_t)-1) 4449 tid = GetCurrentThread(); 4450 4451 if (tid == INVALID_NUB_THREAD) 4452 return SendPacket ("E33"); 4453 4454 DNBThreadResumeActions thread_actions; 4455 thread_actions.AppendAction(tid, eStateStepping); 4456 4457 // Make all other threads stop when we are stepping 4458 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 4459 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4460 return SendPacket ("E49"); 4461 // Don't send an "OK" packet; response is the stopped/exited message. 4462 return rnb_success; 4463 } 4464 4465 /* 'S sig [;addr]' 4466 Step with signal sig, optionally at address addr. */ 4467 4468 rnb_err_t 4469 RNBRemote::HandlePacket_S (const char *p) 4470 { 4471 const nub_process_t pid = m_ctx.ProcessID(); 4472 if (pid == INVALID_NUB_PROCESS) 4473 return SendPacket ("E36"); 4474 4475 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 4476 4477 if (*(p + 1) != '\0') 4478 { 4479 char *end = NULL; 4480 errno = 0; 4481 action.signal = static_cast<int>(strtoul (p + 1, &end, 16)); 4482 if (errno != 0) 4483 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 4484 else if (*end == ';') 4485 { 4486 errno = 0; 4487 action.addr = strtoull (end + 1, NULL, 16); 4488 if (errno != 0 && action.addr == 0) 4489 { 4490 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 4491 } 4492 } 4493 } 4494 4495 action.tid = GetContinueThread (); 4496 if (action.tid == 0 || action.tid == (nub_thread_t)-1) 4497 return SendPacket ("E40"); 4498 4499 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 4500 if (tstate == eStateInvalid || tstate == eStateExited) 4501 return SendPacket ("E37"); 4502 4503 4504 DNBThreadResumeActions thread_actions; 4505 thread_actions.Append (action); 4506 4507 // Make all other threads stop when we are stepping 4508 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4509 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4510 return SendPacket ("E39"); 4511 4512 // Don't send an "OK" packet; response is the stopped/exited message. 4513 return rnb_success; 4514 } 4515 4516 static const char * 4517 GetArchName (const uint32_t cputype, const uint32_t cpusubtype) 4518 { 4519 switch (cputype) 4520 { 4521 case CPU_TYPE_ARM: 4522 switch (cpusubtype) 4523 { 4524 case 5: return "armv4"; 4525 case 6: return "armv6"; 4526 case 7: return "armv5t"; 4527 case 8: return "xscale"; 4528 case 9: return "armv7"; 4529 case 10: return "armv7f"; 4530 case 11: return "armv7s"; 4531 case 12: return "armv7k"; 4532 case 14: return "armv6m"; 4533 case 15: return "armv7m"; 4534 case 16: return "armv7em"; 4535 default: return "arm"; 4536 } 4537 break; 4538 case CPU_TYPE_ARM64: return "arm64"; 4539 case CPU_TYPE_I386: return "i386"; 4540 case CPU_TYPE_X86_64: 4541 switch (cpusubtype) 4542 { 4543 default: return "x86_64"; 4544 case 8: return "x86_64h"; 4545 } 4546 break; 4547 } 4548 return NULL; 4549 } 4550 4551 static bool 4552 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64) 4553 { 4554 static uint32_t g_host_cputype = 0; 4555 static uint32_t g_host_cpusubtype = 0; 4556 static uint32_t g_is_64_bit_capable = 0; 4557 static bool g_promoted_to_64 = false; 4558 4559 if (g_host_cputype == 0) 4560 { 4561 g_promoted_to_64 = false; 4562 size_t len = sizeof(uint32_t); 4563 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) 4564 { 4565 len = sizeof (uint32_t); 4566 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0) 4567 { 4568 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) 4569 { 4570 g_promoted_to_64 = true; 4571 g_host_cputype |= CPU_ARCH_ABI64; 4572 } 4573 } 4574 } 4575 4576 len = sizeof(uint32_t); 4577 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0) 4578 { 4579 if (g_promoted_to_64 && 4580 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486) 4581 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4582 } 4583 } 4584 4585 cputype = g_host_cputype; 4586 cpusubtype = g_host_cpusubtype; 4587 is_64_bit_capable = g_is_64_bit_capable; 4588 promoted_to_64 = g_promoted_to_64; 4589 return g_host_cputype != 0; 4590 } 4591 4592 rnb_err_t 4593 RNBRemote::HandlePacket_qHostInfo (const char *p) 4594 { 4595 std::ostringstream strm; 4596 4597 uint32_t cputype = 0; 4598 uint32_t cpusubtype = 0; 4599 uint32_t is_64_bit_capable = 0; 4600 bool promoted_to_64 = false; 4601 if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) 4602 { 4603 strm << "cputype:" << std::dec << cputype << ';'; 4604 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4605 } 4606 4607 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4608 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4609 // this for now. 4610 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 4611 { 4612 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 4613 strm << "ostype:tvos;"; 4614 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4615 strm << "ostype:watchos;"; 4616 #else 4617 strm << "ostype:ios;"; 4618 #endif 4619 4620 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 4621 strm << "watchpoint_exceptions_received:before;"; 4622 } 4623 else 4624 { 4625 strm << "ostype:macosx;"; 4626 strm << "watchpoint_exceptions_received:after;"; 4627 } 4628 // char ostype[64]; 4629 // len = sizeof(ostype); 4630 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4631 // { 4632 // len = strlen(ostype); 4633 // std::transform (ostype, ostype + len, ostype, tolower); 4634 // strm << "ostype:" << std::dec << ostype << ';'; 4635 // } 4636 4637 strm << "vendor:apple;"; 4638 4639 uint64_t major, minor, patch; 4640 if (DNBGetOSVersionNumbers (&major, &minor, &patch)) 4641 { 4642 strm << "osmajor:" << major << ";"; 4643 strm << "osminor:" << minor << ";"; 4644 strm << "ospatch:" << patch << ";"; 4645 4646 strm << "version:" << major << "." << minor; 4647 if (patch != 0) 4648 { 4649 strm << "." << patch; 4650 } 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 dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum); 5158 if (!queue_name.empty()) 5159 thread_dict_sp->AddStringItem("qname", queue_name); 5160 if (queue_width == 1) 5161 thread_dict_sp->AddStringItem("qkind", "serial"); 5162 else if (queue_width > 1) 5163 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5164 if (queue_serialnum > 0) 5165 thread_dict_sp->AddIntegerItem("qserial", queue_serialnum); 5166 } 5167 } 5168 } 5169 5170 DNBRegisterValue reg_value; 5171 5172 if (g_reg_entries != NULL) 5173 { 5174 JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary()); 5175 5176 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 5177 { 5178 // Expedite all registers in the first register set that aren't 5179 // contained in other registers 5180 if (g_reg_entries[reg].nub_info.set == 1 && 5181 g_reg_entries[reg].nub_info.value_regs == NULL) 5182 { 5183 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 5184 continue; 5185 5186 std::ostringstream reg_num; 5187 reg_num << std::dec << g_reg_entries[reg].debugserver_regnum; 5188 // Encode native byte ordered bytes as hex ascii 5189 registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size); 5190 } 5191 } 5192 thread_dict_sp->AddItem("registers", registers_dict_sp); 5193 } 5194 5195 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 5196 // frame pointer chain. 5197 StackMemoryMap stack_mmap; 5198 ReadStackMemory (pid, tid, stack_mmap); 5199 if (!stack_mmap.empty()) 5200 { 5201 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5202 5203 for (const auto &stack_memory : stack_mmap) 5204 { 5205 JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary()); 5206 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5207 stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length); 5208 memory_array_sp->AddItem(stack_memory_sp); 5209 } 5210 thread_dict_sp->AddItem("memory", memory_array_sp); 5211 } 5212 } 5213 5214 threads_array_sp->AddItem(thread_dict_sp); 5215 } 5216 } 5217 return threads_array_sp; 5218 } 5219 5220 rnb_err_t 5221 RNBRemote::HandlePacket_jThreadsInfo (const char *p) 5222 { 5223 JSONGenerator::ObjectSP threads_info_sp; 5224 std::ostringstream json; 5225 std::ostringstream reply_strm; 5226 // If we haven't run the process yet, return an error. 5227 if (m_ctx.HasValidProcessID()) 5228 { 5229 const bool threads_with_valid_stop_info_only = false; 5230 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5231 5232 if (threads_info_sp) 5233 { 5234 std::ostringstream strm; 5235 threads_info_sp->Dump (strm); 5236 std::string binary_packet = binary_encode_string (strm.str()); 5237 if (!binary_packet.empty()) 5238 return SendPacket (binary_packet.c_str()); 5239 } 5240 } 5241 return SendPacket ("E85"); 5242 5243 } 5244 5245 rnb_err_t 5246 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) 5247 { 5248 nub_process_t pid; 5249 std::ostringstream json; 5250 // If we haven't run the process yet, return an error. 5251 if (!m_ctx.HasValidProcessID()) 5252 { 5253 return SendPacket ("E81"); 5254 } 5255 5256 pid = m_ctx.ProcessID(); 5257 5258 const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" }; 5259 if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0) 5260 { 5261 p += strlen (thread_extended_info_str); 5262 5263 uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p); 5264 uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p); 5265 uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p); 5266 uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p); 5267 uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p); 5268 // Commented out the two variables below as they are not being used 5269 // uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p); 5270 // uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p); 5271 5272 if (tid != INVALID_NUB_ADDRESS) 5273 { 5274 nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid); 5275 5276 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5277 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS 5278 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS 5279 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) 5280 { 5281 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5282 } 5283 5284 bool timed_out = false; 5285 Genealogy::ThreadActivitySP thread_activity_sp; 5286 5287 // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base 5288 // and got an invalid value back, then we have a thread in early startup or shutdown and 5289 // it's possible that gathering the genealogy information for this thread go badly. 5290 // Ideally fetching this info for a thread in these odd states shouldn't matter - but 5291 // we've seen some problems with these new SPI and threads in edge-casey states. 5292 5293 double genealogy_fetch_time = 0; 5294 if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS) 5295 { 5296 DNBTimer timer(false); 5297 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out); 5298 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5299 } 5300 5301 std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen 5302 5303 json << "{"; 5304 5305 bool need_to_print_comma = false; 5306 5307 if (thread_activity_sp && timed_out == false) 5308 { 5309 const Genealogy::Activity *activity = &thread_activity_sp->current_activity; 5310 bool need_vouchers_comma_sep = false; 5311 json << "\"activity_query_timed_out\":false,"; 5312 if (genealogy_fetch_time != 0) 5313 { 5314 // If we append the floating point value with << we'll get it in scientific 5315 // notation. 5316 char floating_point_ascii_buffer[64]; 5317 floating_point_ascii_buffer[0] = '\0'; 5318 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5319 if (strlen (floating_point_ascii_buffer) > 0) 5320 { 5321 if (need_to_print_comma) 5322 json << ","; 5323 need_to_print_comma = true; 5324 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5325 } 5326 } 5327 if (activity->activity_id != 0) 5328 { 5329 if (need_to_print_comma) 5330 json << ","; 5331 need_to_print_comma = true; 5332 need_vouchers_comma_sep = true; 5333 json << "\"activity\":{"; 5334 json << "\"start\":" << activity->activity_start << ","; 5335 json << "\"id\":" << activity->activity_id << ","; 5336 json << "\"parent_id\":" << activity->parent_id << ","; 5337 json << "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\","; 5338 json << "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\""; 5339 json << "}"; 5340 } 5341 if (thread_activity_sp->messages.size() > 0) 5342 { 5343 need_to_print_comma = true; 5344 if (need_vouchers_comma_sep) 5345 json << ","; 5346 need_vouchers_comma_sep = true; 5347 json << "\"trace_messages\":["; 5348 bool printed_one_message = false; 5349 for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter) 5350 { 5351 if (printed_one_message) 5352 json << ","; 5353 else 5354 printed_one_message = true; 5355 json << "{"; 5356 json << "\"timestamp\":" << iter->timestamp << ","; 5357 json << "\"activity_id\":" << iter->activity_id << ","; 5358 json << "\"trace_id\":" << iter->trace_id << ","; 5359 json << "\"thread\":" << iter->thread << ","; 5360 json << "\"type\":" << (int) iter->type << ","; 5361 json << "\"process_info_index\":" << iter->process_info_index << ","; 5362 process_info_indexes.insert (iter->process_info_index); 5363 json << "\"message\":\"" << json_string_quote_metachars (iter->message) << "\""; 5364 json << "}"; 5365 } 5366 json << "]"; 5367 } 5368 if (thread_activity_sp->breadcrumbs.size() == 1) 5369 { 5370 need_to_print_comma = true; 5371 if (need_vouchers_comma_sep) 5372 json << ","; 5373 need_vouchers_comma_sep = true; 5374 json << "\"breadcrumb\":{"; 5375 for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter) 5376 { 5377 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5378 json << "\"activity_id\":" << iter->activity_id << ","; 5379 json << "\"timestamp\":" << iter->timestamp << ","; 5380 json << "\"name\":\"" << json_string_quote_metachars (iter->name) << "\""; 5381 } 5382 json << "}"; 5383 } 5384 if (process_info_indexes.size() > 0) 5385 { 5386 need_to_print_comma = true; 5387 if (need_vouchers_comma_sep) 5388 json << ","; 5389 need_vouchers_comma_sep = true; 5390 json << "\"process_infos\":["; 5391 bool printed_one_process_info = false; 5392 for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter) 5393 { 5394 if (printed_one_process_info) 5395 json << ","; 5396 else 5397 printed_one_process_info = true; 5398 Genealogy::ProcessExecutableInfoSP image_info_sp; 5399 uint32_t idx = *iter; 5400 image_info_sp = DNBGetGenealogyImageInfo (pid, idx); 5401 json << "{"; 5402 char uuid_buf[37]; 5403 uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf); 5404 json << "\"process_info_index\":" << idx << ","; 5405 json << "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\","; 5406 json << "\"image_uuid\":\"" << uuid_buf <<"\""; 5407 json << "}"; 5408 } 5409 json << "]"; 5410 } 5411 } 5412 else 5413 { 5414 if (timed_out) 5415 { 5416 if (need_to_print_comma) 5417 json << ","; 5418 need_to_print_comma = true; 5419 json << "\"activity_query_timed_out\":true"; 5420 if (genealogy_fetch_time != 0) 5421 { 5422 // If we append the floating point value with << we'll get it in scientific 5423 // notation. 5424 char floating_point_ascii_buffer[64]; 5425 floating_point_ascii_buffer[0] = '\0'; 5426 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5427 if (strlen (floating_point_ascii_buffer) > 0) 5428 { 5429 json << ","; 5430 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5431 } 5432 } 5433 } 5434 } 5435 5436 if (tsd_address != INVALID_NUB_ADDRESS) 5437 { 5438 if (need_to_print_comma) 5439 json << ","; 5440 need_to_print_comma = true; 5441 json << "\"tsd_address\":" << tsd_address; 5442 5443 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) 5444 { 5445 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index); 5446 if (requested_qos.IsValid()) 5447 { 5448 if (need_to_print_comma) 5449 json << ","; 5450 need_to_print_comma = true; 5451 json << "\"requested_qos\":{"; 5452 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5453 json << "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\","; 5454 json << "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\""; 5455 json << "}"; 5456 } 5457 } 5458 } 5459 5460 if (pthread_t_value != INVALID_NUB_ADDRESS) 5461 { 5462 if (need_to_print_comma) 5463 json << ","; 5464 need_to_print_comma = true; 5465 json << "\"pthread_t\":" << pthread_t_value; 5466 } 5467 5468 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid); 5469 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) 5470 { 5471 if (need_to_print_comma) 5472 json << ","; 5473 need_to_print_comma = true; 5474 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5475 } 5476 5477 json << "}"; 5478 std::string json_quoted = binary_encode_string (json.str()); 5479 return SendPacket (json_quoted); 5480 } 5481 } 5482 return SendPacket ("OK"); 5483 } 5484 5485 rnb_err_t 5486 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p) 5487 { 5488 nub_process_t pid; 5489 // If we haven't run the process yet, return an error. 5490 if (!m_ctx.HasValidProcessID()) 5491 { 5492 return SendPacket ("E83"); 5493 } 5494 5495 pid = m_ctx.ProcessID(); 5496 5497 const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" }; 5498 if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0) 5499 { 5500 p += strlen (get_loaded_dynamic_libraries_infos_str); 5501 5502 nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p); 5503 nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p); 5504 5505 if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS) 5506 { 5507 JSONGenerator::ObjectSP json_sp; 5508 5509 json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count); 5510 5511 if (json_sp.get()) 5512 { 5513 std::ostringstream json_str; 5514 json_sp->Dump (json_str); 5515 if (json_str.str().size() > 0) 5516 { 5517 std::string json_str_quoted = binary_encode_string (json_str.str()); 5518 return SendPacket (json_str_quoted.c_str()); 5519 } 5520 else 5521 { 5522 SendPacket ("E84"); 5523 } 5524 } 5525 } 5526 } 5527 return SendPacket ("OK"); 5528 } 5529 5530 static bool 5531 MachHeaderIsMainExecutable (nub_process_t pid, uint32_t addr_size, nub_addr_t mach_header_addr, mach_header &mh) 5532 { 5533 DNBLogThreadedIf (LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = %u, mach_header_addr = 0x%16.16llx)", pid, addr_size, mach_header_addr); 5534 const nub_size_t bytes_read = DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh); 5535 if (bytes_read == sizeof(mh)) 5536 { 5537 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); 5538 if ((addr_size == 4 && mh.magic == MH_MAGIC) || 5539 (addr_size == 8 && mh.magic == MH_MAGIC_64)) 5540 { 5541 if (mh.filetype == MH_EXECUTE) 5542 { 5543 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); 5544 return true; 5545 } 5546 } 5547 } 5548 return false; 5549 } 5550 5551 static nub_addr_t 5552 GetMachHeaderForMainExecutable (const nub_process_t pid, const uint32_t addr_size, mach_header &mh) 5553 { 5554 struct AllImageInfos 5555 { 5556 uint32_t version; 5557 uint32_t dylib_info_count; 5558 uint64_t dylib_info_addr; 5559 }; 5560 5561 uint64_t mach_header_addr = 0; 5562 5563 const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress (pid); 5564 uint8_t bytes[256]; 5565 nub_size_t bytes_read = 0; 5566 DNBDataRef data (bytes, sizeof(bytes), false); 5567 DNBDataRef::offset_t offset = 0; 5568 data.SetPointerSize(addr_size); 5569 5570 //---------------------------------------------------------------------- 5571 // When we are sitting at __dyld_start, the kernel has placed the 5572 // address of the mach header of the main executable on the stack. If we 5573 // read the SP and dereference a pointer, we might find the mach header 5574 // for the executable. We also just make sure there is only 1 thread 5575 // since if we are at __dyld_start we shouldn't have multiple threads. 5576 //---------------------------------------------------------------------- 5577 if (DNBProcessGetNumThreads(pid) == 1) 5578 { 5579 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0); 5580 if (tid != INVALID_NUB_THREAD) 5581 { 5582 DNBRegisterValue sp_value; 5583 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_SP, &sp_value)) 5584 { 5585 uint64_t sp = addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32; 5586 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes); 5587 if (bytes_read == addr_size) 5588 { 5589 offset = 0; 5590 mach_header_addr = data.GetPointer(&offset); 5591 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5592 return mach_header_addr; 5593 } 5594 } 5595 } 5596 } 5597 5598 //---------------------------------------------------------------------- 5599 // Check the dyld_all_image_info structure for a list of mach header 5600 // since it is a very easy thing to check 5601 //---------------------------------------------------------------------- 5602 if (shlib_addr != INVALID_NUB_ADDRESS) 5603 { 5604 bytes_read = DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes); 5605 if (bytes_read > 0) 5606 { 5607 AllImageInfos aii; 5608 offset = 0; 5609 aii.version = data.Get32(&offset); 5610 aii.dylib_info_count = data.Get32(&offset); 5611 if (aii.dylib_info_count > 0) 5612 { 5613 aii.dylib_info_addr = data.GetPointer(&offset); 5614 if (aii.dylib_info_addr != 0) 5615 { 5616 const size_t image_info_byte_size = 3 * addr_size; 5617 for (uint32_t i=0; i<aii.dylib_info_count; ++i) 5618 { 5619 bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + i * image_info_byte_size, image_info_byte_size, bytes); 5620 if (bytes_read != image_info_byte_size) 5621 break; 5622 offset = 0; 5623 mach_header_addr = data.GetPointer(&offset); 5624 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5625 return mach_header_addr; 5626 } 5627 } 5628 } 5629 } 5630 } 5631 5632 //---------------------------------------------------------------------- 5633 // We failed to find the executable's mach header from the all image 5634 // infos and by dereferencing the stack pointer. Now we fall back to 5635 // enumerating the memory regions and looking for regions that are 5636 // executable. 5637 //---------------------------------------------------------------------- 5638 DNBRegionInfo region_info; 5639 mach_header_addr = 0; 5640 while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, ®ion_info)) 5641 { 5642 if (region_info.size == 0) 5643 break; 5644 5645 if (region_info.permissions & eMemoryPermissionsExecutable) 5646 { 5647 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' : '-'); 5648 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5649 return mach_header_addr; 5650 } 5651 else 5652 { 5653 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' : '-'); 5654 } 5655 // Set the address to the next mapped region 5656 mach_header_addr = region_info.addr + region_info.size; 5657 } 5658 bzero (&mh, sizeof(mh)); 5659 return INVALID_NUB_ADDRESS; 5660 } 5661 5662 rnb_err_t 5663 RNBRemote::HandlePacket_qSymbol (const char *command) 5664 { 5665 const char *p = command; 5666 p += strlen ("qSymbol:"); 5667 const char *sep = strchr(p, ':'); 5668 5669 std::string symbol_name; 5670 std::string symbol_value_str; 5671 // Extract the symbol value if there is one 5672 if (sep > p) 5673 symbol_value_str.assign(p, sep - p); 5674 p = sep + 1; 5675 5676 if (*p) 5677 { 5678 // We have a symbol name 5679 symbol_name = std::move(decode_hex_ascii_string(p)); 5680 if (!symbol_value_str.empty()) 5681 { 5682 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5683 if (symbol_name == "dispatch_queue_offsets") 5684 m_dispatch_queue_offsets_addr = symbol_value; 5685 } 5686 ++m_qSymbol_index; 5687 } 5688 else 5689 { 5690 // No symbol name, set our symbol index to zero so we can 5691 // read any symbols that we need 5692 m_qSymbol_index = 0; 5693 } 5694 5695 symbol_name.clear(); 5696 5697 if (m_qSymbol_index == 0) 5698 { 5699 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5700 symbol_name = "dispatch_queue_offsets"; 5701 else 5702 ++m_qSymbol_index; 5703 } 5704 5705 // // Lookup next symbol when we have one... 5706 // if (m_qSymbol_index == 1) 5707 // { 5708 // } 5709 5710 5711 if (symbol_name.empty()) 5712 { 5713 // Done with symbol lookups 5714 return SendPacket ("OK"); 5715 } 5716 else 5717 { 5718 std::ostringstream reply; 5719 reply << "qSymbol:"; 5720 for (size_t i = 0; i < symbol_name.size(); ++i) 5721 reply << RAWHEX8(symbol_name[i]); 5722 return SendPacket (reply.str().c_str()); 5723 } 5724 } 5725 5726 // Note that all numeric values returned by qProcessInfo are hex encoded, 5727 // including the pid and the cpu type. 5728 5729 rnb_err_t 5730 RNBRemote::HandlePacket_qProcessInfo (const char *p) 5731 { 5732 nub_process_t pid; 5733 std::ostringstream rep; 5734 5735 // If we haven't run the process yet, return an error. 5736 if (!m_ctx.HasValidProcessID()) 5737 return SendPacket ("E68"); 5738 5739 pid = m_ctx.ProcessID(); 5740 5741 rep << "pid:" << std::hex << pid << ';'; 5742 5743 int procpid_mib[4]; 5744 procpid_mib[0] = CTL_KERN; 5745 procpid_mib[1] = KERN_PROC; 5746 procpid_mib[2] = KERN_PROC_PID; 5747 procpid_mib[3] = pid; 5748 struct kinfo_proc proc_kinfo; 5749 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 5750 5751 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 5752 { 5753 if (proc_kinfo_size > 0) 5754 { 5755 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';'; 5756 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ';'; 5757 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ';'; 5758 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ';'; 5759 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 5760 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';'; 5761 } 5762 } 5763 5764 cpu_type_t cputype = DNBProcessGetCPUType (pid); 5765 if (cputype == 0) 5766 { 5767 DNBLog ("Unable to get the process cpu_type, making a best guess."); 5768 cputype = best_guess_cpu_type(); 5769 } 5770 5771 uint32_t addr_size = 0; 5772 if (cputype != 0) 5773 { 5774 rep << "cputype:" << std::hex << cputype << ";"; 5775 if (cputype & CPU_ARCH_ABI64) 5776 addr_size = 8; 5777 else 5778 addr_size = 4; 5779 } 5780 5781 bool host_cpu_is_64bit = false; 5782 uint32_t is64bit_capable; 5783 size_t is64bit_capable_len = sizeof (is64bit_capable); 5784 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0) 5785 host_cpu_is_64bit = is64bit_capable != 0; 5786 5787 uint32_t cpusubtype; 5788 size_t cpusubtype_len = sizeof(cpusubtype); 5789 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 5790 { 5791 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 5792 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 5793 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype 5794 // for i386... 5795 if (host_cpu_is_64bit) 5796 { 5797 if (cputype == CPU_TYPE_X86) 5798 { 5799 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 5800 } 5801 else if (cputype == CPU_TYPE_ARM) 5802 { 5803 // We can query a process' cputype but we cannot query a process' cpusubtype. 5804 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we 5805 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace) 5806 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 5807 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S 5808 } 5809 } 5810 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 5811 } 5812 5813 bool os_handled = false; 5814 if (addr_size > 0) 5815 { 5816 rep << "ptrsize:" << std::dec << addr_size << ';'; 5817 5818 #if (defined (__x86_64__) || defined (__i386__)) 5819 // Try and get the OS type by looking at the load commands in the main 5820 // executable and looking for a LC_VERSION_MIN load command. This is the 5821 // most reliable way to determine the "ostype" value when on desktop. 5822 5823 mach_header mh; 5824 nub_addr_t exe_mach_header_addr = GetMachHeaderForMainExecutable (pid, addr_size, mh); 5825 if (exe_mach_header_addr != INVALID_NUB_ADDRESS) 5826 { 5827 uint64_t load_command_addr = exe_mach_header_addr + ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header)); 5828 load_command lc; 5829 for (uint32_t i=0; i<mh.ncmds && !os_handled; ++i) 5830 { 5831 const nub_size_t bytes_read = DNBProcessMemoryRead (pid, load_command_addr, sizeof(lc), &lc); 5832 uint32_t raw_cmd = lc.cmd & ~LC_REQ_DYLD; 5833 if (bytes_read != sizeof(lc)) 5834 break; 5835 switch (raw_cmd) 5836 { 5837 case LC_VERSION_MIN_IPHONEOS: 5838 os_handled = true; 5839 rep << "ostype:ios;"; 5840 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_IPHONEOS -> 'ostype:ios;'"); 5841 break; 5842 5843 case LC_VERSION_MIN_MACOSX: 5844 os_handled = true; 5845 rep << "ostype:macosx;"; 5846 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'"); 5847 break; 5848 5849 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 5850 case LC_VERSION_MIN_TVOS: 5851 os_handled = true; 5852 rep << "ostype:tvos;"; 5853 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_TVOS -> 'ostype:tvos;'"); 5854 break; 5855 #endif 5856 5857 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 5858 case LC_VERSION_MIN_WATCHOS: 5859 os_handled = true; 5860 rep << "ostype:watchos;"; 5861 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_WATCHOS -> 'ostype:watchos;'"); 5862 break; 5863 #endif 5864 5865 default: 5866 break; 5867 } 5868 load_command_addr = load_command_addr + lc.cmdsize; 5869 } 5870 } 5871 #endif 5872 } 5873 5874 // If we weren't able to find the OS in a LC_VERSION_MIN load command, try 5875 // to set it correctly by using the cpu type and other tricks 5876 if (!os_handled) 5877 { 5878 // The OS in the triple should be "ios" or "macosx" which doesn't match our 5879 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 5880 // this for now. 5881 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 5882 { 5883 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 5884 rep << "ostype:tvos;"; 5885 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 5886 rep << "ostype:watchos;"; 5887 #else 5888 rep << "ostype:ios;"; 5889 #endif 5890 } 5891 else 5892 { 5893 bool is_ios_simulator = false; 5894 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) 5895 { 5896 // Check for iOS simulator binaries by getting the process argument 5897 // and environment and checking for SIMULATOR_UDID in the environment 5898 int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid }; 5899 5900 uint8_t arg_data[8192]; 5901 size_t arg_data_size = sizeof(arg_data); 5902 if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) 5903 { 5904 DNBDataRef data (arg_data, arg_data_size, false); 5905 DNBDataRef::offset_t offset = 0; 5906 uint32_t argc = data.Get32 (&offset); 5907 const char *cstr; 5908 5909 cstr = data.GetCStr (&offset); 5910 if (cstr) 5911 { 5912 // Skip NULLs 5913 while (1) 5914 { 5915 const char *p = data.PeekCStr(offset); 5916 if ((p == NULL) || (*p != '\0')) 5917 break; 5918 ++offset; 5919 } 5920 // Now skip all arguments 5921 for (uint32_t i = 0; i < argc; ++i) 5922 { 5923 data.GetCStr(&offset); 5924 } 5925 5926 // Now iterate across all environment variables 5927 while ((cstr = data.GetCStr(&offset))) 5928 { 5929 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) 5930 { 5931 is_ios_simulator = true; 5932 break; 5933 } 5934 if (cstr[0] == '\0') 5935 break; 5936 5937 } 5938 } 5939 } 5940 } 5941 if (is_ios_simulator) 5942 { 5943 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 5944 rep << "ostype:tvos;"; 5945 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 5946 rep << "ostype:watchos;"; 5947 #else 5948 rep << "ostype:ios;"; 5949 #endif 5950 } 5951 else 5952 { 5953 rep << "ostype:macosx;"; 5954 } 5955 } 5956 } 5957 5958 rep << "vendor:apple;"; 5959 5960 #if defined (__LITTLE_ENDIAN__) 5961 rep << "endian:little;"; 5962 #elif defined (__BIG_ENDIAN__) 5963 rep << "endian:big;"; 5964 #elif defined (__PDP_ENDIAN__) 5965 rep << "endian:pdp;"; 5966 #endif 5967 5968 if (addr_size == 0) 5969 { 5970 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 5971 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5972 kern_return_t kr; 5973 x86_thread_state_t gp_regs; 5974 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 5975 kr = thread_get_state (static_cast<thread_act_t>(thread), 5976 x86_THREAD_STATE, 5977 (thread_state_t) &gp_regs, 5978 &gp_count); 5979 if (kr == KERN_SUCCESS) 5980 { 5981 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 5982 rep << "ptrsize:8;"; 5983 else 5984 rep << "ptrsize:4;"; 5985 } 5986 #elif defined (__arm__) 5987 rep << "ptrsize:4;"; 5988 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE) 5989 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5990 kern_return_t kr; 5991 arm_unified_thread_state_t gp_regs; 5992 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 5993 kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE, 5994 (thread_state_t) &gp_regs, &gp_count); 5995 if (kr == KERN_SUCCESS) 5996 { 5997 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 5998 rep << "ptrsize:8;"; 5999 else 6000 rep << "ptrsize:4;"; 6001 } 6002 #endif 6003 } 6004 6005 return SendPacket (rep.str()); 6006 } 6007 6008 const RNBRemote::DispatchQueueOffsets * 6009 RNBRemote::GetDispatchQueueOffsets() 6010 { 6011 if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID()) 6012 { 6013 nub_process_t pid = m_ctx.ProcessID(); 6014 nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets); 6015 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 6016 m_dispatch_queue_offsets.Clear(); 6017 } 6018 6019 if (m_dispatch_queue_offsets.IsValid()) 6020 return &m_dispatch_queue_offsets; 6021 else 6022 return nullptr; 6023 } 6024 6025 void 6026 RNBRemote::EnableCompressionNextSendPacket (compression_types type) 6027 { 6028 m_compression_mode = type; 6029 m_enable_compression_next_send_packet = true; 6030 } 6031 6032 compression_types 6033 RNBRemote::GetCompressionType () 6034 { 6035 // The first packet we send back to the debugger after a QEnableCompression request 6036 // should be uncompressed -- so we can indicate whether the compression was enabled 6037 // or not via OK / Enn returns. After that, all packets sent will be using the 6038 // compression protocol. 6039 6040 if (m_enable_compression_next_send_packet) 6041 { 6042 // One time, we send back "None" as our compression type 6043 m_enable_compression_next_send_packet = false; 6044 return compression_types::none; 6045 } 6046 return m_compression_mode; 6047 } 6048