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