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