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 case rnb_err: 1030 DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err); 1031 done = true; 1032 break; 1033 1034 case rnb_not_connected: 1035 DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned not connected..."); 1036 done = true; 1037 break; 1038 } 1039 } 1040 // START: main receive remote command thread loop 1041 events.ResetEvents (RNBContext::event_read_thread_running); 1042 events.SetEvents (RNBContext::event_read_thread_exiting); 1043 } 1044 DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...", __FUNCTION__, arg); 1045 return NULL; 1046 } 1047 1048 1049 // If we fail to get back a valid CPU type for the remote process, 1050 // make a best guess for the CPU type based on the currently running 1051 // debugserver binary -- the debugger may not handle the case of an 1052 // un-specified process CPU type correctly. 1053 1054 static cpu_type_t 1055 best_guess_cpu_type () 1056 { 1057 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__) 1058 if (sizeof (char *) == 8) 1059 { 1060 return CPU_TYPE_ARM64; 1061 } 1062 else 1063 { 1064 return CPU_TYPE_ARM; 1065 } 1066 #elif defined (__i386__) || defined (__x86_64__) 1067 if (sizeof (char*) == 8) 1068 { 1069 return CPU_TYPE_X86_64; 1070 } 1071 else 1072 { 1073 return CPU_TYPE_I386; 1074 } 1075 #endif 1076 return 0; 1077 } 1078 1079 1080 /* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes 1081 (8-bit bytes). 1082 This encoding uses 0x7d ('}') as an escape character for 1083 0x7d ('}'), 0x23 ('#'), 0x24 ('$'), 0x2a ('*'). 1084 LEN is the number of bytes to be processed. If a character is escaped, 1085 it is 2 characters for LEN. A LEN of -1 means decode-until-nul-byte 1086 (end of string). */ 1087 1088 std::vector<uint8_t> 1089 decode_binary_data (const char *str, size_t len) 1090 { 1091 std::vector<uint8_t> bytes; 1092 if (len == 0) 1093 { 1094 return bytes; 1095 } 1096 if (len == (size_t)-1) 1097 len = strlen (str); 1098 1099 while (len--) 1100 { 1101 unsigned char c = *str; 1102 if (c == 0x7d && len > 0) 1103 { 1104 len--; 1105 str++; 1106 c = *str ^ 0x20; 1107 } 1108 bytes.push_back (c); 1109 } 1110 return bytes; 1111 } 1112 1113 // Quote any meta characters in a std::string as per the binary 1114 // packet convention in the gdb-remote protocol. 1115 1116 std::string 1117 binary_encode_string (const std::string &s) 1118 { 1119 std::string output; 1120 const size_t s_size = s.size(); 1121 const char *s_chars = s.c_str(); 1122 1123 for (size_t i = 0; i < s_size; i++) 1124 { 1125 unsigned char ch = *(s_chars + i); 1126 if (ch == '#' || ch == '$' || ch == '}' || ch == '*') 1127 { 1128 output.push_back ('}'); // 0x7d 1129 output.push_back (ch ^ 0x20); 1130 } 1131 else 1132 { 1133 output.push_back (ch); 1134 } 1135 } 1136 return output; 1137 } 1138 1139 // If the value side of a key-value pair in JSON is a string, 1140 // and that string has a " character in it, the " character must 1141 // be escaped. 1142 1143 std::string 1144 json_string_quote_metachars (const std::string &s) 1145 { 1146 if (s.find('"') == std::string::npos) 1147 return s; 1148 1149 std::string output; 1150 const size_t s_size = s.size(); 1151 const char *s_chars = s.c_str(); 1152 for (size_t i = 0; i < s_size; i++) 1153 { 1154 unsigned char ch = *(s_chars + i); 1155 if (ch == '"') 1156 { 1157 output.push_back ('\\'); 1158 } 1159 output.push_back (ch); 1160 } 1161 return output; 1162 } 1163 1164 typedef struct register_map_entry 1165 { 1166 uint32_t debugserver_regnum; // debugserver register number 1167 uint32_t offset; // Offset in bytes into the register context data with no padding between register values 1168 DNBRegisterInfo nub_info; // debugnub register info 1169 std::vector<uint32_t> value_regnums; 1170 std::vector<uint32_t> invalidate_regnums; 1171 } register_map_entry_t; 1172 1173 1174 1175 // If the notion of registers differs from what is handed out by the 1176 // architecture, then flavors can be defined here. 1177 1178 static std::vector<register_map_entry_t> g_dynamic_register_map; 1179 static register_map_entry_t *g_reg_entries = NULL; 1180 static size_t g_num_reg_entries = 0; 1181 1182 void 1183 RNBRemote::Initialize() 1184 { 1185 DNBInitialize(); 1186 } 1187 1188 1189 bool 1190 RNBRemote::InitializeRegisters (bool force) 1191 { 1192 pid_t pid = m_ctx.ProcessID(); 1193 if (pid == INVALID_NUB_PROCESS) 1194 return false; 1195 1196 DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface", __FUNCTION__); 1197 // Discover the registers by querying the DNB interface and letting it 1198 // state the registers that it would like to export. This allows the 1199 // registers to be discovered using multiple qRegisterInfo calls to get 1200 // all register information after the architecture for the process is 1201 // determined. 1202 if (force) 1203 { 1204 g_dynamic_register_map.clear(); 1205 g_reg_entries = NULL; 1206 g_num_reg_entries = 0; 1207 } 1208 1209 if (g_dynamic_register_map.empty()) 1210 { 1211 nub_size_t num_reg_sets = 0; 1212 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets); 1213 1214 assert (num_reg_sets > 0 && reg_sets != NULL); 1215 1216 uint32_t regnum = 0; 1217 uint32_t reg_data_offset = 0; 1218 typedef std::map<std::string, uint32_t> NameToRegNum; 1219 NameToRegNum name_to_regnum; 1220 for (nub_size_t set = 0; set < num_reg_sets; ++set) 1221 { 1222 if (reg_sets[set].registers == NULL) 1223 continue; 1224 1225 for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg) 1226 { 1227 register_map_entry_t reg_entry = { 1228 regnum++, // register number starts at zero and goes up with no gaps 1229 reg_data_offset, // Offset into register context data, no gaps between registers 1230 reg_sets[set].registers[reg], // DNBRegisterInfo 1231 {}, 1232 {}, 1233 }; 1234 1235 name_to_regnum[reg_entry.nub_info.name] = reg_entry.debugserver_regnum; 1236 1237 if (reg_entry.nub_info.value_regs == NULL) 1238 { 1239 reg_data_offset += reg_entry.nub_info.size; 1240 } 1241 1242 g_dynamic_register_map.push_back (reg_entry); 1243 } 1244 } 1245 1246 // Now we must find any registers whose values are in other registers and fix up 1247 // the offsets since we removed all gaps... 1248 for (auto ®_entry: g_dynamic_register_map) 1249 { 1250 if (reg_entry.nub_info.value_regs) 1251 { 1252 uint32_t new_offset = UINT32_MAX; 1253 for (size_t i=0; reg_entry.nub_info.value_regs[i] != NULL; ++i) 1254 { 1255 const char *name = reg_entry.nub_info.value_regs[i]; 1256 auto pos = name_to_regnum.find(name); 1257 if (pos != name_to_regnum.end()) 1258 { 1259 regnum = pos->second; 1260 reg_entry.value_regnums.push_back(regnum); 1261 if (regnum < g_dynamic_register_map.size()) 1262 { 1263 // The offset for value_regs registers is the offset within the register with the lowest offset 1264 const uint32_t reg_offset = g_dynamic_register_map[regnum].offset + reg_entry.nub_info.offset; 1265 if (new_offset > reg_offset) 1266 new_offset = reg_offset; 1267 } 1268 } 1269 } 1270 1271 if (new_offset != UINT32_MAX) 1272 { 1273 reg_entry.offset = new_offset; 1274 } 1275 else 1276 { 1277 DNBLogThreaded("no offset was calculated entry for register %s", reg_entry.nub_info.name); 1278 reg_entry.offset = UINT32_MAX; 1279 } 1280 } 1281 1282 if (reg_entry.nub_info.update_regs) 1283 { 1284 for (size_t i=0; reg_entry.nub_info.update_regs[i] != NULL; ++i) 1285 { 1286 const char *name = reg_entry.nub_info.update_regs[i]; 1287 auto pos = name_to_regnum.find(name); 1288 if (pos != name_to_regnum.end()) 1289 { 1290 regnum = pos->second; 1291 reg_entry.invalidate_regnums.push_back(regnum); 1292 } 1293 } 1294 } 1295 } 1296 1297 1298 // for (auto ®_entry: g_dynamic_register_map) 1299 // { 1300 // DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s", 1301 // reg_entry.offset, 1302 // reg_entry.nub_info.size, 1303 // reg_entry.nub_info.value_regs != NULL, 1304 // reg_entry.nub_info.name); 1305 // } 1306 1307 g_reg_entries = g_dynamic_register_map.data(); 1308 g_num_reg_entries = g_dynamic_register_map.size(); 1309 } 1310 return true; 1311 } 1312 1313 /* The inferior has stopped executing; send a packet 1314 to gdb to let it know. */ 1315 1316 void 1317 RNBRemote::NotifyThatProcessStopped (void) 1318 { 1319 RNBRemote::HandlePacket_last_signal (NULL); 1320 return; 1321 } 1322 1323 1324 /* 'A arglen,argnum,arg,...' 1325 Update the inferior context CTX with the program name and arg 1326 list. 1327 The documentation for this packet is underwhelming but my best reading 1328 of this is that it is a series of (len, position #, arg)'s, one for 1329 each argument with "arg" hex encoded (two 0-9a-f chars?). 1330 Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either 1331 is sufficient to get around the "," position separator escape issue. 1332 1333 e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is 1334 1335 6,0,676462,4,1,2d71,10,2,612e6f7574 1336 1337 Note that "argnum" and "arglen" are numbers in base 10. Again, that's 1338 not documented either way but I'm assuming it's so. */ 1339 1340 rnb_err_t 1341 RNBRemote::HandlePacket_A (const char *p) 1342 { 1343 if (p == NULL || *p == '\0') 1344 { 1345 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Null packet for 'A' pkt"); 1346 } 1347 p++; 1348 if (*p == '\0' || !isdigit (*p)) 1349 { 1350 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not specified on 'A' pkt"); 1351 } 1352 1353 /* I promise I don't modify it anywhere in this function. strtoul()'s 1354 2nd arg has to be non-const which makes it problematic to step 1355 through the string easily. */ 1356 char *buf = const_cast<char *>(p); 1357 1358 RNBContext& ctx = Context(); 1359 1360 while (*buf != '\0') 1361 { 1362 unsigned long arglen, argnum; 1363 std::string arg; 1364 char *c; 1365 1366 errno = 0; 1367 arglen = strtoul (buf, &c, 10); 1368 if (errno != 0 && arglen == 0) 1369 { 1370 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not a number on 'A' pkt"); 1371 } 1372 if (*c != ',') 1373 { 1374 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt"); 1375 } 1376 buf = c + 1; 1377 1378 errno = 0; 1379 argnum = strtoul (buf, &c, 10); 1380 if (errno != 0 && argnum == 0) 1381 { 1382 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "argnum not a number on 'A' pkt"); 1383 } 1384 if (*c != ',') 1385 { 1386 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt"); 1387 } 1388 buf = c + 1; 1389 1390 c = buf; 1391 buf = buf + arglen; 1392 while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0') 1393 { 1394 char smallbuf[3]; 1395 smallbuf[0] = *c; 1396 smallbuf[1] = *(c + 1); 1397 smallbuf[2] = '\0'; 1398 1399 errno = 0; 1400 int ch = static_cast<int>(strtoul (smallbuf, NULL, 16)); 1401 if (errno != 0 && ch == 0) 1402 { 1403 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'A' pkt"); 1404 } 1405 1406 arg.push_back(ch); 1407 c += 2; 1408 } 1409 1410 ctx.PushArgument (arg.c_str()); 1411 if (*buf == ',') 1412 buf++; 1413 } 1414 SendPacket ("OK"); 1415 1416 return rnb_success; 1417 } 1418 1419 /* 'H c t' 1420 Set the thread for subsequent actions; 'c' for step/continue ops, 1421 'g' for other ops. -1 means all threads, 0 means any thread. */ 1422 1423 rnb_err_t 1424 RNBRemote::HandlePacket_H (const char *p) 1425 { 1426 p++; // skip 'H' 1427 if (*p != 'c' && *p != 'g') 1428 { 1429 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing 'c' or 'g' type in H packet"); 1430 } 1431 1432 if (!m_ctx.HasValidProcessID()) 1433 { 1434 // We allow gdb to connect to a server that hasn't started running 1435 // the target yet. gdb still wants to ask questions about it and 1436 // freaks out if it gets an error. So just return OK here. 1437 } 1438 1439 errno = 0; 1440 nub_thread_t tid = strtoul (p + 1, NULL, 16); 1441 if (errno != 0 && tid == 0) 1442 { 1443 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in H packet"); 1444 } 1445 if (*p == 'c') 1446 SetContinueThread (tid); 1447 if (*p == 'g') 1448 SetCurrentThread (tid); 1449 1450 return SendPacket ("OK"); 1451 } 1452 1453 1454 rnb_err_t 1455 RNBRemote::HandlePacket_qLaunchSuccess (const char *p) 1456 { 1457 if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Error() == 0) 1458 return SendPacket("OK"); 1459 std::ostringstream ret_str; 1460 std::string status_str; 1461 ret_str << "E" << m_ctx.LaunchStatusAsString(status_str); 1462 1463 return SendPacket (ret_str.str()); 1464 } 1465 1466 rnb_err_t 1467 RNBRemote::HandlePacket_qShlibInfoAddr (const char *p) 1468 { 1469 if (m_ctx.HasValidProcessID()) 1470 { 1471 nub_addr_t shlib_info_addr = DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID()); 1472 if (shlib_info_addr != INVALID_NUB_ADDRESS) 1473 { 1474 std::ostringstream ostrm; 1475 ostrm << RAW_HEXBASE << shlib_info_addr; 1476 return SendPacket (ostrm.str ()); 1477 } 1478 } 1479 return SendPacket ("E44"); 1480 } 1481 1482 rnb_err_t 1483 RNBRemote::HandlePacket_qStepPacketSupported (const char *p) 1484 { 1485 // Normally the "s" packet is mandatory, yet in gdb when using ARM, they 1486 // get around the need for this packet by implementing software single 1487 // stepping from gdb. Current versions of debugserver do support the "s" 1488 // packet, yet some older versions do not. We need a way to tell if this 1489 // packet is supported so we can disable software single stepping in gdb 1490 // for remote targets (so the "s" packet will get used). 1491 return SendPacket("OK"); 1492 } 1493 1494 rnb_err_t 1495 RNBRemote::HandlePacket_qSyncThreadStateSupported (const char *p) 1496 { 1497 // We support attachOrWait meaning attach if the process exists, otherwise wait to attach. 1498 return SendPacket("OK"); 1499 } 1500 1501 rnb_err_t 1502 RNBRemote::HandlePacket_qVAttachOrWaitSupported (const char *p) 1503 { 1504 // We support attachOrWait meaning attach if the process exists, otherwise wait to attach. 1505 return SendPacket("OK"); 1506 } 1507 1508 rnb_err_t 1509 RNBRemote::HandlePacket_qThreadStopInfo (const char *p) 1510 { 1511 p += strlen ("qThreadStopInfo"); 1512 nub_thread_t tid = strtoul(p, 0, 16); 1513 return SendStopReplyPacketForThread (tid); 1514 } 1515 1516 rnb_err_t 1517 RNBRemote::HandlePacket_qThreadInfo (const char *p) 1518 { 1519 // We allow gdb to connect to a server that hasn't started running 1520 // the target yet. gdb still wants to ask questions about it and 1521 // freaks out if it gets an error. So just return OK here. 1522 nub_process_t pid = m_ctx.ProcessID(); 1523 if (pid == INVALID_NUB_PROCESS) 1524 return SendPacket ("OK"); 1525 1526 // Only "qfThreadInfo" and "qsThreadInfo" get into this function so 1527 // we only need to check the second byte to tell which is which 1528 if (p[1] == 'f') 1529 { 1530 nub_size_t numthreads = DNBProcessGetNumThreads (pid); 1531 std::ostringstream ostrm; 1532 ostrm << "m"; 1533 bool first = true; 1534 for (nub_size_t i = 0; i < numthreads; ++i) 1535 { 1536 if (first) 1537 first = false; 1538 else 1539 ostrm << ","; 1540 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 1541 ostrm << std::hex << th; 1542 } 1543 return SendPacket (ostrm.str ()); 1544 } 1545 else 1546 { 1547 return SendPacket ("l"); 1548 } 1549 } 1550 1551 rnb_err_t 1552 RNBRemote::HandlePacket_qThreadExtraInfo (const char *p) 1553 { 1554 // We allow gdb to connect to a server that hasn't started running 1555 // the target yet. gdb still wants to ask questions about it and 1556 // freaks out if it gets an error. So just return OK here. 1557 nub_process_t pid = m_ctx.ProcessID(); 1558 if (pid == INVALID_NUB_PROCESS) 1559 return SendPacket ("OK"); 1560 1561 /* This is supposed to return a string like 'Runnable' or 1562 'Blocked on Mutex'. 1563 The returned string is formatted like the "A" packet - a 1564 sequence of letters encoded in as 2-hex-chars-per-letter. */ 1565 p += strlen ("qThreadExtraInfo"); 1566 if (*p++ != ',') 1567 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Illformed qThreadExtraInfo packet"); 1568 errno = 0; 1569 nub_thread_t tid = strtoul (p, NULL, 16); 1570 if (errno != 0 && tid == 0) 1571 { 1572 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in qThreadExtraInfo packet"); 1573 } 1574 1575 const char * threadInfo = DNBThreadGetInfo(pid, tid); 1576 if (threadInfo != NULL && threadInfo[0]) 1577 { 1578 return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL); 1579 } 1580 else 1581 { 1582 // "OK" == 4f6b 1583 // Return "OK" as a ASCII hex byte stream if things go wrong 1584 return SendPacket ("4f6b"); 1585 } 1586 1587 return SendPacket (""); 1588 } 1589 1590 1591 const char *k_space_delimiters = " \t"; 1592 static void 1593 skip_spaces (std::string &line) 1594 { 1595 if (!line.empty()) 1596 { 1597 size_t space_pos = line.find_first_not_of (k_space_delimiters); 1598 if (space_pos > 0) 1599 line.erase(0, space_pos); 1600 } 1601 } 1602 1603 static std::string 1604 get_identifier (std::string &line) 1605 { 1606 std::string word; 1607 skip_spaces (line); 1608 const size_t line_size = line.size(); 1609 size_t end_pos; 1610 for (end_pos = 0; end_pos < line_size; ++end_pos) 1611 { 1612 if (end_pos == 0) 1613 { 1614 if (isalpha(line[end_pos]) || line[end_pos] == '_') 1615 continue; 1616 } 1617 else if (isalnum(line[end_pos]) || line[end_pos] == '_') 1618 continue; 1619 break; 1620 } 1621 word.assign (line, 0, end_pos); 1622 line.erase(0, end_pos); 1623 return word; 1624 } 1625 1626 static std::string 1627 get_operator (std::string &line) 1628 { 1629 std::string op; 1630 skip_spaces (line); 1631 if (!line.empty()) 1632 { 1633 if (line[0] == '=') 1634 { 1635 op = '='; 1636 line.erase(0,1); 1637 } 1638 } 1639 return op; 1640 } 1641 1642 static std::string 1643 get_value (std::string &line) 1644 { 1645 std::string value; 1646 skip_spaces (line); 1647 if (!line.empty()) 1648 { 1649 value.swap(line); 1650 } 1651 return value; 1652 } 1653 1654 extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 1655 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 1656 1657 rnb_err_t 1658 RNBRemote::HandlePacket_qRcmd (const char *p) 1659 { 1660 const char *c = p + strlen("qRcmd,"); 1661 std::string line; 1662 while (c[0] && c[1]) 1663 { 1664 char smallbuf[3] = { c[0], c[1], '\0' }; 1665 errno = 0; 1666 int ch = static_cast<int>(strtoul (smallbuf, NULL, 16)); 1667 if (errno != 0 && ch == 0) 1668 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet"); 1669 line.push_back(ch); 1670 c += 2; 1671 } 1672 if (*c == '\0') 1673 { 1674 std::string command = get_identifier(line); 1675 if (command.compare("set") == 0) 1676 { 1677 std::string variable = get_identifier (line); 1678 std::string op = get_operator (line); 1679 std::string value = get_value (line); 1680 if (variable.compare("logfile") == 0) 1681 { 1682 FILE *log_file = fopen(value.c_str(), "w"); 1683 if (log_file) 1684 { 1685 DNBLogSetLogCallback(FileLogCallback, log_file); 1686 return SendPacket ("OK"); 1687 } 1688 return SendPacket ("E71"); 1689 } 1690 else if (variable.compare("logmask") == 0) 1691 { 1692 char *end; 1693 errno = 0; 1694 uint32_t logmask = static_cast<uint32_t>(strtoul (value.c_str(), &end, 0)); 1695 if (errno == 0 && end && *end == '\0') 1696 { 1697 DNBLogSetLogMask (logmask); 1698 if (!DNBLogGetLogCallback()) 1699 DNBLogSetLogCallback(ASLLogCallback, NULL); 1700 return SendPacket ("OK"); 1701 } 1702 errno = 0; 1703 logmask = static_cast<uint32_t>(strtoul (value.c_str(), &end, 16)); 1704 if (errno == 0 && end && *end == '\0') 1705 { 1706 DNBLogSetLogMask (logmask); 1707 return SendPacket ("OK"); 1708 } 1709 return SendPacket ("E72"); 1710 } 1711 return SendPacket ("E70"); 1712 } 1713 return SendPacket ("E69"); 1714 } 1715 return SendPacket ("E73"); 1716 } 1717 1718 rnb_err_t 1719 RNBRemote::HandlePacket_qC (const char *p) 1720 { 1721 nub_thread_t tid; 1722 std::ostringstream rep; 1723 // If we haven't run the process yet, we tell the debugger the 1724 // pid is 0. That way it can know to tell use to run later on. 1725 if (!m_ctx.HasValidProcessID()) 1726 tid = 0; 1727 else 1728 { 1729 // Grab the current thread. 1730 tid = DNBProcessGetCurrentThread (m_ctx.ProcessID()); 1731 // Make sure we set the current thread so g and p packets return 1732 // the data the gdb will expect. 1733 SetCurrentThread (tid); 1734 } 1735 rep << "QC" << std::hex << tid; 1736 return SendPacket (rep.str()); 1737 } 1738 1739 rnb_err_t 1740 RNBRemote::HandlePacket_qEcho (const char *p) 1741 { 1742 // Just send the exact same packet back that we received to 1743 // synchronize the response packets after a previous packet 1744 // timed out. This allows the debugger to get back on track 1745 // with responses after a packet timeout. 1746 return SendPacket (p); 1747 } 1748 1749 rnb_err_t 1750 RNBRemote::HandlePacket_qGetPid (const char *p) 1751 { 1752 nub_process_t pid; 1753 std::ostringstream rep; 1754 // If we haven't run the process yet, we tell the debugger the 1755 // pid is 0. That way it can know to tell use to run later on. 1756 if (m_ctx.HasValidProcessID()) 1757 pid = m_ctx.ProcessID(); 1758 else 1759 pid = 0; 1760 rep << std::hex << pid; 1761 return SendPacket (rep.str()); 1762 } 1763 1764 rnb_err_t 1765 RNBRemote::HandlePacket_qRegisterInfo (const char *p) 1766 { 1767 if (g_num_reg_entries == 0) 1768 InitializeRegisters (); 1769 1770 p += strlen ("qRegisterInfo"); 1771 1772 nub_size_t num_reg_sets = 0; 1773 const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets); 1774 uint32_t reg_num = static_cast<uint32_t>(strtoul(p, 0, 16)); 1775 1776 if (reg_num < g_num_reg_entries) 1777 { 1778 const register_map_entry_t *reg_entry = &g_reg_entries[reg_num]; 1779 std::ostringstream ostrm; 1780 if (reg_entry->nub_info.name) 1781 ostrm << "name:" << reg_entry->nub_info.name << ';'; 1782 if (reg_entry->nub_info.alt) 1783 ostrm << "alt-name:" << reg_entry->nub_info.alt << ';'; 1784 1785 ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';'; 1786 ostrm << "offset:" << std::dec << reg_entry->offset << ';'; 1787 1788 switch (reg_entry->nub_info.type) 1789 { 1790 case Uint: ostrm << "encoding:uint;"; break; 1791 case Sint: ostrm << "encoding:sint;"; break; 1792 case IEEE754: ostrm << "encoding:ieee754;"; break; 1793 case Vector: ostrm << "encoding:vector;"; break; 1794 } 1795 1796 switch (reg_entry->nub_info.format) 1797 { 1798 case Binary: ostrm << "format:binary;"; break; 1799 case Decimal: ostrm << "format:decimal;"; break; 1800 case Hex: ostrm << "format:hex;"; break; 1801 case Float: ostrm << "format:float;"; break; 1802 case VectorOfSInt8: ostrm << "format:vector-sint8;"; break; 1803 case VectorOfUInt8: ostrm << "format:vector-uint8;"; break; 1804 case VectorOfSInt16: ostrm << "format:vector-sint16;"; break; 1805 case VectorOfUInt16: ostrm << "format:vector-uint16;"; break; 1806 case VectorOfSInt32: ostrm << "format:vector-sint32;"; break; 1807 case VectorOfUInt32: ostrm << "format:vector-uint32;"; break; 1808 case VectorOfFloat32: ostrm << "format:vector-float32;"; break; 1809 case VectorOfUInt128: ostrm << "format:vector-uint128;"; break; 1810 }; 1811 1812 if (reg_set_info && reg_entry->nub_info.set < num_reg_sets) 1813 ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';'; 1814 1815 if (reg_entry->nub_info.reg_ehframe != INVALID_NUB_REGNUM) 1816 ostrm << "ehframe:" << std::dec << reg_entry->nub_info.reg_ehframe << ';'; 1817 1818 if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM) 1819 ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';'; 1820 1821 switch (reg_entry->nub_info.reg_generic) 1822 { 1823 case GENERIC_REGNUM_FP: ostrm << "generic:fp;"; break; 1824 case GENERIC_REGNUM_PC: ostrm << "generic:pc;"; break; 1825 case GENERIC_REGNUM_SP: ostrm << "generic:sp;"; break; 1826 case GENERIC_REGNUM_RA: ostrm << "generic:ra;"; break; 1827 case GENERIC_REGNUM_FLAGS: ostrm << "generic:flags;"; break; 1828 case GENERIC_REGNUM_ARG1: ostrm << "generic:arg1;"; break; 1829 case GENERIC_REGNUM_ARG2: ostrm << "generic:arg2;"; break; 1830 case GENERIC_REGNUM_ARG3: ostrm << "generic:arg3;"; break; 1831 case GENERIC_REGNUM_ARG4: ostrm << "generic:arg4;"; break; 1832 case GENERIC_REGNUM_ARG5: ostrm << "generic:arg5;"; break; 1833 case GENERIC_REGNUM_ARG6: ostrm << "generic:arg6;"; break; 1834 case GENERIC_REGNUM_ARG7: ostrm << "generic:arg7;"; break; 1835 case GENERIC_REGNUM_ARG8: ostrm << "generic:arg8;"; break; 1836 default: break; 1837 } 1838 1839 if (!reg_entry->value_regnums.empty()) 1840 { 1841 ostrm << "container-regs:"; 1842 for (size_t i=0, n=reg_entry->value_regnums.size(); i < n; ++i) 1843 { 1844 if (i > 0) 1845 ostrm << ','; 1846 ostrm << RAW_HEXBASE << reg_entry->value_regnums[i]; 1847 } 1848 ostrm << ';'; 1849 } 1850 1851 if (!reg_entry->invalidate_regnums.empty()) 1852 { 1853 ostrm << "invalidate-regs:"; 1854 for (size_t i=0, n=reg_entry->invalidate_regnums.size(); i < n; ++i) 1855 { 1856 if (i > 0) 1857 ostrm << ','; 1858 ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i]; 1859 } 1860 ostrm << ';'; 1861 } 1862 1863 return SendPacket (ostrm.str ()); 1864 } 1865 return SendPacket ("E45"); 1866 } 1867 1868 1869 /* This expects a packet formatted like 1870 1871 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE; 1872 1873 with the "QSetLogging:" already removed from the start. Maybe in the 1874 future this packet will include other keyvalue pairs like 1875 1876 QSetLogging:bitmask=LOG_ALL;mode=asl; 1877 */ 1878 1879 rnb_err_t 1880 set_logging (const char *p) 1881 { 1882 int bitmask = 0; 1883 while (p && *p != '\0') 1884 { 1885 if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0) 1886 { 1887 p += sizeof ("bitmask=") - 1; 1888 while (p && *p != '\0' && *p != ';') 1889 { 1890 if (*p == '|') 1891 p++; 1892 1893 // to regenerate the LOG_ entries (not including the LOG_RNB entries) 1894 // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'` 1895 // do 1896 // echo " else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)" 1897 // echo " {" 1898 // echo " p += sizeof (\"$logname\") - 1;" 1899 // echo " bitmask |= $logname;" 1900 // echo " }" 1901 // done 1902 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0) 1903 { 1904 p += sizeof ("LOG_VERBOSE") - 1; 1905 bitmask |= LOG_VERBOSE; 1906 } 1907 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0) 1908 { 1909 p += sizeof ("LOG_PROCESS") - 1; 1910 bitmask |= LOG_PROCESS; 1911 } 1912 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0) 1913 { 1914 p += sizeof ("LOG_THREAD") - 1; 1915 bitmask |= LOG_THREAD; 1916 } 1917 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0) 1918 { 1919 p += sizeof ("LOG_EXCEPTIONS") - 1; 1920 bitmask |= LOG_EXCEPTIONS; 1921 } 1922 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0) 1923 { 1924 p += sizeof ("LOG_SHLIB") - 1; 1925 bitmask |= LOG_SHLIB; 1926 } 1927 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0) 1928 { 1929 p += sizeof ("LOG_MEMORY") - 1; 1930 bitmask |= LOG_MEMORY; 1931 } 1932 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0) 1933 { 1934 p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1; 1935 bitmask |= LOG_MEMORY_DATA_SHORT; 1936 } 1937 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0) 1938 { 1939 p += sizeof ("LOG_MEMORY_DATA_LONG") - 1; 1940 bitmask |= LOG_MEMORY_DATA_LONG; 1941 } 1942 else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0) 1943 { 1944 p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1; 1945 bitmask |= LOG_MEMORY_PROTECTIONS; 1946 } 1947 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0) 1948 { 1949 p += sizeof ("LOG_BREAKPOINTS") - 1; 1950 bitmask |= LOG_BREAKPOINTS; 1951 } 1952 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0) 1953 { 1954 p += sizeof ("LOG_EVENTS") - 1; 1955 bitmask |= LOG_EVENTS; 1956 } 1957 else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0) 1958 { 1959 p += sizeof ("LOG_WATCHPOINTS") - 1; 1960 bitmask |= LOG_WATCHPOINTS; 1961 } 1962 else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0) 1963 { 1964 p += sizeof ("LOG_STEP") - 1; 1965 bitmask |= LOG_STEP; 1966 } 1967 else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0) 1968 { 1969 p += sizeof ("LOG_TASK") - 1; 1970 bitmask |= LOG_TASK; 1971 } 1972 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0) 1973 { 1974 p += sizeof ("LOG_ALL") - 1; 1975 bitmask |= LOG_ALL; 1976 } 1977 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0) 1978 { 1979 p += sizeof ("LOG_DEFAULT") - 1; 1980 bitmask |= LOG_DEFAULT; 1981 } 1982 // end of auto-generated entries 1983 1984 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0) 1985 { 1986 p += sizeof ("LOG_NONE") - 1; 1987 bitmask = 0; 1988 } 1989 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0) 1990 { 1991 p += sizeof ("LOG_RNB_MINIMAL") - 1; 1992 bitmask |= LOG_RNB_MINIMAL; 1993 } 1994 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0) 1995 { 1996 p += sizeof ("LOG_RNB_MEDIUM") - 1; 1997 bitmask |= LOG_RNB_MEDIUM; 1998 } 1999 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0) 2000 { 2001 p += sizeof ("LOG_RNB_MAX") - 1; 2002 bitmask |= LOG_RNB_MAX; 2003 } 2004 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0) 2005 { 2006 p += sizeof ("LOG_RNB_COMM") - 1; 2007 bitmask |= LOG_RNB_COMM; 2008 } 2009 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0) 2010 { 2011 p += sizeof ("LOG_RNB_REMOTE") - 1; 2012 bitmask |= LOG_RNB_REMOTE; 2013 } 2014 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0) 2015 { 2016 p += sizeof ("LOG_RNB_EVENTS") - 1; 2017 bitmask |= LOG_RNB_EVENTS; 2018 } 2019 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0) 2020 { 2021 p += sizeof ("LOG_RNB_PROC") - 1; 2022 bitmask |= LOG_RNB_PROC; 2023 } 2024 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0) 2025 { 2026 p += sizeof ("LOG_RNB_PACKETS") - 1; 2027 bitmask |= LOG_RNB_PACKETS; 2028 } 2029 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0) 2030 { 2031 p += sizeof ("LOG_RNB_ALL") - 1; 2032 bitmask |= LOG_RNB_ALL; 2033 } 2034 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0) 2035 { 2036 p += sizeof ("LOG_RNB_DEFAULT") - 1; 2037 bitmask |= LOG_RNB_DEFAULT; 2038 } 2039 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0) 2040 { 2041 p += sizeof ("LOG_RNB_NONE") - 1; 2042 bitmask = 0; 2043 } 2044 else 2045 { 2046 /* Unrecognized logging bit; ignore it. */ 2047 const char *c = strchr (p, '|'); 2048 if (c) 2049 { 2050 p = c; 2051 } 2052 else 2053 { 2054 c = strchr (p, ';'); 2055 if (c) 2056 { 2057 p = c; 2058 } 2059 else 2060 { 2061 // Improperly terminated word; just go to end of str 2062 p = strchr (p, '\0'); 2063 } 2064 } 2065 } 2066 } 2067 // Did we get a properly formatted logging bitmask? 2068 if (p && *p == ';') 2069 { 2070 // Enable DNB logging 2071 DNBLogSetLogCallback(ASLLogCallback, NULL); 2072 DNBLogSetLogMask (bitmask); 2073 p++; 2074 } 2075 } 2076 // We're not going to support logging to a file for now. All logging 2077 // goes through ASL. 2078 #if 0 2079 else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0) 2080 { 2081 p += sizeof ("mode=") - 1; 2082 if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0) 2083 { 2084 DNBLogToASL (); 2085 p += sizeof ("asl;") - 1; 2086 } 2087 else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0) 2088 { 2089 DNBLogToFile (); 2090 p += sizeof ("file;") - 1; 2091 } 2092 else 2093 { 2094 // Ignore unknown argument 2095 const char *c = strchr (p, ';'); 2096 if (c) 2097 p = c + 1; 2098 else 2099 p = strchr (p, '\0'); 2100 } 2101 } 2102 else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0) 2103 { 2104 p += sizeof ("filename=") - 1; 2105 const char *c = strchr (p, ';'); 2106 if (c == NULL) 2107 { 2108 c = strchr (p, '\0'); 2109 continue; 2110 } 2111 char *fn = (char *) alloca (c - p + 1); 2112 strncpy (fn, p, c - p); 2113 fn[c - p] = '\0'; 2114 2115 // A file name of "asl" is special and is another way to indicate 2116 // that logging should be done via ASL, not by file. 2117 if (strcmp (fn, "asl") == 0) 2118 { 2119 DNBLogToASL (); 2120 } 2121 else 2122 { 2123 FILE *f = fopen (fn, "w"); 2124 if (f) 2125 { 2126 DNBLogSetLogFile (f); 2127 DNBEnableLogging (f, DNBLogGetLogMask ()); 2128 DNBLogToFile (); 2129 } 2130 } 2131 p = c + 1; 2132 } 2133 #endif /* #if 0 to enforce ASL logging only. */ 2134 else 2135 { 2136 // Ignore unknown argument 2137 const char *c = strchr (p, ';'); 2138 if (c) 2139 p = c + 1; 2140 else 2141 p = strchr (p, '\0'); 2142 } 2143 } 2144 2145 return rnb_success; 2146 } 2147 2148 rnb_err_t 2149 RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p) 2150 { 2151 m_thread_suffix_supported = true; 2152 return SendPacket ("OK"); 2153 } 2154 2155 rnb_err_t 2156 RNBRemote::HandlePacket_QStartNoAckMode (const char *p) 2157 { 2158 // Send the OK packet first so the correct checksum is appended... 2159 rnb_err_t result = SendPacket ("OK"); 2160 m_noack_mode = true; 2161 return result; 2162 } 2163 2164 2165 rnb_err_t 2166 RNBRemote::HandlePacket_QSetLogging (const char *p) 2167 { 2168 p += sizeof ("QSetLogging:") - 1; 2169 rnb_err_t result = set_logging (p); 2170 if (result == rnb_success) 2171 return SendPacket ("OK"); 2172 else 2173 return SendPacket ("E35"); 2174 } 2175 2176 rnb_err_t 2177 RNBRemote::HandlePacket_QSetDisableASLR (const char *p) 2178 { 2179 extern int g_disable_aslr; 2180 p += sizeof ("QSetDisableASLR:") - 1; 2181 switch (*p) 2182 { 2183 case '0': g_disable_aslr = 0; break; 2184 case '1': g_disable_aslr = 1; break; 2185 default: 2186 return SendPacket ("E56"); 2187 } 2188 return SendPacket ("OK"); 2189 } 2190 2191 rnb_err_t 2192 RNBRemote::HandlePacket_QSetSTDIO (const char *p) 2193 { 2194 // Only set stdin/out/err if we don't already have a process 2195 if (!m_ctx.HasValidProcessID()) 2196 { 2197 bool success = false; 2198 // Check the seventh character since the packet will be one of: 2199 // QSetSTDIN 2200 // QSetSTDOUT 2201 // QSetSTDERR 2202 StringExtractor packet(p); 2203 packet.SetFilePos (7); 2204 char ch = packet.GetChar(); 2205 while (packet.GetChar() != ':') 2206 /* Do nothing. */; 2207 2208 switch (ch) 2209 { 2210 case 'I': // STDIN 2211 packet.GetHexByteString (m_ctx.GetSTDIN()); 2212 success = !m_ctx.GetSTDIN().empty(); 2213 break; 2214 2215 case 'O': // STDOUT 2216 packet.GetHexByteString (m_ctx.GetSTDOUT()); 2217 success = !m_ctx.GetSTDOUT().empty(); 2218 break; 2219 2220 case 'E': // STDERR 2221 packet.GetHexByteString (m_ctx.GetSTDERR()); 2222 success = !m_ctx.GetSTDERR().empty(); 2223 break; 2224 2225 default: 2226 break; 2227 } 2228 if (success) 2229 return SendPacket ("OK"); 2230 return SendPacket ("E57"); 2231 } 2232 return SendPacket ("E58"); 2233 } 2234 2235 rnb_err_t 2236 RNBRemote::HandlePacket_QSetWorkingDir (const char *p) 2237 { 2238 // Only set the working directory if we don't already have a process 2239 if (!m_ctx.HasValidProcessID()) 2240 { 2241 StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1); 2242 if (packet.GetHexByteString (m_ctx.GetWorkingDir())) 2243 { 2244 struct stat working_dir_stat; 2245 if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) 2246 { 2247 m_ctx.GetWorkingDir().clear(); 2248 return SendPacket ("E61"); // Working directory doesn't exist... 2249 } 2250 else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) 2251 { 2252 return SendPacket ("OK"); 2253 } 2254 else 2255 { 2256 m_ctx.GetWorkingDir().clear(); 2257 return SendPacket ("E62"); // Working directory isn't a directory... 2258 } 2259 } 2260 return SendPacket ("E59"); // Invalid path 2261 } 2262 return SendPacket ("E60"); // Already had a process, too late to set working dir 2263 } 2264 2265 rnb_err_t 2266 RNBRemote::HandlePacket_QSyncThreadState (const char *p) 2267 { 2268 if (!m_ctx.HasValidProcessID()) 2269 { 2270 // We allow gdb to connect to a server that hasn't started running 2271 // the target yet. gdb still wants to ask questions about it and 2272 // freaks out if it gets an error. So just return OK here. 2273 return SendPacket ("OK"); 2274 } 2275 2276 errno = 0; 2277 p += strlen("QSyncThreadState:"); 2278 nub_thread_t tid = strtoul (p, NULL, 16); 2279 if (errno != 0 && tid == 0) 2280 { 2281 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet"); 2282 } 2283 if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid)) 2284 return SendPacket("OK"); 2285 else 2286 return SendPacket ("E61"); 2287 } 2288 2289 rnb_err_t 2290 RNBRemote::HandlePacket_QSetDetachOnError (const char *p) 2291 { 2292 p += sizeof ("QSetDetachOnError:") - 1; 2293 bool should_detach = true; 2294 switch (*p) 2295 { 2296 case '0': should_detach = false; break; 2297 case '1': should_detach = true; break; 2298 default: 2299 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid value for QSetDetachOnError - should be 0 or 1"); 2300 break; 2301 } 2302 2303 m_ctx.SetDetachOnError(should_detach); 2304 return SendPacket ("OK"); 2305 } 2306 2307 rnb_err_t 2308 RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p) 2309 { 2310 // If this packet is received, it allows us to send an extra key/value 2311 // pair in the stop reply packets where we will list all of the thread IDs 2312 // separated by commas: 2313 // 2314 // "threads:10a,10b,10c;" 2315 // 2316 // This will get included in the stop reply packet as something like: 2317 // 2318 // "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;" 2319 // 2320 // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and 2321 // speed things up a bit. 2322 // 2323 // Send the OK packet first so the correct checksum is appended... 2324 rnb_err_t result = SendPacket ("OK"); 2325 m_list_threads_in_stop_reply = true; 2326 2327 return result; 2328 } 2329 2330 2331 rnb_err_t 2332 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p) 2333 { 2334 /* The number of characters in a packet payload that gdb is 2335 prepared to accept. The packet-start char, packet-end char, 2336 2 checksum chars and terminating null character are not included 2337 in this size. */ 2338 p += sizeof ("QSetMaxPayloadSize:") - 1; 2339 errno = 0; 2340 uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16)); 2341 if (errno != 0 && size == 0) 2342 { 2343 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet"); 2344 } 2345 m_max_payload_size = size; 2346 return SendPacket ("OK"); 2347 } 2348 2349 rnb_err_t 2350 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p) 2351 { 2352 /* This tells us the largest packet that gdb can handle. 2353 i.e. the size of gdb's packet-reading buffer. 2354 QSetMaxPayloadSize is preferred because it is less ambiguous. */ 2355 p += sizeof ("QSetMaxPacketSize:") - 1; 2356 errno = 0; 2357 uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16)); 2358 if (errno != 0 && size == 0) 2359 { 2360 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet"); 2361 } 2362 m_max_payload_size = size - 5; 2363 return SendPacket ("OK"); 2364 } 2365 2366 2367 2368 2369 rnb_err_t 2370 RNBRemote::HandlePacket_QEnvironment (const char *p) 2371 { 2372 /* This sets the environment for the target program. The packet is of the form: 2373 2374 QEnvironment:VARIABLE=VALUE 2375 2376 */ 2377 2378 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"", 2379 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2380 2381 p += sizeof ("QEnvironment:") - 1; 2382 RNBContext& ctx = Context(); 2383 2384 ctx.PushEnvironment (p); 2385 return SendPacket ("OK"); 2386 } 2387 2388 rnb_err_t 2389 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p) 2390 { 2391 /* This sets the environment for the target program. The packet is of the form: 2392 2393 QEnvironmentHexEncoded:VARIABLE=VALUE 2394 2395 The VARIABLE=VALUE part is sent hex-encoded so characters like '#' with special 2396 meaning in the remote protocol won't break it. 2397 */ 2398 2399 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"", 2400 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2401 2402 p += sizeof ("QEnvironmentHexEncoded:") - 1; 2403 2404 std::string arg; 2405 const char *c; 2406 c = p; 2407 while (*c != '\0') 2408 { 2409 if (*(c + 1) == '\0') 2410 { 2411 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2412 } 2413 char smallbuf[3]; 2414 smallbuf[0] = *c; 2415 smallbuf[1] = *(c + 1); 2416 smallbuf[2] = '\0'; 2417 errno = 0; 2418 int ch = static_cast<int>(strtoul (smallbuf, NULL, 16)); 2419 if (errno != 0 && ch == 0) 2420 { 2421 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2422 } 2423 arg.push_back(ch); 2424 c += 2; 2425 } 2426 2427 RNBContext& ctx = Context(); 2428 if (arg.length() > 0) 2429 ctx.PushEnvironment (arg.c_str()); 2430 2431 return SendPacket ("OK"); 2432 } 2433 2434 2435 rnb_err_t 2436 RNBRemote::HandlePacket_QLaunchArch (const char *p) 2437 { 2438 p += sizeof ("QLaunchArch:") - 1; 2439 if (DNBSetArchitecture(p)) 2440 return SendPacket ("OK"); 2441 return SendPacket ("E63"); 2442 } 2443 2444 rnb_err_t 2445 RNBRemote::HandlePacket_QSetProcessEvent (const char *p) 2446 { 2447 p += sizeof ("QSetProcessEvent:") - 1; 2448 // If the process is running, then send the event to the process, otherwise 2449 // store it in the context. 2450 if (Context().HasValidProcessID()) 2451 { 2452 if (DNBProcessSendEvent (Context().ProcessID(), p)) 2453 return SendPacket("OK"); 2454 else 2455 return SendPacket ("E80"); 2456 } 2457 else 2458 { 2459 Context().PushProcessEvent(p); 2460 } 2461 return SendPacket ("OK"); 2462 } 2463 2464 void 2465 append_hex_value (std::ostream& ostrm, const void *buf, size_t buf_size, bool swap) 2466 { 2467 int i; 2468 const uint8_t *p = (const uint8_t *)buf; 2469 if (swap) 2470 { 2471 for (i = static_cast<int>(buf_size)-1; i >= 0; i--) 2472 ostrm << RAWHEX8(p[i]); 2473 } 2474 else 2475 { 2476 for (size_t i = 0; i < buf_size; i++) 2477 ostrm << RAWHEX8(p[i]); 2478 } 2479 } 2480 2481 void 2482 append_hexified_string (std::ostream& ostrm, const std::string &string) 2483 { 2484 size_t string_size = string.size(); 2485 const char *string_buf = string.c_str(); 2486 for (size_t i = 0; i < string_size; i++) 2487 { 2488 ostrm << RAWHEX8(*(string_buf + i)); 2489 } 2490 } 2491 2492 2493 2494 void 2495 register_value_in_hex_fixed_width (std::ostream& ostrm, 2496 nub_process_t pid, 2497 nub_thread_t tid, 2498 const register_map_entry_t* reg, 2499 const DNBRegisterValue *reg_value_ptr) 2500 { 2501 if (reg != NULL) 2502 { 2503 DNBRegisterValue reg_value; 2504 if (reg_value_ptr == NULL) 2505 { 2506 if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, ®_value)) 2507 reg_value_ptr = ®_value; 2508 } 2509 2510 if (reg_value_ptr) 2511 { 2512 append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false); 2513 } 2514 else 2515 { 2516 // If we fail to read a register value, check if it has a default 2517 // fail value. If it does, return this instead in case some of 2518 // the registers are not available on the current system. 2519 if (reg->nub_info.size > 0) 2520 { 2521 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0'); 2522 append_hex_value (ostrm, zeros.data(), zeros.size(), false); 2523 } 2524 } 2525 } 2526 } 2527 2528 2529 void 2530 debugserver_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm, 2531 nub_process_t pid, 2532 nub_thread_t tid, 2533 const register_map_entry_t* reg, 2534 const DNBRegisterValue *reg_value_ptr) 2535 { 2536 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX 2537 // gdb register number, and VVVVVVVV is the correct number of hex bytes 2538 // as ASCII for the register value. 2539 if (reg != NULL) 2540 { 2541 ostrm << RAWHEX8(reg->debugserver_regnum) << ':'; 2542 register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr); 2543 ostrm << ';'; 2544 } 2545 } 2546 2547 2548 void 2549 RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid, 2550 nub_addr_t dispatch_qaddr, 2551 nub_addr_t &dispatch_queue_t, 2552 std::string &queue_name, 2553 uint64_t &queue_width, 2554 uint64_t &queue_serialnum) const 2555 { 2556 queue_name.clear(); 2557 queue_width = 0; 2558 queue_serialnum = 0; 2559 2560 if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS && dispatch_qaddr != 0) 2561 { 2562 dispatch_queue_t = DNBProcessMemoryReadPointer (pid, dispatch_qaddr); 2563 if (dispatch_queue_t) 2564 { 2565 queue_width = DNBProcessMemoryReadInteger (pid, dispatch_queue_t + dqo_width, dqo_width_size, 0); 2566 queue_serialnum = DNBProcessMemoryReadInteger (pid, dispatch_queue_t + dqo_serialnum, dqo_serialnum_size, 0); 2567 2568 if (dqo_version >= 4) 2569 { 2570 // libdispatch versions 4+, pointer to dispatch name is in the 2571 // queue structure. 2572 nub_addr_t pointer_to_label_address = dispatch_queue_t + dqo_label; 2573 nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address); 2574 if (label_addr) 2575 queue_name = DNBProcessMemoryReadCString(pid, label_addr); 2576 } 2577 else 2578 { 2579 // libdispatch versions 1-3, dispatch name is a fixed width char array 2580 // in the queue structure. 2581 queue_name = DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_t + dqo_label, dqo_label_size); 2582 } 2583 } 2584 } 2585 } 2586 2587 struct StackMemory 2588 { 2589 uint8_t bytes[2*sizeof(nub_addr_t)]; 2590 nub_size_t length; 2591 }; 2592 typedef std::map<nub_addr_t, StackMemory> StackMemoryMap; 2593 2594 2595 static void 2596 ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap, uint32_t backtrace_limit = 256) 2597 { 2598 DNBRegisterValue reg_value; 2599 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, ®_value)) 2600 { 2601 uint32_t frame_count = 0; 2602 uint64_t fp = 0; 2603 if (reg_value.info.size == 4) 2604 fp = reg_value.value.uint32; 2605 else 2606 fp = reg_value.value.uint64; 2607 while (fp != 0) 2608 { 2609 // Make sure we never recurse more than 256 times so we don't recurse too far or 2610 // store up too much memory in the expedited cache 2611 if (++frame_count > backtrace_limit) 2612 break; 2613 2614 const nub_size_t read_size = reg_value.info.size*2; 2615 StackMemory stack_memory; 2616 stack_memory.length = read_size; 2617 if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size) 2618 break; 2619 // Make sure we don't try to put the same stack memory in more than once 2620 if (stack_mmap.find(fp) != stack_mmap.end()) 2621 break; 2622 // Put the entry into the cache 2623 stack_mmap[fp] = stack_memory; 2624 // Dereference the frame pointer to get to the previous frame pointer 2625 if (reg_value.info.size == 4) 2626 fp = ((uint32_t *)stack_memory.bytes)[0]; 2627 else 2628 fp = ((uint64_t *)stack_memory.bytes)[0]; 2629 } 2630 } 2631 } 2632 2633 rnb_err_t 2634 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) 2635 { 2636 const nub_process_t pid = m_ctx.ProcessID(); 2637 if (pid == INVALID_NUB_PROCESS) 2638 return SendPacket("E50"); 2639 2640 struct DNBThreadStopInfo tid_stop_info; 2641 2642 /* Fill the remaining space in this packet with as many registers 2643 as we can stuff in there. */ 2644 2645 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) 2646 { 2647 const bool did_exec = tid_stop_info.reason == eStopTypeExec; 2648 if (did_exec) 2649 { 2650 RNBRemote::InitializeRegisters(true); 2651 2652 // Reset any symbols that need resetting when we exec 2653 m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS; 2654 m_dispatch_queue_offsets.Clear(); 2655 } 2656 2657 std::ostringstream ostrm; 2658 // Output the T packet with the thread 2659 ostrm << 'T'; 2660 int signum = tid_stop_info.details.signal.signo; 2661 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); 2662 2663 // Translate any mach exceptions to gdb versions, unless they are 2664 // common exceptions like a breakpoint or a soft signal. 2665 switch (tid_stop_info.details.exception.type) 2666 { 2667 default: signum = 0; break; 2668 case EXC_BREAKPOINT: signum = SIGTRAP; break; 2669 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break; 2670 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break; 2671 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break; 2672 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break; 2673 case EXC_SOFTWARE: 2674 if (tid_stop_info.details.exception.data_count == 2 && 2675 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2676 signum = static_cast<int>(tid_stop_info.details.exception.data[1]); 2677 else 2678 signum = TARGET_EXC_SOFTWARE; 2679 break; 2680 } 2681 2682 ostrm << RAWHEX8(signum & 0xff); 2683 2684 ostrm << std::hex << "thread:" << tid << ';'; 2685 2686 const char *thread_name = DNBThreadGetName (pid, tid); 2687 if (thread_name && thread_name[0]) 2688 { 2689 size_t thread_name_len = strlen(thread_name); 2690 2691 2692 if (::strcspn (thread_name, "$#+-;:") == thread_name_len) 2693 ostrm << std::hex << "name:" << thread_name << ';'; 2694 else 2695 { 2696 // the thread name contains special chars, send as hex bytes 2697 ostrm << std::hex << "hexname:"; 2698 uint8_t *u_thread_name = (uint8_t *)thread_name; 2699 for (size_t i = 0; i < thread_name_len; i++) 2700 ostrm << RAWHEX8(u_thread_name[i]); 2701 ostrm << ';'; 2702 } 2703 } 2704 2705 // If a 'QListThreadsInStopReply' was sent to enable this feature, we 2706 // will send all thread IDs back in the "threads" key whose value is 2707 // a list of hex thread IDs separated by commas: 2708 // "threads:10a,10b,10c;" 2709 // This will save the debugger from having to send a pair of qfThreadInfo 2710 // and qsThreadInfo packets, but it also might take a lot of room in the 2711 // stop reply packet, so it must be enabled only on systems where there 2712 // are no limits on packet lengths. 2713 if (m_list_threads_in_stop_reply) 2714 { 2715 const nub_size_t numthreads = DNBProcessGetNumThreads (pid); 2716 if (numthreads > 0) 2717 { 2718 std::vector<uint64_t> pc_values; 2719 ostrm << std::hex << "threads:"; 2720 for (nub_size_t i = 0; i < numthreads; ++i) 2721 { 2722 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 2723 if (i > 0) 2724 ostrm << ','; 2725 ostrm << std::hex << th; 2726 DNBRegisterValue pc_regval; 2727 if (DNBThreadGetRegisterValueByID (pid, th, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_regval)) 2728 { 2729 uint64_t pc = INVALID_NUB_ADDRESS; 2730 if (pc_regval.value.uint64 != INVALID_NUB_ADDRESS) 2731 { 2732 if (pc_regval.info.size == 4) 2733 { 2734 pc = pc_regval.value.uint32; 2735 } 2736 else if (pc_regval.info.size == 8) 2737 { 2738 pc = pc_regval.value.uint64; 2739 } 2740 if (pc != INVALID_NUB_ADDRESS) 2741 { 2742 pc_values.push_back (pc); 2743 } 2744 } 2745 } 2746 } 2747 ostrm << ';'; 2748 2749 // If we failed to get any of the thread pc values, the size of our vector will not 2750 // be the same as the # of threads. Don't provide any expedited thread pc values in 2751 // that case. This should not happen. 2752 if (pc_values.size() == numthreads) 2753 { 2754 ostrm << std::hex << "thread-pcs:"; 2755 for (nub_size_t i = 0; i < numthreads; ++i) 2756 { 2757 if (i > 0) 2758 ostrm << ','; 2759 ostrm << std::hex << pc_values[i]; 2760 } 2761 ostrm << ';'; 2762 } 2763 } 2764 2765 // Include JSON info that describes the stop reason for any threads 2766 // that actually have stop reasons. We use the new "jstopinfo" key 2767 // whose values is hex ascii JSON that contains the thread IDs 2768 // thread stop info only for threads that have stop reasons. Only send 2769 // this if we have more than one thread otherwise this packet has all 2770 // the info it needs. 2771 if (numthreads > 1) 2772 { 2773 const bool threads_with_valid_stop_info_only = true; 2774 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 2775 if (threads_info_sp) 2776 { 2777 ostrm << std::hex << "jstopinfo:"; 2778 std::ostringstream json_strm; 2779 threads_info_sp->Dump (json_strm); 2780 append_hexified_string (ostrm, json_strm.str()); 2781 ostrm << ';'; 2782 } 2783 } 2784 } 2785 2786 if (g_num_reg_entries == 0) 2787 InitializeRegisters (); 2788 2789 if (g_reg_entries != NULL) 2790 { 2791 DNBRegisterValue reg_value; 2792 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2793 { 2794 // Expedite all registers in the first register set that aren't 2795 // contained in other registers 2796 if (g_reg_entries[reg].nub_info.set == 1 && 2797 g_reg_entries[reg].nub_info.value_regs == NULL) 2798 { 2799 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 2800 continue; 2801 2802 debugserver_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], ®_value); 2803 } 2804 } 2805 } 2806 2807 if (did_exec) 2808 { 2809 ostrm << "reason:exec;"; 2810 } 2811 else if (tid_stop_info.details.exception.type) 2812 { 2813 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';'; 2814 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';'; 2815 for (nub_size_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) 2816 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';'; 2817 } 2818 2819 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 2820 // frame pointer chain. 2821 StackMemoryMap stack_mmap; 2822 ReadStackMemory (pid, tid, stack_mmap, 2); 2823 if (!stack_mmap.empty()) 2824 { 2825 for (const auto &stack_memory : stack_mmap) 2826 { 2827 ostrm << "memory:" << HEXBASE << stack_memory.first << '='; 2828 append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false); 2829 ostrm << ';'; 2830 } 2831 } 2832 2833 return SendPacket (ostrm.str ()); 2834 } 2835 return SendPacket("E51"); 2836 } 2837 2838 /* '?' 2839 The stop reply packet - tell gdb what the status of the inferior is. 2840 Often called the questionmark_packet. */ 2841 2842 rnb_err_t 2843 RNBRemote::HandlePacket_last_signal (const char *unused) 2844 { 2845 if (!m_ctx.HasValidProcessID()) 2846 { 2847 // Inferior is not yet specified/running 2848 return SendPacket ("E02"); 2849 } 2850 2851 nub_process_t pid = m_ctx.ProcessID(); 2852 nub_state_t pid_state = DNBProcessGetState (pid); 2853 2854 switch (pid_state) 2855 { 2856 case eStateAttaching: 2857 case eStateLaunching: 2858 case eStateRunning: 2859 case eStateStepping: 2860 case eStateDetached: 2861 return rnb_success; // Ignore 2862 2863 case eStateSuspended: 2864 case eStateStopped: 2865 case eStateCrashed: 2866 { 2867 nub_thread_t tid = DNBProcessGetCurrentThread (pid); 2868 // Make sure we set the current thread so g and p packets return 2869 // the data the gdb will expect. 2870 SetCurrentThread (tid); 2871 2872 SendStopReplyPacketForThread (tid); 2873 } 2874 break; 2875 2876 case eStateInvalid: 2877 case eStateUnloaded: 2878 case eStateExited: 2879 { 2880 char pid_exited_packet[16] = ""; 2881 int pid_status = 0; 2882 // Process exited with exit status 2883 if (!DNBProcessGetExitStatus(pid, &pid_status)) 2884 pid_status = 0; 2885 2886 if (pid_status) 2887 { 2888 if (WIFEXITED (pid_status)) 2889 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status)); 2890 else if (WIFSIGNALED (pid_status)) 2891 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status)); 2892 else if (WIFSTOPPED (pid_status)) 2893 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status)); 2894 } 2895 2896 // If we have an empty exit packet, lets fill one in to be safe. 2897 if (!pid_exited_packet[0]) 2898 { 2899 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1); 2900 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0'; 2901 } 2902 2903 const char *exit_info = DNBProcessGetExitInfo (pid); 2904 if (exit_info != NULL && *exit_info != '\0') 2905 { 2906 std::ostringstream exit_packet; 2907 exit_packet << pid_exited_packet; 2908 exit_packet << ';'; 2909 exit_packet << RAW_HEXBASE << "description"; 2910 exit_packet << ':'; 2911 for (size_t i = 0; exit_info[i] != '\0'; i++) 2912 exit_packet << RAWHEX8(exit_info[i]); 2913 exit_packet << ';'; 2914 return SendPacket (exit_packet.str()); 2915 } 2916 else 2917 return SendPacket (pid_exited_packet); 2918 } 2919 break; 2920 } 2921 return rnb_success; 2922 } 2923 2924 rnb_err_t 2925 RNBRemote::HandlePacket_M (const char *p) 2926 { 2927 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2928 { 2929 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet"); 2930 } 2931 2932 char *c; 2933 p++; 2934 errno = 0; 2935 nub_addr_t addr = strtoull (p, &c, 16); 2936 if (errno != 0 && addr == 0) 2937 { 2938 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet"); 2939 } 2940 if (*c != ',') 2941 { 2942 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet"); 2943 } 2944 2945 /* Advance 'p' to the length part of the packet. */ 2946 p += (c - p) + 1; 2947 2948 errno = 0; 2949 unsigned long length = strtoul (p, &c, 16); 2950 if (errno != 0 && length == 0) 2951 { 2952 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet"); 2953 } 2954 if (length == 0) 2955 { 2956 return SendPacket ("OK"); 2957 } 2958 2959 if (*c != ':') 2960 { 2961 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet"); 2962 } 2963 /* Advance 'p' to the data part of the packet. */ 2964 p += (c - p) + 1; 2965 2966 size_t datalen = strlen (p); 2967 if (datalen & 0x1) 2968 { 2969 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet"); 2970 } 2971 if (datalen == 0) 2972 { 2973 return SendPacket ("OK"); 2974 } 2975 2976 uint8_t *buf = (uint8_t *) alloca (datalen / 2); 2977 uint8_t *i = buf; 2978 2979 while (*p != '\0' && *(p + 1) != '\0') 2980 { 2981 char hexbuf[3]; 2982 hexbuf[0] = *p; 2983 hexbuf[1] = *(p + 1); 2984 hexbuf[2] = '\0'; 2985 errno = 0; 2986 uint8_t byte = strtoul (hexbuf, NULL, 16); 2987 if (errno != 0 && byte == 0) 2988 { 2989 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet"); 2990 } 2991 *i++ = byte; 2992 p += 2; 2993 } 2994 2995 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf); 2996 if (wrote != length) 2997 return SendPacket ("E09"); 2998 else 2999 return SendPacket ("OK"); 3000 } 3001 3002 3003 rnb_err_t 3004 RNBRemote::HandlePacket_m (const char *p) 3005 { 3006 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3007 { 3008 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet"); 3009 } 3010 3011 char *c; 3012 p++; 3013 errno = 0; 3014 nub_addr_t addr = strtoull (p, &c, 16); 3015 if (errno != 0 && addr == 0) 3016 { 3017 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet"); 3018 } 3019 if (*c != ',') 3020 { 3021 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet"); 3022 } 3023 3024 /* Advance 'p' to the length part of the packet. */ 3025 p += (c - p) + 1; 3026 3027 errno = 0; 3028 auto length = strtoul (p, NULL, 16); 3029 if (errno != 0 && length == 0) 3030 { 3031 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 3032 } 3033 if (length == 0) 3034 { 3035 return SendPacket (""); 3036 } 3037 3038 std::string buf(length, '\0'); 3039 if (buf.empty()) 3040 { 3041 return SendPacket ("E78"); 3042 } 3043 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3044 if (bytes_read == 0) 3045 { 3046 return SendPacket ("E08"); 3047 } 3048 3049 // "The reply may contain fewer bytes than requested if the server was able 3050 // to read only part of the region of memory." 3051 length = bytes_read; 3052 3053 std::ostringstream ostrm; 3054 for (unsigned long i = 0; i < length; i++) 3055 ostrm << RAWHEX8(buf[i]); 3056 return SendPacket (ostrm.str ()); 3057 } 3058 3059 // Read memory, sent it up as binary data. 3060 // Usage: xADDR,LEN 3061 // ADDR and LEN are both base 16. 3062 3063 // Responds with 'OK' for zero-length request 3064 // or 3065 // 3066 // DATA 3067 // 3068 // where DATA is the binary data payload. 3069 3070 rnb_err_t 3071 RNBRemote::HandlePacket_x (const char *p) 3072 { 3073 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3074 { 3075 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 3076 } 3077 3078 char *c; 3079 p++; 3080 errno = 0; 3081 nub_addr_t addr = strtoull (p, &c, 16); 3082 if (errno != 0) 3083 { 3084 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 3085 } 3086 if (*c != ',') 3087 { 3088 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 3089 } 3090 3091 /* Advance 'p' to the number of bytes to be read. */ 3092 p += (c - p) + 1; 3093 3094 errno = 0; 3095 auto length = strtoul (p, NULL, 16); 3096 if (errno != 0) 3097 { 3098 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in x packet"); 3099 } 3100 3101 // zero length read means this is a test of whether that packet is implemented or not. 3102 if (length == 0) 3103 { 3104 return SendPacket ("OK"); 3105 } 3106 3107 std::vector<uint8_t> buf (length); 3108 3109 if (buf.capacity() != length) 3110 { 3111 return SendPacket ("E79"); 3112 } 3113 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3114 if (bytes_read == 0) 3115 { 3116 return SendPacket ("E80"); 3117 } 3118 3119 std::vector<uint8_t> buf_quoted; 3120 buf_quoted.reserve (bytes_read + 30); 3121 for (nub_size_t i = 0; i < bytes_read; i++) 3122 { 3123 if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*') 3124 { 3125 buf_quoted.push_back(0x7d); 3126 buf_quoted.push_back(buf[i] ^ 0x20); 3127 } 3128 else 3129 { 3130 buf_quoted.push_back(buf[i]); 3131 } 3132 } 3133 length = buf_quoted.size(); 3134 3135 std::ostringstream ostrm; 3136 for (unsigned long i = 0; i < length; i++) 3137 ostrm << buf_quoted[i]; 3138 3139 return SendPacket (ostrm.str ()); 3140 } 3141 3142 rnb_err_t 3143 RNBRemote::HandlePacket_X (const char *p) 3144 { 3145 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3146 { 3147 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 3148 } 3149 3150 char *c; 3151 p++; 3152 errno = 0; 3153 nub_addr_t addr = strtoull (p, &c, 16); 3154 if (errno != 0 && addr == 0) 3155 { 3156 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 3157 } 3158 if (*c != ',') 3159 { 3160 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 3161 } 3162 3163 /* Advance 'p' to the length part of the packet. NB this is the length of the packet 3164 including any escaped chars. The data payload may be a little bit smaller after 3165 decoding. */ 3166 p += (c - p) + 1; 3167 3168 errno = 0; 3169 auto length = strtoul (p, NULL, 16); 3170 if (errno != 0 && length == 0) 3171 { 3172 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in X packet"); 3173 } 3174 3175 // I think gdb sends a zero length write request to test whether this 3176 // packet is accepted. 3177 if (length == 0) 3178 { 3179 return SendPacket ("OK"); 3180 } 3181 3182 std::vector<uint8_t> data = decode_binary_data (c, -1); 3183 std::vector<uint8_t>::const_iterator it; 3184 uint8_t *buf = (uint8_t *) alloca (data.size ()); 3185 uint8_t *i = buf; 3186 for (it = data.begin (); it != data.end (); ++it) 3187 { 3188 *i++ = *it; 3189 } 3190 3191 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf); 3192 if (wrote != data.size ()) 3193 return SendPacket ("E08"); 3194 return SendPacket ("OK"); 3195 } 3196 3197 /* 'g' -- read registers 3198 Get the contents of the registers for the current thread, 3199 send them to gdb. 3200 Should the setting of the Hg packet determine which thread's registers 3201 are returned? */ 3202 3203 rnb_err_t 3204 RNBRemote::HandlePacket_g (const char *p) 3205 { 3206 std::ostringstream ostrm; 3207 if (!m_ctx.HasValidProcessID()) 3208 { 3209 return SendPacket ("E11"); 3210 } 3211 3212 if (g_num_reg_entries == 0) 3213 InitializeRegisters (); 3214 3215 nub_process_t pid = m_ctx.ProcessID (); 3216 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1); 3217 if (tid == INVALID_NUB_THREAD) 3218 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3219 3220 // Get the register context size first by calling with NULL buffer 3221 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3222 if (reg_ctx_size) 3223 { 3224 // Now allocate enough space for the entire register context 3225 std::vector<uint8_t> reg_ctx; 3226 reg_ctx.resize(reg_ctx_size); 3227 // Now read the register context 3228 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 3229 if (reg_ctx_size) 3230 { 3231 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false); 3232 return SendPacket (ostrm.str ()); 3233 } 3234 } 3235 return SendPacket ("E74"); 3236 } 3237 3238 /* 'G XXX...' -- write registers 3239 How is the thread for these specified, beyond "the current thread"? 3240 Does gdb actually use the Hg packet to set this? */ 3241 3242 rnb_err_t 3243 RNBRemote::HandlePacket_G (const char *p) 3244 { 3245 if (!m_ctx.HasValidProcessID()) 3246 { 3247 return SendPacket ("E11"); 3248 } 3249 3250 if (g_num_reg_entries == 0) 3251 InitializeRegisters (); 3252 3253 StringExtractor packet(p); 3254 packet.SetFilePos(1); // Skip the 'G' 3255 3256 nub_process_t pid = m_ctx.ProcessID(); 3257 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3258 if (tid == INVALID_NUB_THREAD) 3259 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3260 3261 // Get the register context size first by calling with NULL buffer 3262 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3263 if (reg_ctx_size) 3264 { 3265 // Now allocate enough space for the entire register context 3266 std::vector<uint8_t> reg_ctx; 3267 reg_ctx.resize(reg_ctx_size); 3268 3269 const nub_size_t bytes_extracted = packet.GetHexBytes (®_ctx[0], reg_ctx.size(), 0xcc); 3270 if (bytes_extracted == reg_ctx.size()) 3271 { 3272 // Now write the register context 3273 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 3274 if (reg_ctx_size == reg_ctx.size()) 3275 return SendPacket ("OK"); 3276 else 3277 return SendPacket ("E55"); 3278 } 3279 else 3280 { 3281 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); 3282 return SendPacket ("E64"); 3283 } 3284 } 3285 return SendPacket ("E65"); 3286 } 3287 3288 static bool 3289 RNBRemoteShouldCancelCallback (void *not_used) 3290 { 3291 RNBRemoteSP remoteSP(g_remoteSP); 3292 if (remoteSP.get() != NULL) 3293 { 3294 RNBRemote* remote = remoteSP.get(); 3295 if (remote->Comm().IsConnected()) 3296 return false; 3297 else 3298 return true; 3299 } 3300 return true; 3301 } 3302 3303 3304 // FORMAT: _MXXXXXX,PPP 3305 // XXXXXX: big endian hex chars 3306 // PPP: permissions can be any combo of r w x chars 3307 // 3308 // RESPONSE: XXXXXX 3309 // XXXXXX: hex address of the newly allocated memory 3310 // EXX: error code 3311 // 3312 // EXAMPLES: 3313 // _M123000,rw 3314 // _M123000,rwx 3315 // _M123000,xw 3316 3317 rnb_err_t 3318 RNBRemote::HandlePacket_AllocateMemory (const char *p) 3319 { 3320 StringExtractor packet (p); 3321 packet.SetFilePos(2); // Skip the "_M" 3322 3323 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0); 3324 if (size != 0) 3325 { 3326 if (packet.GetChar() == ',') 3327 { 3328 uint32_t permissions = 0; 3329 char ch; 3330 bool success = true; 3331 while (success && (ch = packet.GetChar()) != '\0') 3332 { 3333 switch (ch) 3334 { 3335 case 'r': permissions |= eMemoryPermissionsReadable; break; 3336 case 'w': permissions |= eMemoryPermissionsWritable; break; 3337 case 'x': permissions |= eMemoryPermissionsExecutable; break; 3338 default: success = false; break; 3339 } 3340 } 3341 3342 if (success) 3343 { 3344 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions); 3345 if (addr != INVALID_NUB_ADDRESS) 3346 { 3347 std::ostringstream ostrm; 3348 ostrm << RAW_HEXBASE << addr; 3349 return SendPacket (ostrm.str ()); 3350 } 3351 } 3352 } 3353 } 3354 return SendPacket ("E53"); 3355 } 3356 3357 // FORMAT: _mXXXXXX 3358 // XXXXXX: address that was previously allocated 3359 // 3360 // RESPONSE: XXXXXX 3361 // OK: address was deallocated 3362 // EXX: error code 3363 // 3364 // EXAMPLES: 3365 // _m123000 3366 3367 rnb_err_t 3368 RNBRemote::HandlePacket_DeallocateMemory (const char *p) 3369 { 3370 StringExtractor packet (p); 3371 packet.SetFilePos(2); // Skip the "_m" 3372 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS); 3373 3374 if (addr != INVALID_NUB_ADDRESS) 3375 { 3376 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr)) 3377 return SendPacket ("OK"); 3378 } 3379 return SendPacket ("E54"); 3380 } 3381 3382 3383 // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) 3384 // FORMAT: QSaveRegisterState (when thread suffix is NOT supported) 3385 // TTTT: thread ID in hex 3386 // 3387 // RESPONSE: 3388 // SAVEID: Where SAVEID is a decimal number that represents the save ID 3389 // that can be passed back into a "QRestoreRegisterState" packet 3390 // EXX: error code 3391 // 3392 // EXAMPLES: 3393 // QSaveRegisterState;thread:1E34; (when thread suffix is supported) 3394 // QSaveRegisterState (when thread suffix is NOT supported) 3395 3396 rnb_err_t 3397 RNBRemote::HandlePacket_SaveRegisterState (const char *p) 3398 { 3399 nub_process_t pid = m_ctx.ProcessID (); 3400 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3401 if (tid == INVALID_NUB_THREAD) 3402 { 3403 if (m_thread_suffix_supported) 3404 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 3405 else 3406 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 3407 } 3408 3409 // Get the register context size first by calling with NULL buffer 3410 const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid); 3411 if (save_id != 0) 3412 { 3413 char response[64]; 3414 snprintf (response, sizeof(response), "%u", save_id); 3415 return SendPacket (response); 3416 } 3417 else 3418 { 3419 return SendPacket ("E75"); 3420 } 3421 } 3422 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is supported) 3423 // FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT supported) 3424 // TTTT: thread ID in hex 3425 // SAVEID: a decimal number that represents the save ID that was 3426 // returned from a call to "QSaveRegisterState" 3427 // 3428 // RESPONSE: 3429 // OK: successfully restored registers for the specified thread 3430 // EXX: error code 3431 // 3432 // EXAMPLES: 3433 // QRestoreRegisterState:1;thread:1E34; (when thread suffix is supported) 3434 // QRestoreRegisterState:1 (when thread suffix is NOT supported) 3435 3436 rnb_err_t 3437 RNBRemote::HandlePacket_RestoreRegisterState (const char *p) 3438 { 3439 nub_process_t pid = m_ctx.ProcessID (); 3440 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3441 if (tid == INVALID_NUB_THREAD) 3442 { 3443 if (m_thread_suffix_supported) 3444 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 3445 else 3446 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 3447 } 3448 3449 StringExtractor packet (p); 3450 packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:" 3451 const uint32_t save_id = packet.GetU32(0); 3452 3453 if (save_id != 0) 3454 { 3455 // Get the register context size first by calling with NULL buffer 3456 if (DNBThreadRestoreRegisterState(pid, tid, save_id)) 3457 return SendPacket ("OK"); 3458 else 3459 return SendPacket ("E77"); 3460 } 3461 return SendPacket ("E76"); 3462 } 3463 3464 static bool 3465 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name) 3466 { 3467 bool return_val = true; 3468 while (*p != '\0') 3469 { 3470 char smallbuf[3]; 3471 smallbuf[0] = *p; 3472 smallbuf[1] = *(p + 1); 3473 smallbuf[2] = '\0'; 3474 3475 errno = 0; 3476 int ch = static_cast<int>(strtoul (smallbuf, NULL, 16)); 3477 if (errno != 0 && ch == 0) 3478 { 3479 return_val = false; 3480 break; 3481 } 3482 3483 attach_name.push_back(ch); 3484 p += 2; 3485 } 3486 return return_val; 3487 } 3488 3489 rnb_err_t 3490 RNBRemote::HandlePacket_qSupported (const char *p) 3491 { 3492 uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less 3493 char buf[256]; 3494 snprintf (buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", max_packet_size); 3495 3496 // By default, don't enable compression. It's only worth doing when we are working 3497 // with a low speed communication channel. 3498 bool enable_compression = false; 3499 (void)enable_compression; 3500 3501 // Enable compression when debugserver is running on a watchOS device where communication may be over Bluetooth. 3502 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 3503 enable_compression = true; 3504 #endif 3505 3506 #if defined (HAVE_LIBCOMPRESSION) 3507 // libcompression is weak linked so test if compression_decode_buffer() is available 3508 if (enable_compression && compression_decode_buffer != NULL) 3509 { 3510 strcat (buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;DefaultCompressionMinSize="); 3511 char numbuf[16]; 3512 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3513 numbuf[sizeof (numbuf) - 1] = '\0'; 3514 strcat (buf, numbuf); 3515 } 3516 #elif defined (HAVE_LIBZ) 3517 if (enable_compression) 3518 { 3519 strcat (buf, ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize="); 3520 char numbuf[16]; 3521 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3522 numbuf[sizeof (numbuf) - 1] = '\0'; 3523 strcat (buf, numbuf); 3524 } 3525 #endif 3526 3527 return SendPacket (buf); 3528 } 3529 3530 /* 3531 vAttach;pid 3532 3533 Attach to a new process with the specified process ID. pid is a hexadecimal integer 3534 identifying the process. If the stub is currently controlling a process, it is 3535 killed. The attached process is stopped.This packet is only available in extended 3536 mode (see extended mode). 3537 3538 Reply: 3539 "ENN" for an error 3540 "Any Stop Reply Packet" for success 3541 */ 3542 3543 rnb_err_t 3544 RNBRemote::HandlePacket_v (const char *p) 3545 { 3546 if (strcmp (p, "vCont;c") == 0) 3547 { 3548 // Simple continue 3549 return RNBRemote::HandlePacket_c("c"); 3550 } 3551 else if (strcmp (p, "vCont;s") == 0) 3552 { 3553 // Simple step 3554 return RNBRemote::HandlePacket_s("s"); 3555 } 3556 else if (strstr (p, "vCont") == p) 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 DNBLogThreaded ("RNBRemote::HandlePacket_stop_process() sending extra stop reply because DNBProcessInterrupt returned false"); 4431 HandlePacket_last_signal (NULL); 4432 } 4433 return rnb_success; 4434 #endif 4435 } 4436 4437 /* 's' 4438 Step the inferior process. */ 4439 4440 rnb_err_t 4441 RNBRemote::HandlePacket_s (const char *p) 4442 { 4443 const nub_process_t pid = m_ctx.ProcessID(); 4444 if (pid == INVALID_NUB_PROCESS) 4445 return SendPacket ("E32"); 4446 4447 // Hardware supported stepping not supported on arm 4448 nub_thread_t tid = GetContinueThread (); 4449 if (tid == 0 || tid == (nub_thread_t)-1) 4450 tid = GetCurrentThread(); 4451 4452 if (tid == INVALID_NUB_THREAD) 4453 return SendPacket ("E33"); 4454 4455 DNBThreadResumeActions thread_actions; 4456 thread_actions.AppendAction(tid, eStateStepping); 4457 4458 // Make all other threads stop when we are stepping 4459 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 4460 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4461 return SendPacket ("E49"); 4462 // Don't send an "OK" packet; response is the stopped/exited message. 4463 return rnb_success; 4464 } 4465 4466 /* 'S sig [;addr]' 4467 Step with signal sig, optionally at address addr. */ 4468 4469 rnb_err_t 4470 RNBRemote::HandlePacket_S (const char *p) 4471 { 4472 const nub_process_t pid = m_ctx.ProcessID(); 4473 if (pid == INVALID_NUB_PROCESS) 4474 return SendPacket ("E36"); 4475 4476 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 4477 4478 if (*(p + 1) != '\0') 4479 { 4480 char *end = NULL; 4481 errno = 0; 4482 action.signal = static_cast<int>(strtoul (p + 1, &end, 16)); 4483 if (errno != 0) 4484 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 4485 else if (*end == ';') 4486 { 4487 errno = 0; 4488 action.addr = strtoull (end + 1, NULL, 16); 4489 if (errno != 0 && action.addr == 0) 4490 { 4491 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 4492 } 4493 } 4494 } 4495 4496 action.tid = GetContinueThread (); 4497 if (action.tid == 0 || action.tid == (nub_thread_t)-1) 4498 return SendPacket ("E40"); 4499 4500 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 4501 if (tstate == eStateInvalid || tstate == eStateExited) 4502 return SendPacket ("E37"); 4503 4504 4505 DNBThreadResumeActions thread_actions; 4506 thread_actions.Append (action); 4507 4508 // Make all other threads stop when we are stepping 4509 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4510 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4511 return SendPacket ("E39"); 4512 4513 // Don't send an "OK" packet; response is the stopped/exited message. 4514 return rnb_success; 4515 } 4516 4517 static const char * 4518 GetArchName (const uint32_t cputype, const uint32_t cpusubtype) 4519 { 4520 switch (cputype) 4521 { 4522 case CPU_TYPE_ARM: 4523 switch (cpusubtype) 4524 { 4525 case 5: return "armv4"; 4526 case 6: return "armv6"; 4527 case 7: return "armv5t"; 4528 case 8: return "xscale"; 4529 case 9: return "armv7"; 4530 case 10: return "armv7f"; 4531 case 11: return "armv7s"; 4532 case 12: return "armv7k"; 4533 case 14: return "armv6m"; 4534 case 15: return "armv7m"; 4535 case 16: return "armv7em"; 4536 default: return "arm"; 4537 } 4538 break; 4539 case CPU_TYPE_ARM64: return "arm64"; 4540 case CPU_TYPE_I386: return "i386"; 4541 case CPU_TYPE_X86_64: 4542 switch (cpusubtype) 4543 { 4544 default: return "x86_64"; 4545 case 8: return "x86_64h"; 4546 } 4547 break; 4548 } 4549 return NULL; 4550 } 4551 4552 static bool 4553 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64) 4554 { 4555 static uint32_t g_host_cputype = 0; 4556 static uint32_t g_host_cpusubtype = 0; 4557 static uint32_t g_is_64_bit_capable = 0; 4558 static bool g_promoted_to_64 = false; 4559 4560 if (g_host_cputype == 0) 4561 { 4562 g_promoted_to_64 = false; 4563 size_t len = sizeof(uint32_t); 4564 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) 4565 { 4566 len = sizeof (uint32_t); 4567 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0) 4568 { 4569 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) 4570 { 4571 g_promoted_to_64 = true; 4572 g_host_cputype |= CPU_ARCH_ABI64; 4573 } 4574 } 4575 } 4576 4577 len = sizeof(uint32_t); 4578 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0) 4579 { 4580 if (g_promoted_to_64 && 4581 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486) 4582 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4583 } 4584 } 4585 4586 cputype = g_host_cputype; 4587 cpusubtype = g_host_cpusubtype; 4588 is_64_bit_capable = g_is_64_bit_capable; 4589 promoted_to_64 = g_promoted_to_64; 4590 return g_host_cputype != 0; 4591 } 4592 4593 rnb_err_t 4594 RNBRemote::HandlePacket_qHostInfo (const char *p) 4595 { 4596 std::ostringstream strm; 4597 4598 uint32_t cputype = 0; 4599 uint32_t cpusubtype = 0; 4600 uint32_t is_64_bit_capable = 0; 4601 bool promoted_to_64 = false; 4602 if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) 4603 { 4604 strm << "cputype:" << std::dec << cputype << ';'; 4605 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4606 } 4607 4608 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4609 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4610 // this for now. 4611 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 4612 { 4613 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 4614 strm << "ostype:tvos;"; 4615 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4616 strm << "ostype:watchos;"; 4617 #else 4618 strm << "ostype:ios;"; 4619 #endif 4620 4621 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 4622 strm << "watchpoint_exceptions_received:before;"; 4623 } 4624 else 4625 { 4626 strm << "ostype:macosx;"; 4627 strm << "watchpoint_exceptions_received:after;"; 4628 } 4629 // char ostype[64]; 4630 // len = sizeof(ostype); 4631 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4632 // { 4633 // len = strlen(ostype); 4634 // std::transform (ostype, ostype + len, ostype, tolower); 4635 // strm << "ostype:" << std::dec << ostype << ';'; 4636 // } 4637 4638 strm << "vendor:apple;"; 4639 4640 uint64_t major, minor, patch; 4641 if (DNBGetOSVersionNumbers (&major, &minor, &patch)) 4642 { 4643 strm << "os_version:" << major << "." << minor; 4644 if (patch != UINT64_MAX) 4645 strm << "." << patch; 4646 strm << ";"; 4647 } 4648 4649 #if defined (__LITTLE_ENDIAN__) 4650 strm << "endian:little;"; 4651 #elif defined (__BIG_ENDIAN__) 4652 strm << "endian:big;"; 4653 #elif defined (__PDP_ENDIAN__) 4654 strm << "endian:pdp;"; 4655 #endif 4656 4657 if (promoted_to_64) 4658 strm << "ptrsize:8;"; 4659 else 4660 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4661 4662 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 4663 strm << "default_packet_timeout:10;"; 4664 #endif 4665 4666 return SendPacket (strm.str()); 4667 } 4668 4669 void 4670 XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes) 4671 { 4672 if (indent) 4673 s << INDENT_WITH_SPACES(indent); 4674 s << '<' << name; 4675 if (!has_attributes) 4676 s << '>' << std::endl; 4677 } 4678 4679 void 4680 XMLElementStartEndAttributes (std::ostringstream &s, bool empty) 4681 { 4682 if (empty) 4683 s << '/'; 4684 s << '>' << std::endl; 4685 } 4686 4687 void 4688 XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name) 4689 { 4690 if (indent) 4691 s << INDENT_WITH_SPACES(indent); 4692 s << '<' << '/' << name << '>' << std::endl; 4693 } 4694 4695 void 4696 XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true) 4697 { 4698 if (value) 4699 { 4700 if (indent) 4701 s << INDENT_WITH_SPACES(indent); 4702 s << '<' << name << '>' << value; 4703 if (close) 4704 XMLElementEnd(s, 0, name); 4705 } 4706 } 4707 4708 void 4709 XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true) 4710 { 4711 if (indent) 4712 s << INDENT_WITH_SPACES(indent); 4713 4714 s << '<' << name << '>' << DECIMAL << value; 4715 if (close) 4716 XMLElementEnd(s, 0, name); 4717 } 4718 4719 void 4720 XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL) 4721 { 4722 if (value) 4723 { 4724 if (default_value && strcmp(value, default_value) == 0) 4725 return; // No need to emit the attribute because it matches the default value 4726 s <<' ' << name << "=\"" << value << "\""; 4727 } 4728 } 4729 4730 void 4731 XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value) 4732 { 4733 s <<' ' << name << "=\"" << DECIMAL << value << "\""; 4734 } 4735 4736 void 4737 GenerateTargetXMLRegister (std::ostringstream &s, 4738 const uint32_t reg_num, 4739 nub_size_t num_reg_sets, 4740 const DNBRegisterSetInfo *reg_set_info, 4741 const register_map_entry_t ®) 4742 { 4743 const char *default_lldb_encoding = "uint"; 4744 const char *lldb_encoding = default_lldb_encoding; 4745 const char *gdb_group = "general"; 4746 const char *default_gdb_type = "int"; 4747 const char *gdb_type = default_gdb_type; 4748 const char *default_lldb_format = "hex"; 4749 const char *lldb_format = default_lldb_format; 4750 const char *lldb_set = NULL; 4751 4752 switch (reg.nub_info.type) 4753 { 4754 case Uint: lldb_encoding = "uint"; break; 4755 case Sint: lldb_encoding = "sint"; break; 4756 case IEEE754: lldb_encoding = "ieee754"; if (reg.nub_info.set > 0) gdb_group = "float"; break; 4757 case Vector: lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break; 4758 } 4759 4760 switch (reg.nub_info.format) 4761 { 4762 case Binary: lldb_format = "binary"; break; 4763 case Decimal: lldb_format = "decimal"; break; 4764 case Hex: lldb_format = "hex"; break; 4765 case Float: gdb_type = "float"; lldb_format = "float"; break; 4766 case VectorOfSInt8: gdb_type = "float"; lldb_format = "vector-sint8"; break; 4767 case VectorOfUInt8: gdb_type = "float"; lldb_format = "vector-uint8"; break; 4768 case VectorOfSInt16: gdb_type = "float"; lldb_format = "vector-sint16"; break; 4769 case VectorOfUInt16: gdb_type = "float"; lldb_format = "vector-uint16"; break; 4770 case VectorOfSInt32: gdb_type = "float"; lldb_format = "vector-sint32"; break; 4771 case VectorOfUInt32: gdb_type = "float"; lldb_format = "vector-uint32"; break; 4772 case VectorOfFloat32: gdb_type = "float"; lldb_format = "vector-float32"; break; 4773 case VectorOfUInt128: gdb_type = "float"; lldb_format = "vector-uint128"; break; 4774 }; 4775 if (reg_set_info && reg.nub_info.set < num_reg_sets) 4776 lldb_set = reg_set_info[reg.nub_info.set].name; 4777 4778 uint32_t indent = 2; 4779 4780 XMLElementStart(s, indent, "reg", true); 4781 XMLAttributeString(s, "name", reg.nub_info.name); 4782 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 4783 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 4784 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 4785 XMLAttributeString(s, "group", gdb_group); 4786 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 4787 XMLAttributeString (s, "altname", reg.nub_info.alt); 4788 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 4789 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 4790 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 4791 if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM) 4792 XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe); 4793 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 4794 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 4795 4796 const char *lldb_generic = NULL; 4797 switch (reg.nub_info.reg_generic) 4798 { 4799 case GENERIC_REGNUM_FP: lldb_generic = "fp"; break; 4800 case GENERIC_REGNUM_PC: lldb_generic = "pc"; break; 4801 case GENERIC_REGNUM_SP: lldb_generic = "sp"; break; 4802 case GENERIC_REGNUM_RA: lldb_generic = "ra"; break; 4803 case GENERIC_REGNUM_FLAGS: lldb_generic = "flags"; break; 4804 case GENERIC_REGNUM_ARG1: lldb_generic = "arg1"; break; 4805 case GENERIC_REGNUM_ARG2: lldb_generic = "arg2"; break; 4806 case GENERIC_REGNUM_ARG3: lldb_generic = "arg3"; break; 4807 case GENERIC_REGNUM_ARG4: lldb_generic = "arg4"; break; 4808 case GENERIC_REGNUM_ARG5: lldb_generic = "arg5"; break; 4809 case GENERIC_REGNUM_ARG6: lldb_generic = "arg6"; break; 4810 case GENERIC_REGNUM_ARG7: lldb_generic = "arg7"; break; 4811 case GENERIC_REGNUM_ARG8: lldb_generic = "arg8"; break; 4812 default: break; 4813 } 4814 XMLAttributeString(s, "generic", lldb_generic); 4815 4816 4817 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 4818 if (!empty) 4819 { 4820 if (!reg.value_regnums.empty()) 4821 { 4822 std::ostringstream regnums; 4823 bool first = true; 4824 regnums << DECIMAL; 4825 for (auto regnum : reg.value_regnums) 4826 { 4827 if (!first) 4828 regnums << ','; 4829 regnums << regnum; 4830 first = false; 4831 } 4832 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 4833 } 4834 4835 if (!reg.invalidate_regnums.empty()) 4836 { 4837 std::ostringstream regnums; 4838 bool first = true; 4839 regnums << DECIMAL; 4840 for (auto regnum : reg.invalidate_regnums) 4841 { 4842 if (!first) 4843 regnums << ','; 4844 regnums << regnum; 4845 first = false; 4846 } 4847 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 4848 } 4849 } 4850 XMLElementStartEndAttributes(s, true); 4851 } 4852 4853 void 4854 GenerateTargetXMLRegisters (std::ostringstream &s) 4855 { 4856 nub_size_t num_reg_sets = 0; 4857 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets); 4858 4859 4860 uint32_t cputype = DNBGetRegisterCPUType(); 4861 if (cputype) 4862 { 4863 XMLElementStart(s, 0, "feature", true); 4864 std::ostringstream name_strm; 4865 name_strm << "com.apple.debugserver." << GetArchName (cputype, 0); 4866 XMLAttributeString(s, "name", name_strm.str().c_str()); 4867 XMLElementStartEndAttributes(s, false); 4868 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 4869 // for (const auto ®: g_dynamic_register_map) 4870 { 4871 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]); 4872 } 4873 XMLElementEnd(s, 0, "feature"); 4874 4875 if (num_reg_sets > 0) 4876 { 4877 XMLElementStart(s, 0, "groups", false); 4878 for (uint32_t set=1; set<num_reg_sets; ++set) 4879 { 4880 XMLElementStart(s, 2, "group", true); 4881 XMLAttributeUnsignedDecimal(s, "id", set); 4882 XMLAttributeString(s, "name", reg_sets[set].name); 4883 XMLElementStartEndAttributes(s, true); 4884 } 4885 XMLElementEnd(s, 0, "groups"); 4886 } 4887 } 4888 } 4889 4890 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 4891 <target version="1.0">)"; 4892 4893 static const char *g_target_xml_footer = "</target>"; 4894 4895 static std::string g_target_xml; 4896 4897 void 4898 UpdateTargetXML () 4899 { 4900 std::ostringstream s; 4901 s << g_target_xml_header << std::endl; 4902 4903 // Set the architecture 4904 //s << "<architecture>" << arch "</architecture>" << std::endl; 4905 4906 // Set the OSABI 4907 //s << "<osabi>abi-name</osabi>" 4908 4909 GenerateTargetXMLRegisters(s); 4910 4911 s << g_target_xml_footer << std::endl; 4912 4913 // Save the XML output in case it gets retrieved in chunks 4914 g_target_xml = s.str(); 4915 } 4916 4917 rnb_err_t 4918 RNBRemote::HandlePacket_qXfer (const char *command) 4919 { 4920 const char *p = command; 4921 p += strlen ("qXfer:"); 4922 const char *sep = strchr(p, ':'); 4923 if (sep) 4924 { 4925 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 4926 p = sep + 1; 4927 sep = strchr(p, ':'); 4928 if (sep) 4929 { 4930 std::string rw(p, sep - p); // "read" or "write" 4931 p = sep + 1; 4932 sep = strchr(p, ':'); 4933 if (sep) 4934 { 4935 std::string annex(p, sep - p); // "read" or "write" 4936 4937 p = sep + 1; 4938 sep = strchr(p, ','); 4939 if (sep) 4940 { 4941 std::string offset_str(p, sep - p); // read the length as a string 4942 p = sep + 1; 4943 std::string length_str(p); // read the offset as a string 4944 char *end = nullptr; 4945 const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset 4946 if (*end == '\0') 4947 { 4948 const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length 4949 if (*end == '\0') 4950 { 4951 if (object == "features" && 4952 rw == "read" && 4953 annex == "target.xml") 4954 { 4955 std::ostringstream xml_out; 4956 4957 if (offset == 0) 4958 { 4959 InitializeRegisters (true); 4960 4961 UpdateTargetXML(); 4962 if (g_target_xml.empty()) 4963 return SendPacket("E83"); 4964 4965 if (length > g_target_xml.size()) 4966 { 4967 xml_out << 'l'; // No more data 4968 xml_out << binary_encode_string(g_target_xml); 4969 } 4970 else 4971 { 4972 xml_out << 'm'; // More data needs to be read with a subsequent call 4973 xml_out << binary_encode_string(std::string(g_target_xml, offset, length)); 4974 } 4975 } 4976 else 4977 { 4978 // Retrieving target XML in chunks 4979 if (offset < g_target_xml.size()) 4980 { 4981 std::string chunk(g_target_xml, offset, length); 4982 if (chunk.size() < length) 4983 xml_out << 'l'; // No more data 4984 else 4985 xml_out << 'm'; // More data needs to be read with a subsequent call 4986 xml_out << binary_encode_string(chunk.data()); 4987 } 4988 } 4989 return SendPacket(xml_out.str()); 4990 } 4991 // Well formed, put not supported 4992 return HandlePacket_UNIMPLEMENTED (command); 4993 } 4994 } 4995 } 4996 } 4997 else 4998 { 4999 SendPacket ("E85"); 5000 } 5001 } 5002 else 5003 { 5004 SendPacket ("E86"); 5005 } 5006 } 5007 return SendPacket ("E82"); 5008 } 5009 5010 5011 rnb_err_t 5012 RNBRemote::HandlePacket_qGDBServerVersion (const char *p) 5013 { 5014 std::ostringstream strm; 5015 5016 #if defined(DEBUGSERVER_PROGRAM_NAME) 5017 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 5018 #else 5019 strm << "name:debugserver;"; 5020 #endif 5021 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 5022 5023 return SendPacket (strm.str()); 5024 } 5025 5026 // A helper function that retrieves a single integer value from 5027 // a one-level-deep JSON dictionary of key-value pairs. e.g. 5028 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 5029 // 5030 uint64_t 5031 get_integer_value_for_key_name_from_json (const char *key, const char *json_string) 5032 { 5033 uint64_t retval = INVALID_NUB_ADDRESS; 5034 std::string key_with_quotes = "\""; 5035 key_with_quotes += key; 5036 key_with_quotes += "\""; 5037 const char *c = strstr (json_string, key_with_quotes.c_str()); 5038 if (c) 5039 { 5040 c += key_with_quotes.size(); 5041 5042 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5043 c++; 5044 5045 if (*c == ':') 5046 { 5047 c++; 5048 5049 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 5050 c++; 5051 5052 errno = 0; 5053 retval = strtoul (c, NULL, 10); 5054 if (errno != 0) 5055 { 5056 retval = INVALID_NUB_ADDRESS; 5057 } 5058 } 5059 } 5060 return retval; 5061 5062 } 5063 5064 JSONGenerator::ObjectSP 5065 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) 5066 { 5067 JSONGenerator::ArraySP threads_array_sp; 5068 if (m_ctx.HasValidProcessID()) 5069 { 5070 threads_array_sp.reset(new JSONGenerator::Array()); 5071 5072 nub_process_t pid = m_ctx.ProcessID(); 5073 5074 nub_size_t numthreads = DNBProcessGetNumThreads (pid); 5075 for (nub_size_t i = 0; i < numthreads; ++i) 5076 { 5077 nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i); 5078 5079 struct DNBThreadStopInfo tid_stop_info; 5080 5081 const bool stop_info_valid = DNBThreadGetStopReason (pid, tid, &tid_stop_info); 5082 5083 // If we are doing stop info only, then we only show threads that have a 5084 // valid stop reason 5085 if (threads_with_valid_stop_info_only) 5086 { 5087 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5088 continue; 5089 } 5090 5091 JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary()); 5092 thread_dict_sp->AddIntegerItem("tid", tid); 5093 5094 std::string reason_value("none"); 5095 5096 if (stop_info_valid) 5097 { 5098 switch (tid_stop_info.reason) 5099 { 5100 case eStopTypeInvalid: 5101 break; 5102 5103 case eStopTypeSignal: 5104 if (tid_stop_info.details.signal.signo != 0) 5105 { 5106 thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo); 5107 reason_value = "signal"; 5108 } 5109 break; 5110 5111 case eStopTypeException: 5112 if (tid_stop_info.details.exception.type != 0) 5113 { 5114 reason_value = "exception"; 5115 thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type); 5116 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5117 for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i) 5118 { 5119 medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i]))); 5120 } 5121 thread_dict_sp->AddItem("medata", medata_array_sp); 5122 } 5123 break; 5124 5125 case eStopTypeExec: 5126 reason_value = "exec"; 5127 break; 5128 } 5129 } 5130 5131 thread_dict_sp->AddStringItem("reason", reason_value); 5132 5133 if (threads_with_valid_stop_info_only == false) 5134 { 5135 const char *thread_name = DNBThreadGetName (pid, tid); 5136 if (thread_name && thread_name[0]) 5137 thread_dict_sp->AddStringItem("name", thread_name); 5138 5139 thread_identifier_info_data_t thread_ident_info; 5140 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 5141 { 5142 if (thread_ident_info.dispatch_qaddr != 0) 5143 { 5144 thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr); 5145 5146 const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets(); 5147 if (dispatch_queue_offsets) 5148 { 5149 std::string queue_name; 5150 uint64_t queue_width = 0; 5151 uint64_t queue_serialnum = 0; 5152 nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS; 5153 dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, queue_name, queue_width, queue_serialnum); 5154 if (dispatch_queue_t == 0 && queue_name.empty() && queue_serialnum == 0) 5155 { 5156 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", false); 5157 } 5158 else 5159 { 5160 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", true); 5161 } 5162 if (dispatch_queue_t != INVALID_NUB_ADDRESS && dispatch_queue_t != 0) 5163 thread_dict_sp->AddIntegerItem("dispatch_queue_t", dispatch_queue_t); 5164 if (!queue_name.empty()) 5165 thread_dict_sp->AddStringItem("qname", queue_name); 5166 if (queue_width == 1) 5167 thread_dict_sp->AddStringItem("qkind", "serial"); 5168 else if (queue_width > 1) 5169 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5170 if (queue_serialnum > 0) 5171 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum); 5172 } 5173 } 5174 } 5175 5176 DNBRegisterValue reg_value; 5177 5178 if (g_reg_entries != NULL) 5179 { 5180 JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary()); 5181 5182 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 5183 { 5184 // Expedite all registers in the first register set that aren't 5185 // contained in other registers 5186 if (g_reg_entries[reg].nub_info.set == 1 && 5187 g_reg_entries[reg].nub_info.value_regs == NULL) 5188 { 5189 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 5190 continue; 5191 5192 std::ostringstream reg_num; 5193 reg_num << std::dec << g_reg_entries[reg].debugserver_regnum; 5194 // Encode native byte ordered bytes as hex ascii 5195 registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size); 5196 } 5197 } 5198 thread_dict_sp->AddItem("registers", registers_dict_sp); 5199 } 5200 5201 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 5202 // frame pointer chain. 5203 StackMemoryMap stack_mmap; 5204 ReadStackMemory (pid, tid, stack_mmap); 5205 if (!stack_mmap.empty()) 5206 { 5207 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5208 5209 for (const auto &stack_memory : stack_mmap) 5210 { 5211 JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary()); 5212 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5213 stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length); 5214 memory_array_sp->AddItem(stack_memory_sp); 5215 } 5216 thread_dict_sp->AddItem("memory", memory_array_sp); 5217 } 5218 } 5219 5220 threads_array_sp->AddItem(thread_dict_sp); 5221 } 5222 } 5223 return threads_array_sp; 5224 } 5225 5226 rnb_err_t 5227 RNBRemote::HandlePacket_jThreadsInfo (const char *p) 5228 { 5229 JSONGenerator::ObjectSP threads_info_sp; 5230 std::ostringstream json; 5231 std::ostringstream reply_strm; 5232 // If we haven't run the process yet, return an error. 5233 if (m_ctx.HasValidProcessID()) 5234 { 5235 const bool threads_with_valid_stop_info_only = false; 5236 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5237 5238 if (threads_info_sp) 5239 { 5240 std::ostringstream strm; 5241 threads_info_sp->Dump (strm); 5242 std::string binary_packet = binary_encode_string (strm.str()); 5243 if (!binary_packet.empty()) 5244 return SendPacket (binary_packet.c_str()); 5245 } 5246 } 5247 return SendPacket ("E85"); 5248 5249 } 5250 5251 rnb_err_t 5252 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) 5253 { 5254 nub_process_t pid; 5255 std::ostringstream json; 5256 // If we haven't run the process yet, return an error. 5257 if (!m_ctx.HasValidProcessID()) 5258 { 5259 return SendPacket ("E81"); 5260 } 5261 5262 pid = m_ctx.ProcessID(); 5263 5264 const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" }; 5265 if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0) 5266 { 5267 p += strlen (thread_extended_info_str); 5268 5269 uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p); 5270 uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p); 5271 uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p); 5272 uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p); 5273 uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p); 5274 // Commented out the two variables below as they are not being used 5275 // uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p); 5276 // uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p); 5277 5278 if (tid != INVALID_NUB_ADDRESS) 5279 { 5280 nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid); 5281 5282 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5283 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS 5284 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS 5285 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) 5286 { 5287 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5288 } 5289 5290 bool timed_out = false; 5291 Genealogy::ThreadActivitySP thread_activity_sp; 5292 5293 // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base 5294 // and got an invalid value back, then we have a thread in early startup or shutdown and 5295 // it's possible that gathering the genealogy information for this thread go badly. 5296 // Ideally fetching this info for a thread in these odd states shouldn't matter - but 5297 // we've seen some problems with these new SPI and threads in edge-casey states. 5298 5299 double genealogy_fetch_time = 0; 5300 if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS) 5301 { 5302 DNBTimer timer(false); 5303 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out); 5304 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5305 } 5306 5307 std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen 5308 5309 json << "{"; 5310 5311 bool need_to_print_comma = false; 5312 5313 if (thread_activity_sp && timed_out == false) 5314 { 5315 const Genealogy::Activity *activity = &thread_activity_sp->current_activity; 5316 bool need_vouchers_comma_sep = false; 5317 json << "\"activity_query_timed_out\":false,"; 5318 if (genealogy_fetch_time != 0) 5319 { 5320 // If we append the floating point value with << we'll get it in scientific 5321 // notation. 5322 char floating_point_ascii_buffer[64]; 5323 floating_point_ascii_buffer[0] = '\0'; 5324 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5325 if (strlen (floating_point_ascii_buffer) > 0) 5326 { 5327 if (need_to_print_comma) 5328 json << ","; 5329 need_to_print_comma = true; 5330 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5331 } 5332 } 5333 if (activity->activity_id != 0) 5334 { 5335 if (need_to_print_comma) 5336 json << ","; 5337 need_to_print_comma = true; 5338 need_vouchers_comma_sep = true; 5339 json << "\"activity\":{"; 5340 json << "\"start\":" << activity->activity_start << ","; 5341 json << "\"id\":" << activity->activity_id << ","; 5342 json << "\"parent_id\":" << activity->parent_id << ","; 5343 json << "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\","; 5344 json << "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\""; 5345 json << "}"; 5346 } 5347 if (thread_activity_sp->messages.size() > 0) 5348 { 5349 need_to_print_comma = true; 5350 if (need_vouchers_comma_sep) 5351 json << ","; 5352 need_vouchers_comma_sep = true; 5353 json << "\"trace_messages\":["; 5354 bool printed_one_message = false; 5355 for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter) 5356 { 5357 if (printed_one_message) 5358 json << ","; 5359 else 5360 printed_one_message = true; 5361 json << "{"; 5362 json << "\"timestamp\":" << iter->timestamp << ","; 5363 json << "\"activity_id\":" << iter->activity_id << ","; 5364 json << "\"trace_id\":" << iter->trace_id << ","; 5365 json << "\"thread\":" << iter->thread << ","; 5366 json << "\"type\":" << (int) iter->type << ","; 5367 json << "\"process_info_index\":" << iter->process_info_index << ","; 5368 process_info_indexes.insert (iter->process_info_index); 5369 json << "\"message\":\"" << json_string_quote_metachars (iter->message) << "\""; 5370 json << "}"; 5371 } 5372 json << "]"; 5373 } 5374 if (thread_activity_sp->breadcrumbs.size() == 1) 5375 { 5376 need_to_print_comma = true; 5377 if (need_vouchers_comma_sep) 5378 json << ","; 5379 need_vouchers_comma_sep = true; 5380 json << "\"breadcrumb\":{"; 5381 for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter) 5382 { 5383 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5384 json << "\"activity_id\":" << iter->activity_id << ","; 5385 json << "\"timestamp\":" << iter->timestamp << ","; 5386 json << "\"name\":\"" << json_string_quote_metachars (iter->name) << "\""; 5387 } 5388 json << "}"; 5389 } 5390 if (process_info_indexes.size() > 0) 5391 { 5392 need_to_print_comma = true; 5393 if (need_vouchers_comma_sep) 5394 json << ","; 5395 need_vouchers_comma_sep = true; 5396 json << "\"process_infos\":["; 5397 bool printed_one_process_info = false; 5398 for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter) 5399 { 5400 if (printed_one_process_info) 5401 json << ","; 5402 else 5403 printed_one_process_info = true; 5404 Genealogy::ProcessExecutableInfoSP image_info_sp; 5405 uint32_t idx = *iter; 5406 image_info_sp = DNBGetGenealogyImageInfo (pid, idx); 5407 json << "{"; 5408 char uuid_buf[37]; 5409 uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf); 5410 json << "\"process_info_index\":" << idx << ","; 5411 json << "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\","; 5412 json << "\"image_uuid\":\"" << uuid_buf <<"\""; 5413 json << "}"; 5414 } 5415 json << "]"; 5416 } 5417 } 5418 else 5419 { 5420 if (timed_out) 5421 { 5422 if (need_to_print_comma) 5423 json << ","; 5424 need_to_print_comma = true; 5425 json << "\"activity_query_timed_out\":true"; 5426 if (genealogy_fetch_time != 0) 5427 { 5428 // If we append the floating point value with << we'll get it in scientific 5429 // notation. 5430 char floating_point_ascii_buffer[64]; 5431 floating_point_ascii_buffer[0] = '\0'; 5432 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5433 if (strlen (floating_point_ascii_buffer) > 0) 5434 { 5435 json << ","; 5436 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5437 } 5438 } 5439 } 5440 } 5441 5442 if (tsd_address != INVALID_NUB_ADDRESS) 5443 { 5444 if (need_to_print_comma) 5445 json << ","; 5446 need_to_print_comma = true; 5447 json << "\"tsd_address\":" << tsd_address; 5448 5449 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) 5450 { 5451 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index); 5452 if (requested_qos.IsValid()) 5453 { 5454 if (need_to_print_comma) 5455 json << ","; 5456 need_to_print_comma = true; 5457 json << "\"requested_qos\":{"; 5458 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5459 json << "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\","; 5460 json << "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\""; 5461 json << "}"; 5462 } 5463 } 5464 } 5465 5466 if (pthread_t_value != INVALID_NUB_ADDRESS) 5467 { 5468 if (need_to_print_comma) 5469 json << ","; 5470 need_to_print_comma = true; 5471 json << "\"pthread_t\":" << pthread_t_value; 5472 } 5473 5474 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid); 5475 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) 5476 { 5477 if (need_to_print_comma) 5478 json << ","; 5479 need_to_print_comma = true; 5480 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5481 } 5482 5483 json << "}"; 5484 std::string json_quoted = binary_encode_string (json.str()); 5485 return SendPacket (json_quoted); 5486 } 5487 } 5488 return SendPacket ("OK"); 5489 } 5490 5491 rnb_err_t 5492 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p) 5493 { 5494 nub_process_t pid; 5495 // If we haven't run the process yet, return an error. 5496 if (!m_ctx.HasValidProcessID()) 5497 { 5498 return SendPacket ("E83"); 5499 } 5500 5501 pid = m_ctx.ProcessID(); 5502 5503 const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" }; 5504 if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0) 5505 { 5506 p += strlen (get_loaded_dynamic_libraries_infos_str); 5507 5508 nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p); 5509 nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p); 5510 5511 if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS) 5512 { 5513 JSONGenerator::ObjectSP json_sp; 5514 5515 json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count); 5516 5517 if (json_sp.get()) 5518 { 5519 std::ostringstream json_str; 5520 json_sp->Dump (json_str); 5521 if (json_str.str().size() > 0) 5522 { 5523 std::string json_str_quoted = binary_encode_string (json_str.str()); 5524 return SendPacket (json_str_quoted.c_str()); 5525 } 5526 else 5527 { 5528 SendPacket ("E84"); 5529 } 5530 } 5531 } 5532 } 5533 return SendPacket ("OK"); 5534 } 5535 5536 static bool 5537 MachHeaderIsMainExecutable (nub_process_t pid, uint32_t addr_size, nub_addr_t mach_header_addr, mach_header &mh) 5538 { 5539 DNBLogThreadedIf (LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = %u, mach_header_addr = 0x%16.16llx)", pid, addr_size, mach_header_addr); 5540 const nub_size_t bytes_read = DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh); 5541 if (bytes_read == sizeof(mh)) 5542 { 5543 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); 5544 if ((addr_size == 4 && mh.magic == MH_MAGIC) || 5545 (addr_size == 8 && mh.magic == MH_MAGIC_64)) 5546 { 5547 if (mh.filetype == MH_EXECUTE) 5548 { 5549 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); 5550 return true; 5551 } 5552 } 5553 } 5554 return false; 5555 } 5556 5557 static nub_addr_t 5558 GetMachHeaderForMainExecutable (const nub_process_t pid, const uint32_t addr_size, mach_header &mh) 5559 { 5560 struct AllImageInfos 5561 { 5562 uint32_t version; 5563 uint32_t dylib_info_count; 5564 uint64_t dylib_info_addr; 5565 }; 5566 5567 uint64_t mach_header_addr = 0; 5568 5569 const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress (pid); 5570 uint8_t bytes[256]; 5571 nub_size_t bytes_read = 0; 5572 DNBDataRef data (bytes, sizeof(bytes), false); 5573 DNBDataRef::offset_t offset = 0; 5574 data.SetPointerSize(addr_size); 5575 5576 //---------------------------------------------------------------------- 5577 // When we are sitting at __dyld_start, the kernel has placed the 5578 // address of the mach header of the main executable on the stack. If we 5579 // read the SP and dereference a pointer, we might find the mach header 5580 // for the executable. We also just make sure there is only 1 thread 5581 // since if we are at __dyld_start we shouldn't have multiple threads. 5582 //---------------------------------------------------------------------- 5583 if (DNBProcessGetNumThreads(pid) == 1) 5584 { 5585 nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0); 5586 if (tid != INVALID_NUB_THREAD) 5587 { 5588 DNBRegisterValue sp_value; 5589 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_SP, &sp_value)) 5590 { 5591 uint64_t sp = addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32; 5592 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes); 5593 if (bytes_read == addr_size) 5594 { 5595 offset = 0; 5596 mach_header_addr = data.GetPointer(&offset); 5597 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5598 return mach_header_addr; 5599 } 5600 } 5601 } 5602 } 5603 5604 //---------------------------------------------------------------------- 5605 // Check the dyld_all_image_info structure for a list of mach header 5606 // since it is a very easy thing to check 5607 //---------------------------------------------------------------------- 5608 if (shlib_addr != INVALID_NUB_ADDRESS) 5609 { 5610 bytes_read = DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes); 5611 if (bytes_read > 0) 5612 { 5613 AllImageInfos aii; 5614 offset = 0; 5615 aii.version = data.Get32(&offset); 5616 aii.dylib_info_count = data.Get32(&offset); 5617 if (aii.dylib_info_count > 0) 5618 { 5619 aii.dylib_info_addr = data.GetPointer(&offset); 5620 if (aii.dylib_info_addr != 0) 5621 { 5622 const size_t image_info_byte_size = 3 * addr_size; 5623 for (uint32_t i=0; i<aii.dylib_info_count; ++i) 5624 { 5625 bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + i * image_info_byte_size, image_info_byte_size, bytes); 5626 if (bytes_read != image_info_byte_size) 5627 break; 5628 offset = 0; 5629 mach_header_addr = data.GetPointer(&offset); 5630 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5631 return mach_header_addr; 5632 } 5633 } 5634 } 5635 } 5636 } 5637 5638 //---------------------------------------------------------------------- 5639 // We failed to find the executable's mach header from the all image 5640 // infos and by dereferencing the stack pointer. Now we fall back to 5641 // enumerating the memory regions and looking for regions that are 5642 // executable. 5643 //---------------------------------------------------------------------- 5644 DNBRegionInfo region_info; 5645 mach_header_addr = 0; 5646 while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, ®ion_info)) 5647 { 5648 if (region_info.size == 0) 5649 break; 5650 5651 if (region_info.permissions & eMemoryPermissionsExecutable) 5652 { 5653 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' : '-'); 5654 if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh)) 5655 return mach_header_addr; 5656 } 5657 else 5658 { 5659 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' : '-'); 5660 } 5661 // Set the address to the next mapped region 5662 mach_header_addr = region_info.addr + region_info.size; 5663 } 5664 bzero (&mh, sizeof(mh)); 5665 return INVALID_NUB_ADDRESS; 5666 } 5667 5668 rnb_err_t 5669 RNBRemote::HandlePacket_qSymbol (const char *command) 5670 { 5671 const char *p = command; 5672 p += strlen ("qSymbol:"); 5673 const char *sep = strchr(p, ':'); 5674 5675 std::string symbol_name; 5676 std::string symbol_value_str; 5677 // Extract the symbol value if there is one 5678 if (sep > p) 5679 symbol_value_str.assign(p, sep - p); 5680 p = sep + 1; 5681 5682 if (*p) 5683 { 5684 // We have a symbol name 5685 symbol_name = decode_hex_ascii_string(p); 5686 if (!symbol_value_str.empty()) 5687 { 5688 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5689 if (symbol_name == "dispatch_queue_offsets") 5690 m_dispatch_queue_offsets_addr = symbol_value; 5691 } 5692 ++m_qSymbol_index; 5693 } 5694 else 5695 { 5696 // No symbol name, set our symbol index to zero so we can 5697 // read any symbols that we need 5698 m_qSymbol_index = 0; 5699 } 5700 5701 symbol_name.clear(); 5702 5703 if (m_qSymbol_index == 0) 5704 { 5705 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5706 symbol_name = "dispatch_queue_offsets"; 5707 else 5708 ++m_qSymbol_index; 5709 } 5710 5711 // // Lookup next symbol when we have one... 5712 // if (m_qSymbol_index == 1) 5713 // { 5714 // } 5715 5716 5717 if (symbol_name.empty()) 5718 { 5719 // Done with symbol lookups 5720 return SendPacket ("OK"); 5721 } 5722 else 5723 { 5724 std::ostringstream reply; 5725 reply << "qSymbol:"; 5726 for (size_t i = 0; i < symbol_name.size(); ++i) 5727 reply << RAWHEX8(symbol_name[i]); 5728 return SendPacket (reply.str().c_str()); 5729 } 5730 } 5731 5732 // Note that all numeric values returned by qProcessInfo are hex encoded, 5733 // including the pid and the cpu type. 5734 5735 rnb_err_t 5736 RNBRemote::HandlePacket_qProcessInfo (const char *p) 5737 { 5738 nub_process_t pid; 5739 std::ostringstream rep; 5740 5741 // If we haven't run the process yet, return an error. 5742 if (!m_ctx.HasValidProcessID()) 5743 return SendPacket ("E68"); 5744 5745 pid = m_ctx.ProcessID(); 5746 5747 rep << "pid:" << std::hex << pid << ';'; 5748 5749 int procpid_mib[4]; 5750 procpid_mib[0] = CTL_KERN; 5751 procpid_mib[1] = KERN_PROC; 5752 procpid_mib[2] = KERN_PROC_PID; 5753 procpid_mib[3] = pid; 5754 struct kinfo_proc proc_kinfo; 5755 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 5756 5757 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 5758 { 5759 if (proc_kinfo_size > 0) 5760 { 5761 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';'; 5762 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ';'; 5763 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ';'; 5764 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ';'; 5765 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 5766 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';'; 5767 } 5768 } 5769 5770 cpu_type_t cputype = DNBProcessGetCPUType (pid); 5771 if (cputype == 0) 5772 { 5773 DNBLog ("Unable to get the process cpu_type, making a best guess."); 5774 cputype = best_guess_cpu_type(); 5775 } 5776 5777 uint32_t addr_size = 0; 5778 if (cputype != 0) 5779 { 5780 rep << "cputype:" << std::hex << cputype << ";"; 5781 if (cputype & CPU_ARCH_ABI64) 5782 addr_size = 8; 5783 else 5784 addr_size = 4; 5785 } 5786 5787 bool host_cpu_is_64bit = false; 5788 uint32_t is64bit_capable; 5789 size_t is64bit_capable_len = sizeof (is64bit_capable); 5790 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0) 5791 host_cpu_is_64bit = is64bit_capable != 0; 5792 5793 uint32_t cpusubtype; 5794 size_t cpusubtype_len = sizeof(cpusubtype); 5795 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 5796 { 5797 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 5798 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 5799 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype 5800 // for i386... 5801 if (host_cpu_is_64bit) 5802 { 5803 if (cputype == CPU_TYPE_X86) 5804 { 5805 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 5806 } 5807 else if (cputype == CPU_TYPE_ARM) 5808 { 5809 // We can query a process' cputype but we cannot query a process' cpusubtype. 5810 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we 5811 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace) 5812 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 5813 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S 5814 } 5815 } 5816 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 5817 } 5818 5819 bool os_handled = false; 5820 if (addr_size > 0) 5821 { 5822 rep << "ptrsize:" << std::dec << addr_size << ';'; 5823 5824 #if (defined (__x86_64__) || defined (__i386__)) 5825 // Try and get the OS type by looking at the load commands in the main 5826 // executable and looking for a LC_VERSION_MIN load command. This is the 5827 // most reliable way to determine the "ostype" value when on desktop. 5828 5829 mach_header mh; 5830 nub_addr_t exe_mach_header_addr = GetMachHeaderForMainExecutable (pid, addr_size, mh); 5831 if (exe_mach_header_addr != INVALID_NUB_ADDRESS) 5832 { 5833 uint64_t load_command_addr = exe_mach_header_addr + ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header)); 5834 load_command lc; 5835 for (uint32_t i=0; i<mh.ncmds && !os_handled; ++i) 5836 { 5837 const nub_size_t bytes_read = DNBProcessMemoryRead (pid, load_command_addr, sizeof(lc), &lc); 5838 uint32_t raw_cmd = lc.cmd & ~LC_REQ_DYLD; 5839 if (bytes_read != sizeof(lc)) 5840 break; 5841 switch (raw_cmd) 5842 { 5843 case LC_VERSION_MIN_IPHONEOS: 5844 os_handled = true; 5845 rep << "ostype:ios;"; 5846 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_IPHONEOS -> 'ostype:ios;'"); 5847 break; 5848 5849 case LC_VERSION_MIN_MACOSX: 5850 os_handled = true; 5851 rep << "ostype:macosx;"; 5852 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'"); 5853 break; 5854 5855 #if defined (LC_VERSION_MIN_TVOS) 5856 case LC_VERSION_MIN_TVOS: 5857 os_handled = true; 5858 rep << "ostype:tvos;"; 5859 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_TVOS -> 'ostype:tvos;'"); 5860 break; 5861 #endif 5862 5863 #if defined (LC_VERSION_MIN_WATCHOS) 5864 case LC_VERSION_MIN_WATCHOS: 5865 os_handled = true; 5866 rep << "ostype:watchos;"; 5867 DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_WATCHOS -> 'ostype:watchos;'"); 5868 break; 5869 #endif 5870 5871 default: 5872 break; 5873 } 5874 load_command_addr = load_command_addr + lc.cmdsize; 5875 } 5876 } 5877 #endif 5878 } 5879 5880 // If we weren't able to find the OS in a LC_VERSION_MIN load command, try 5881 // to set it correctly by using the cpu type and other tricks 5882 if (!os_handled) 5883 { 5884 // The OS in the triple should be "ios" or "macosx" which doesn't match our 5885 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 5886 // this for now. 5887 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 5888 { 5889 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 5890 rep << "ostype:tvos;"; 5891 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 5892 rep << "ostype:watchos;"; 5893 #else 5894 rep << "ostype:ios;"; 5895 #endif 5896 } 5897 else 5898 { 5899 bool is_ios_simulator = false; 5900 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) 5901 { 5902 // Check for iOS simulator binaries by getting the process argument 5903 // and environment and checking for SIMULATOR_UDID in the environment 5904 int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid }; 5905 5906 uint8_t arg_data[8192]; 5907 size_t arg_data_size = sizeof(arg_data); 5908 if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) 5909 { 5910 DNBDataRef data (arg_data, arg_data_size, false); 5911 DNBDataRef::offset_t offset = 0; 5912 uint32_t argc = data.Get32 (&offset); 5913 const char *cstr; 5914 5915 cstr = data.GetCStr (&offset); 5916 if (cstr) 5917 { 5918 // Skip NULLs 5919 while (1) 5920 { 5921 const char *p = data.PeekCStr(offset); 5922 if ((p == NULL) || (*p != '\0')) 5923 break; 5924 ++offset; 5925 } 5926 // Now skip all arguments 5927 for (uint32_t i = 0; i < argc; ++i) 5928 { 5929 data.GetCStr(&offset); 5930 } 5931 5932 // Now iterate across all environment variables 5933 while ((cstr = data.GetCStr(&offset))) 5934 { 5935 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) 5936 { 5937 is_ios_simulator = true; 5938 break; 5939 } 5940 if (cstr[0] == '\0') 5941 break; 5942 5943 } 5944 } 5945 } 5946 } 5947 if (is_ios_simulator) 5948 { 5949 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 5950 rep << "ostype:tvos;"; 5951 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 5952 rep << "ostype:watchos;"; 5953 #else 5954 rep << "ostype:ios;"; 5955 #endif 5956 } 5957 else 5958 { 5959 rep << "ostype:macosx;"; 5960 } 5961 } 5962 } 5963 5964 rep << "vendor:apple;"; 5965 5966 #if defined (__LITTLE_ENDIAN__) 5967 rep << "endian:little;"; 5968 #elif defined (__BIG_ENDIAN__) 5969 rep << "endian:big;"; 5970 #elif defined (__PDP_ENDIAN__) 5971 rep << "endian:pdp;"; 5972 #endif 5973 5974 if (addr_size == 0) 5975 { 5976 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 5977 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5978 kern_return_t kr; 5979 x86_thread_state_t gp_regs; 5980 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 5981 kr = thread_get_state (static_cast<thread_act_t>(thread), 5982 x86_THREAD_STATE, 5983 (thread_state_t) &gp_regs, 5984 &gp_count); 5985 if (kr == KERN_SUCCESS) 5986 { 5987 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 5988 rep << "ptrsize:8;"; 5989 else 5990 rep << "ptrsize:4;"; 5991 } 5992 #elif defined (__arm__) 5993 rep << "ptrsize:4;"; 5994 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE) 5995 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5996 kern_return_t kr; 5997 arm_unified_thread_state_t gp_regs; 5998 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 5999 kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE, 6000 (thread_state_t) &gp_regs, &gp_count); 6001 if (kr == KERN_SUCCESS) 6002 { 6003 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 6004 rep << "ptrsize:8;"; 6005 else 6006 rep << "ptrsize:4;"; 6007 } 6008 #endif 6009 } 6010 6011 return SendPacket (rep.str()); 6012 } 6013 6014 const RNBRemote::DispatchQueueOffsets * 6015 RNBRemote::GetDispatchQueueOffsets() 6016 { 6017 if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID()) 6018 { 6019 nub_process_t pid = m_ctx.ProcessID(); 6020 nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets); 6021 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 6022 m_dispatch_queue_offsets.Clear(); 6023 } 6024 6025 if (m_dispatch_queue_offsets.IsValid()) 6026 return &m_dispatch_queue_offsets; 6027 else 6028 return nullptr; 6029 } 6030 6031 void 6032 RNBRemote::EnableCompressionNextSendPacket (compression_types type) 6033 { 6034 m_compression_mode = type; 6035 m_enable_compression_next_send_packet = true; 6036 } 6037 6038 compression_types 6039 RNBRemote::GetCompressionType () 6040 { 6041 // The first packet we send back to the debugger after a QEnableCompression request 6042 // should be uncompressed -- so we can indicate whether the compression was enabled 6043 // or not via OK / Enn returns. After that, all packets sent will be using the 6044 // compression protocol. 6045 6046 if (m_enable_compression_next_send_packet) 6047 { 6048 // One time, we send back "None" as our compression type 6049 m_enable_compression_next_send_packet = false; 6050 return compression_types::none; 6051 } 6052 return m_compression_mode; 6053 } 6054