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 2308 return result; 2309 } 2310 2311 2312 rnb_err_t 2313 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p) 2314 { 2315 /* The number of characters in a packet payload that gdb is 2316 prepared to accept. The packet-start char, packet-end char, 2317 2 checksum chars and terminating null character are not included 2318 in this size. */ 2319 p += sizeof ("QSetMaxPayloadSize:") - 1; 2320 errno = 0; 2321 uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16)); 2322 if (errno != 0 && size == 0) 2323 { 2324 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet"); 2325 } 2326 m_max_payload_size = size; 2327 return SendPacket ("OK"); 2328 } 2329 2330 rnb_err_t 2331 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p) 2332 { 2333 /* This tells us the largest packet that gdb can handle. 2334 i.e. the size of gdb's packet-reading buffer. 2335 QSetMaxPayloadSize is preferred because it is less ambiguous. */ 2336 p += sizeof ("QSetMaxPacketSize:") - 1; 2337 errno = 0; 2338 uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16)); 2339 if (errno != 0 && size == 0) 2340 { 2341 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet"); 2342 } 2343 m_max_payload_size = size - 5; 2344 return SendPacket ("OK"); 2345 } 2346 2347 2348 2349 2350 rnb_err_t 2351 RNBRemote::HandlePacket_QEnvironment (const char *p) 2352 { 2353 /* This sets the environment for the target program. The packet is of the form: 2354 2355 QEnvironment:VARIABLE=VALUE 2356 2357 */ 2358 2359 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"", 2360 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2361 2362 p += sizeof ("QEnvironment:") - 1; 2363 RNBContext& ctx = Context(); 2364 2365 ctx.PushEnvironment (p); 2366 return SendPacket ("OK"); 2367 } 2368 2369 rnb_err_t 2370 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p) 2371 { 2372 /* This sets the environment for the target program. The packet is of the form: 2373 2374 QEnvironmentHexEncoded:VARIABLE=VALUE 2375 2376 The VARIABLE=VALUE part is sent hex-encoded so characters like '#' with special 2377 meaning in the remote protocol won't break it. 2378 */ 2379 2380 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"", 2381 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2382 2383 p += sizeof ("QEnvironmentHexEncoded:") - 1; 2384 2385 std::string arg; 2386 const char *c; 2387 c = p; 2388 while (*c != '\0') 2389 { 2390 if (*(c + 1) == '\0') 2391 { 2392 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2393 } 2394 char smallbuf[3]; 2395 smallbuf[0] = *c; 2396 smallbuf[1] = *(c + 1); 2397 smallbuf[2] = '\0'; 2398 errno = 0; 2399 int ch = static_cast<int>(strtoul (smallbuf, NULL, 16)); 2400 if (errno != 0 && ch == 0) 2401 { 2402 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2403 } 2404 arg.push_back(ch); 2405 c += 2; 2406 } 2407 2408 RNBContext& ctx = Context(); 2409 if (arg.length() > 0) 2410 ctx.PushEnvironment (arg.c_str()); 2411 2412 return SendPacket ("OK"); 2413 } 2414 2415 2416 rnb_err_t 2417 RNBRemote::HandlePacket_QLaunchArch (const char *p) 2418 { 2419 p += sizeof ("QLaunchArch:") - 1; 2420 if (DNBSetArchitecture(p)) 2421 return SendPacket ("OK"); 2422 return SendPacket ("E63"); 2423 } 2424 2425 rnb_err_t 2426 RNBRemote::HandlePacket_QSetProcessEvent (const char *p) 2427 { 2428 p += sizeof ("QSetProcessEvent:") - 1; 2429 // If the process is running, then send the event to the process, otherwise 2430 // store it in the context. 2431 if (Context().HasValidProcessID()) 2432 { 2433 if (DNBProcessSendEvent (Context().ProcessID(), p)) 2434 return SendPacket("OK"); 2435 else 2436 return SendPacket ("E80"); 2437 } 2438 else 2439 { 2440 Context().PushProcessEvent(p); 2441 } 2442 return SendPacket ("OK"); 2443 } 2444 2445 void 2446 append_hex_value (std::ostream& ostrm, const void *buf, size_t buf_size, bool swap) 2447 { 2448 int i; 2449 const uint8_t *p = (const uint8_t *)buf; 2450 if (swap) 2451 { 2452 for (i = static_cast<int>(buf_size)-1; i >= 0; i--) 2453 ostrm << RAWHEX8(p[i]); 2454 } 2455 else 2456 { 2457 for (i = 0; i < buf_size; i++) 2458 ostrm << RAWHEX8(p[i]); 2459 } 2460 } 2461 2462 void 2463 append_hexified_string (std::ostream& ostrm, const std::string &string) 2464 { 2465 size_t string_size = string.size(); 2466 const char *string_buf = string.c_str(); 2467 for (size_t i = 0; i < string_size; i++) 2468 { 2469 ostrm << RAWHEX8(*(string_buf + i)); 2470 } 2471 } 2472 2473 2474 2475 void 2476 register_value_in_hex_fixed_width (std::ostream& ostrm, 2477 nub_process_t pid, 2478 nub_thread_t tid, 2479 const register_map_entry_t* reg, 2480 const DNBRegisterValue *reg_value_ptr) 2481 { 2482 if (reg != NULL) 2483 { 2484 DNBRegisterValue reg_value; 2485 if (reg_value_ptr == NULL) 2486 { 2487 if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, ®_value)) 2488 reg_value_ptr = ®_value; 2489 } 2490 2491 if (reg_value_ptr) 2492 { 2493 append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false); 2494 } 2495 else 2496 { 2497 // If we fail to read a register value, check if it has a default 2498 // fail value. If it does, return this instead in case some of 2499 // the registers are not available on the current system. 2500 if (reg->nub_info.size > 0) 2501 { 2502 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0'); 2503 append_hex_value (ostrm, zeros.data(), zeros.size(), false); 2504 } 2505 } 2506 } 2507 } 2508 2509 2510 void 2511 gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm, 2512 nub_process_t pid, 2513 nub_thread_t tid, 2514 const register_map_entry_t* reg, 2515 const DNBRegisterValue *reg_value_ptr) 2516 { 2517 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX 2518 // gdb register number, and VVVVVVVV is the correct number of hex bytes 2519 // as ASCII for the register value. 2520 if (reg != NULL) 2521 { 2522 ostrm << RAWHEX8(reg->gdb_regnum) << ':'; 2523 register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr); 2524 ostrm << ';'; 2525 } 2526 } 2527 2528 2529 void 2530 RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid, 2531 nub_addr_t dispatch_qaddr, 2532 std::string &queue_name, 2533 uint64_t &queue_width, 2534 uint64_t &queue_serialnum) const 2535 { 2536 queue_name.clear(); 2537 queue_width = 0; 2538 queue_serialnum = 0; 2539 2540 if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS && dispatch_qaddr != 0) 2541 { 2542 nub_addr_t dispatch_queue_addr = DNBProcessMemoryReadPointer (pid, dispatch_qaddr); 2543 if (dispatch_queue_addr) 2544 { 2545 queue_width = DNBProcessMemoryReadInteger (pid, dispatch_queue_addr + dqo_width, dqo_width_size, 0); 2546 queue_serialnum = DNBProcessMemoryReadInteger (pid, dispatch_queue_addr + dqo_serialnum, dqo_serialnum_size, 0); 2547 2548 if (dqo_version >= 4) 2549 { 2550 // libdispatch versions 4+, pointer to dispatch name is in the 2551 // queue structure. 2552 nub_addr_t pointer_to_label_address = dispatch_queue_addr + dqo_label; 2553 nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address); 2554 if (label_addr) 2555 queue_name = std::move(DNBProcessMemoryReadCString (pid, label_addr)); 2556 } 2557 else 2558 { 2559 // libdispatch versions 1-3, dispatch name is a fixed width char array 2560 // in the queue structure. 2561 queue_name = std::move(DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_addr + dqo_label, dqo_label_size)); 2562 } 2563 } 2564 } 2565 } 2566 2567 struct StackMemory 2568 { 2569 uint8_t bytes[2*sizeof(nub_addr_t)]; 2570 nub_size_t length; 2571 }; 2572 typedef std::map<nub_addr_t, StackMemory> StackMemoryMap; 2573 2574 2575 static void 2576 ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap, uint32_t backtrace_limit = 256) 2577 { 2578 DNBRegisterValue reg_value; 2579 if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, ®_value)) 2580 { 2581 uint32_t frame_count = 0; 2582 uint64_t fp = 0; 2583 if (reg_value.info.size == 4) 2584 fp = reg_value.value.uint32; 2585 else 2586 fp = reg_value.value.uint64; 2587 while (fp != 0) 2588 { 2589 // Make sure we never recurse more than 256 times so we don't recurse too far or 2590 // store up too much memory in the expedited cache 2591 if (++frame_count > backtrace_limit) 2592 break; 2593 2594 const nub_size_t read_size = reg_value.info.size*2; 2595 StackMemory stack_memory; 2596 stack_memory.length = read_size; 2597 if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size) 2598 break; 2599 // Make sure we don't try to put the same stack memory in more than once 2600 if (stack_mmap.find(fp) != stack_mmap.end()) 2601 break; 2602 // Put the entry into the cache 2603 stack_mmap[fp] = stack_memory; 2604 // Dereference the frame pointer to get to the previous frame pointer 2605 if (reg_value.info.size == 4) 2606 fp = ((uint32_t *)stack_memory.bytes)[0]; 2607 else 2608 fp = ((uint64_t *)stack_memory.bytes)[0]; 2609 } 2610 } 2611 } 2612 2613 rnb_err_t 2614 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) 2615 { 2616 const nub_process_t pid = m_ctx.ProcessID(); 2617 if (pid == INVALID_NUB_PROCESS) 2618 return SendPacket("E50"); 2619 2620 struct DNBThreadStopInfo tid_stop_info; 2621 2622 /* Fill the remaining space in this packet with as many registers 2623 as we can stuff in there. */ 2624 2625 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) 2626 { 2627 const bool did_exec = tid_stop_info.reason == eStopTypeExec; 2628 if (did_exec) 2629 { 2630 RNBRemote::InitializeRegisters(true); 2631 2632 // Reset any symbols that need resetting when we exec 2633 m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS; 2634 m_dispatch_queue_offsets.Clear(); 2635 } 2636 2637 std::ostringstream ostrm; 2638 // Output the T packet with the thread 2639 ostrm << 'T'; 2640 int signum = tid_stop_info.details.signal.signo; 2641 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); 2642 2643 // Translate any mach exceptions to gdb versions, unless they are 2644 // common exceptions like a breakpoint or a soft signal. 2645 switch (tid_stop_info.details.exception.type) 2646 { 2647 default: signum = 0; break; 2648 case EXC_BREAKPOINT: signum = SIGTRAP; break; 2649 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break; 2650 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break; 2651 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break; 2652 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break; 2653 case EXC_SOFTWARE: 2654 if (tid_stop_info.details.exception.data_count == 2 && 2655 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2656 signum = static_cast<int>(tid_stop_info.details.exception.data[1]); 2657 else 2658 signum = TARGET_EXC_SOFTWARE; 2659 break; 2660 } 2661 2662 ostrm << RAWHEX8(signum & 0xff); 2663 2664 ostrm << std::hex << "thread:" << tid << ';'; 2665 2666 const char *thread_name = DNBThreadGetName (pid, tid); 2667 if (thread_name && thread_name[0]) 2668 { 2669 size_t thread_name_len = strlen(thread_name); 2670 2671 2672 if (::strcspn (thread_name, "$#+-;:") == thread_name_len) 2673 ostrm << std::hex << "name:" << thread_name << ';'; 2674 else 2675 { 2676 // the thread name contains special chars, send as hex bytes 2677 ostrm << std::hex << "hexname:"; 2678 uint8_t *u_thread_name = (uint8_t *)thread_name; 2679 for (int i = 0; i < thread_name_len; i++) 2680 ostrm << RAWHEX8(u_thread_name[i]); 2681 ostrm << ';'; 2682 } 2683 } 2684 2685 thread_identifier_info_data_t thread_ident_info; 2686 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 2687 { 2688 if (thread_ident_info.dispatch_qaddr != 0) 2689 { 2690 ostrm << "qaddr:" << std::hex << thread_ident_info.dispatch_qaddr << ';'; 2691 const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets(); 2692 if (dispatch_queue_offsets) 2693 { 2694 std::string queue_name; 2695 uint64_t queue_width = 0; 2696 uint64_t queue_serialnum = 0; 2697 dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum); 2698 if (!queue_name.empty()) 2699 { 2700 ostrm << "qname:"; 2701 append_hex_value(ostrm, queue_name.data(), queue_name.size(), false); 2702 ostrm << ';'; 2703 } 2704 if (queue_width == 1) 2705 ostrm << "qkind:serial;"; 2706 else if (queue_width > 1) 2707 ostrm << "qkind:concurrent;"; 2708 2709 if (queue_serialnum > 0) 2710 ostrm << "qserial:" << DECIMAL << queue_serialnum << ';'; 2711 } 2712 } 2713 } 2714 2715 // If a 'QListThreadsInStopReply' was sent to enable this feature, we 2716 // will send all thread IDs back in the "threads" key whose value is 2717 // a list of hex thread IDs separated by commas: 2718 // "threads:10a,10b,10c;" 2719 // This will save the debugger from having to send a pair of qfThreadInfo 2720 // and qsThreadInfo packets, but it also might take a lot of room in the 2721 // stop reply packet, so it must be enabled only on systems where there 2722 // are no limits on packet lengths. 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 // Include JSON info that describes the stop reason for any threads 2740 // that actually have stop reasons. We use the new "jstopinfo" key 2741 // whose values is hex ascii JSON that contains the thread IDs 2742 // thread stop info only for threads that have stop reasons. Only send 2743 // this if we have more than one thread otherwise this packet has all 2744 // the info it needs. 2745 if (numthreads > 1) 2746 { 2747 const bool threads_with_valid_stop_info_only = true; 2748 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 2749 if (threads_info_sp) 2750 { 2751 ostrm << std::hex << "jstopinfo:"; 2752 std::ostringstream json_strm; 2753 threads_info_sp->Dump (json_strm); 2754 append_hexified_string (ostrm, json_strm.str()); 2755 ostrm << ';'; 2756 } 2757 } 2758 } 2759 2760 2761 if (g_num_reg_entries == 0) 2762 InitializeRegisters (); 2763 2764 if (g_reg_entries != NULL) 2765 { 2766 DNBRegisterValue reg_value; 2767 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2768 { 2769 // Expedite all registers in the first register set that aren't 2770 // contained in other registers 2771 if (g_reg_entries[reg].nub_info.set == 1 && 2772 g_reg_entries[reg].nub_info.value_regs == NULL) 2773 { 2774 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 2775 continue; 2776 2777 gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], ®_value); 2778 } 2779 } 2780 } 2781 2782 if (did_exec) 2783 { 2784 ostrm << "reason:exec;"; 2785 } 2786 else if (tid_stop_info.details.exception.type) 2787 { 2788 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';'; 2789 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';'; 2790 for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i) 2791 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';'; 2792 } 2793 2794 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 2795 // frame pointer chain. 2796 StackMemoryMap stack_mmap; 2797 ReadStackMemory (pid, tid, stack_mmap, 1); 2798 if (!stack_mmap.empty()) 2799 { 2800 for (const auto &stack_memory : stack_mmap) 2801 { 2802 ostrm << "memory:" << HEXBASE << stack_memory.first << '='; 2803 append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false); 2804 ostrm << ';'; 2805 } 2806 } 2807 2808 return SendPacket (ostrm.str ()); 2809 } 2810 return SendPacket("E51"); 2811 } 2812 2813 /* '?' 2814 The stop reply packet - tell gdb what the status of the inferior is. 2815 Often called the questionmark_packet. */ 2816 2817 rnb_err_t 2818 RNBRemote::HandlePacket_last_signal (const char *unused) 2819 { 2820 if (!m_ctx.HasValidProcessID()) 2821 { 2822 // Inferior is not yet specified/running 2823 return SendPacket ("E02"); 2824 } 2825 2826 nub_process_t pid = m_ctx.ProcessID(); 2827 nub_state_t pid_state = DNBProcessGetState (pid); 2828 2829 switch (pid_state) 2830 { 2831 case eStateAttaching: 2832 case eStateLaunching: 2833 case eStateRunning: 2834 case eStateStepping: 2835 case eStateDetached: 2836 return rnb_success; // Ignore 2837 2838 case eStateSuspended: 2839 case eStateStopped: 2840 case eStateCrashed: 2841 { 2842 nub_thread_t tid = DNBProcessGetCurrentThread (pid); 2843 // Make sure we set the current thread so g and p packets return 2844 // the data the gdb will expect. 2845 SetCurrentThread (tid); 2846 2847 SendStopReplyPacketForThread (tid); 2848 } 2849 break; 2850 2851 case eStateInvalid: 2852 case eStateUnloaded: 2853 case eStateExited: 2854 { 2855 char pid_exited_packet[16] = ""; 2856 int pid_status = 0; 2857 // Process exited with exit status 2858 if (!DNBProcessGetExitStatus(pid, &pid_status)) 2859 pid_status = 0; 2860 2861 if (pid_status) 2862 { 2863 if (WIFEXITED (pid_status)) 2864 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status)); 2865 else if (WIFSIGNALED (pid_status)) 2866 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status)); 2867 else if (WIFSTOPPED (pid_status)) 2868 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status)); 2869 } 2870 2871 // If we have an empty exit packet, lets fill one in to be safe. 2872 if (!pid_exited_packet[0]) 2873 { 2874 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1); 2875 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0'; 2876 } 2877 2878 const char *exit_info = DNBProcessGetExitInfo (pid); 2879 if (exit_info != NULL && *exit_info != '\0') 2880 { 2881 std::ostringstream exit_packet; 2882 exit_packet << pid_exited_packet; 2883 exit_packet << ';'; 2884 exit_packet << RAW_HEXBASE << "description"; 2885 exit_packet << ':'; 2886 for (size_t i = 0; exit_info[i] != '\0'; i++) 2887 exit_packet << RAWHEX8(exit_info[i]); 2888 exit_packet << ';'; 2889 return SendPacket (exit_packet.str()); 2890 } 2891 else 2892 return SendPacket (pid_exited_packet); 2893 } 2894 break; 2895 } 2896 return rnb_success; 2897 } 2898 2899 rnb_err_t 2900 RNBRemote::HandlePacket_M (const char *p) 2901 { 2902 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2903 { 2904 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet"); 2905 } 2906 2907 char *c; 2908 p++; 2909 errno = 0; 2910 nub_addr_t addr = strtoull (p, &c, 16); 2911 if (errno != 0 && addr == 0) 2912 { 2913 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet"); 2914 } 2915 if (*c != ',') 2916 { 2917 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet"); 2918 } 2919 2920 /* Advance 'p' to the length part of the packet. */ 2921 p += (c - p) + 1; 2922 2923 errno = 0; 2924 unsigned long length = strtoul (p, &c, 16); 2925 if (errno != 0 && length == 0) 2926 { 2927 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet"); 2928 } 2929 if (length == 0) 2930 { 2931 return SendPacket ("OK"); 2932 } 2933 2934 if (*c != ':') 2935 { 2936 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet"); 2937 } 2938 /* Advance 'p' to the data part of the packet. */ 2939 p += (c - p) + 1; 2940 2941 size_t datalen = strlen (p); 2942 if (datalen & 0x1) 2943 { 2944 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet"); 2945 } 2946 if (datalen == 0) 2947 { 2948 return SendPacket ("OK"); 2949 } 2950 2951 uint8_t *buf = (uint8_t *) alloca (datalen / 2); 2952 uint8_t *i = buf; 2953 2954 while (*p != '\0' && *(p + 1) != '\0') 2955 { 2956 char hexbuf[3]; 2957 hexbuf[0] = *p; 2958 hexbuf[1] = *(p + 1); 2959 hexbuf[2] = '\0'; 2960 errno = 0; 2961 uint8_t byte = strtoul (hexbuf, NULL, 16); 2962 if (errno != 0 && byte == 0) 2963 { 2964 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet"); 2965 } 2966 *i++ = byte; 2967 p += 2; 2968 } 2969 2970 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf); 2971 if (wrote != length) 2972 return SendPacket ("E09"); 2973 else 2974 return SendPacket ("OK"); 2975 } 2976 2977 2978 rnb_err_t 2979 RNBRemote::HandlePacket_m (const char *p) 2980 { 2981 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2982 { 2983 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet"); 2984 } 2985 2986 char *c; 2987 p++; 2988 errno = 0; 2989 nub_addr_t addr = strtoull (p, &c, 16); 2990 if (errno != 0 && addr == 0) 2991 { 2992 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet"); 2993 } 2994 if (*c != ',') 2995 { 2996 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet"); 2997 } 2998 2999 /* Advance 'p' to the length part of the packet. */ 3000 p += (c - p) + 1; 3001 3002 errno = 0; 3003 auto length = strtoul (p, NULL, 16); 3004 if (errno != 0 && length == 0) 3005 { 3006 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 3007 } 3008 if (length == 0) 3009 { 3010 return SendPacket (""); 3011 } 3012 3013 std::string buf(length, '\0'); 3014 if (buf.empty()) 3015 { 3016 return SendPacket ("E78"); 3017 } 3018 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3019 if (bytes_read == 0) 3020 { 3021 return SendPacket ("E08"); 3022 } 3023 3024 // "The reply may contain fewer bytes than requested if the server was able 3025 // to read only part of the region of memory." 3026 length = bytes_read; 3027 3028 std::ostringstream ostrm; 3029 for (int i = 0; i < length; i++) 3030 ostrm << RAWHEX8(buf[i]); 3031 return SendPacket (ostrm.str ()); 3032 } 3033 3034 // Read memory, sent it up as binary data. 3035 // Usage: xADDR,LEN 3036 // ADDR and LEN are both base 16. 3037 3038 // Responds with 'OK' for zero-length request 3039 // or 3040 // 3041 // DATA 3042 // 3043 // where DATA is the binary data payload. 3044 3045 rnb_err_t 3046 RNBRemote::HandlePacket_x (const char *p) 3047 { 3048 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3049 { 3050 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 3051 } 3052 3053 char *c; 3054 p++; 3055 errno = 0; 3056 nub_addr_t addr = strtoull (p, &c, 16); 3057 if (errno != 0) 3058 { 3059 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 3060 } 3061 if (*c != ',') 3062 { 3063 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 3064 } 3065 3066 /* Advance 'p' to the number of bytes to be read. */ 3067 p += (c - p) + 1; 3068 3069 errno = 0; 3070 auto length = strtoul (p, NULL, 16); 3071 if (errno != 0) 3072 { 3073 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in x packet"); 3074 } 3075 3076 // zero length read means this is a test of whether that packet is implemented or not. 3077 if (length == 0) 3078 { 3079 return SendPacket ("OK"); 3080 } 3081 3082 std::vector<uint8_t> buf (length); 3083 3084 if (buf.capacity() != length) 3085 { 3086 return SendPacket ("E79"); 3087 } 3088 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]); 3089 if (bytes_read == 0) 3090 { 3091 return SendPacket ("E80"); 3092 } 3093 3094 std::vector<uint8_t> buf_quoted; 3095 buf_quoted.reserve (bytes_read + 30); 3096 for (int i = 0; i < bytes_read; i++) 3097 { 3098 if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*') 3099 { 3100 buf_quoted.push_back(0x7d); 3101 buf_quoted.push_back(buf[i] ^ 0x20); 3102 } 3103 else 3104 { 3105 buf_quoted.push_back(buf[i]); 3106 } 3107 } 3108 length = buf_quoted.size(); 3109 3110 std::ostringstream ostrm; 3111 for (int i = 0; i < length; i++) 3112 ostrm << buf_quoted[i]; 3113 3114 return SendPacket (ostrm.str ()); 3115 } 3116 3117 rnb_err_t 3118 RNBRemote::HandlePacket_X (const char *p) 3119 { 3120 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 3121 { 3122 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 3123 } 3124 3125 char *c; 3126 p++; 3127 errno = 0; 3128 nub_addr_t addr = strtoull (p, &c, 16); 3129 if (errno != 0 && addr == 0) 3130 { 3131 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 3132 } 3133 if (*c != ',') 3134 { 3135 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 3136 } 3137 3138 /* Advance 'p' to the length part of the packet. NB this is the length of the packet 3139 including any escaped chars. The data payload may be a little bit smaller after 3140 decoding. */ 3141 p += (c - p) + 1; 3142 3143 errno = 0; 3144 auto length = strtoul (p, NULL, 16); 3145 if (errno != 0 && length == 0) 3146 { 3147 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in X packet"); 3148 } 3149 3150 // I think gdb sends a zero length write request to test whether this 3151 // packet is accepted. 3152 if (length == 0) 3153 { 3154 return SendPacket ("OK"); 3155 } 3156 3157 std::vector<uint8_t> data = decode_binary_data (c, -1); 3158 std::vector<uint8_t>::const_iterator it; 3159 uint8_t *buf = (uint8_t *) alloca (data.size ()); 3160 uint8_t *i = buf; 3161 for (it = data.begin (); it != data.end (); ++it) 3162 { 3163 *i++ = *it; 3164 } 3165 3166 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf); 3167 if (wrote != data.size ()) 3168 return SendPacket ("E08"); 3169 return SendPacket ("OK"); 3170 } 3171 3172 /* 'g' -- read registers 3173 Get the contents of the registers for the current thread, 3174 send them to gdb. 3175 Should the setting of the Hg packet determine which thread's registers 3176 are returned? */ 3177 3178 rnb_err_t 3179 RNBRemote::HandlePacket_g (const char *p) 3180 { 3181 std::ostringstream ostrm; 3182 if (!m_ctx.HasValidProcessID()) 3183 { 3184 return SendPacket ("E11"); 3185 } 3186 3187 if (g_num_reg_entries == 0) 3188 InitializeRegisters (); 3189 3190 nub_process_t pid = m_ctx.ProcessID (); 3191 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1); 3192 if (tid == INVALID_NUB_THREAD) 3193 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3194 3195 // Get the register context size first by calling with NULL buffer 3196 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3197 if (reg_ctx_size) 3198 { 3199 // Now allocate enough space for the entire register context 3200 std::vector<uint8_t> reg_ctx; 3201 reg_ctx.resize(reg_ctx_size); 3202 // Now read the register context 3203 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 3204 if (reg_ctx_size) 3205 { 3206 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false); 3207 return SendPacket (ostrm.str ()); 3208 } 3209 } 3210 return SendPacket ("E74"); 3211 } 3212 3213 /* 'G XXX...' -- write registers 3214 How is the thread for these specified, beyond "the current thread"? 3215 Does gdb actually use the Hg packet to set this? */ 3216 3217 rnb_err_t 3218 RNBRemote::HandlePacket_G (const char *p) 3219 { 3220 if (!m_ctx.HasValidProcessID()) 3221 { 3222 return SendPacket ("E11"); 3223 } 3224 3225 if (g_num_reg_entries == 0) 3226 InitializeRegisters (); 3227 3228 StringExtractor packet(p); 3229 packet.SetFilePos(1); // Skip the 'G' 3230 3231 nub_process_t pid = m_ctx.ProcessID(); 3232 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3233 if (tid == INVALID_NUB_THREAD) 3234 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3235 3236 // Get the register context size first by calling with NULL buffer 3237 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 3238 if (reg_ctx_size) 3239 { 3240 // Now allocate enough space for the entire register context 3241 std::vector<uint8_t> reg_ctx; 3242 reg_ctx.resize(reg_ctx_size); 3243 3244 const nub_size_t bytes_extracted = packet.GetHexBytes (®_ctx[0], reg_ctx.size(), 0xcc); 3245 if (bytes_extracted == reg_ctx.size()) 3246 { 3247 // Now write the register context 3248 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 3249 if (reg_ctx_size == reg_ctx.size()) 3250 return SendPacket ("OK"); 3251 else 3252 return SendPacket ("E55"); 3253 } 3254 else 3255 { 3256 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); 3257 return SendPacket ("E64"); 3258 } 3259 } 3260 return SendPacket ("E65"); 3261 } 3262 3263 static bool 3264 RNBRemoteShouldCancelCallback (void *not_used) 3265 { 3266 RNBRemoteSP remoteSP(g_remoteSP); 3267 if (remoteSP.get() != NULL) 3268 { 3269 RNBRemote* remote = remoteSP.get(); 3270 if (remote->Comm().IsConnected()) 3271 return false; 3272 else 3273 return true; 3274 } 3275 return true; 3276 } 3277 3278 3279 // FORMAT: _MXXXXXX,PPP 3280 // XXXXXX: big endian hex chars 3281 // PPP: permissions can be any combo of r w x chars 3282 // 3283 // RESPONSE: XXXXXX 3284 // XXXXXX: hex address of the newly allocated memory 3285 // EXX: error code 3286 // 3287 // EXAMPLES: 3288 // _M123000,rw 3289 // _M123000,rwx 3290 // _M123000,xw 3291 3292 rnb_err_t 3293 RNBRemote::HandlePacket_AllocateMemory (const char *p) 3294 { 3295 StringExtractor packet (p); 3296 packet.SetFilePos(2); // Skip the "_M" 3297 3298 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0); 3299 if (size != 0) 3300 { 3301 if (packet.GetChar() == ',') 3302 { 3303 uint32_t permissions = 0; 3304 char ch; 3305 bool success = true; 3306 while (success && (ch = packet.GetChar()) != '\0') 3307 { 3308 switch (ch) 3309 { 3310 case 'r': permissions |= eMemoryPermissionsReadable; break; 3311 case 'w': permissions |= eMemoryPermissionsWritable; break; 3312 case 'x': permissions |= eMemoryPermissionsExecutable; break; 3313 default: success = false; break; 3314 } 3315 } 3316 3317 if (success) 3318 { 3319 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions); 3320 if (addr != INVALID_NUB_ADDRESS) 3321 { 3322 std::ostringstream ostrm; 3323 ostrm << RAW_HEXBASE << addr; 3324 return SendPacket (ostrm.str ()); 3325 } 3326 } 3327 } 3328 } 3329 return SendPacket ("E53"); 3330 } 3331 3332 // FORMAT: _mXXXXXX 3333 // XXXXXX: address that was previously allocated 3334 // 3335 // RESPONSE: XXXXXX 3336 // OK: address was deallocated 3337 // EXX: error code 3338 // 3339 // EXAMPLES: 3340 // _m123000 3341 3342 rnb_err_t 3343 RNBRemote::HandlePacket_DeallocateMemory (const char *p) 3344 { 3345 StringExtractor packet (p); 3346 packet.SetFilePos(2); // Skip the "_m" 3347 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS); 3348 3349 if (addr != INVALID_NUB_ADDRESS) 3350 { 3351 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr)) 3352 return SendPacket ("OK"); 3353 } 3354 return SendPacket ("E54"); 3355 } 3356 3357 3358 // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) 3359 // FORMAT: QSaveRegisterState (when thread suffix is NOT supported) 3360 // TTTT: thread ID in hex 3361 // 3362 // RESPONSE: 3363 // SAVEID: Where SAVEID is a decimal number that represents the save ID 3364 // that can be passed back into a "QRestoreRegisterState" packet 3365 // EXX: error code 3366 // 3367 // EXAMPLES: 3368 // QSaveRegisterState;thread:1E34; (when thread suffix is supported) 3369 // QSaveRegisterState (when thread suffix is NOT supported) 3370 3371 rnb_err_t 3372 RNBRemote::HandlePacket_SaveRegisterState (const char *p) 3373 { 3374 nub_process_t pid = m_ctx.ProcessID (); 3375 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3376 if (tid == INVALID_NUB_THREAD) 3377 { 3378 if (m_thread_suffix_supported) 3379 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 3380 else 3381 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 3382 } 3383 3384 // Get the register context size first by calling with NULL buffer 3385 const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid); 3386 if (save_id != 0) 3387 { 3388 char response[64]; 3389 snprintf (response, sizeof(response), "%u", save_id); 3390 return SendPacket (response); 3391 } 3392 else 3393 { 3394 return SendPacket ("E75"); 3395 } 3396 } 3397 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is supported) 3398 // FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT supported) 3399 // TTTT: thread ID in hex 3400 // SAVEID: a decimal number that represents the save ID that was 3401 // returned from a call to "QSaveRegisterState" 3402 // 3403 // RESPONSE: 3404 // OK: successfully restored registers for the specified thread 3405 // EXX: error code 3406 // 3407 // EXAMPLES: 3408 // QRestoreRegisterState:1;thread:1E34; (when thread suffix is supported) 3409 // QRestoreRegisterState:1 (when thread suffix is NOT supported) 3410 3411 rnb_err_t 3412 RNBRemote::HandlePacket_RestoreRegisterState (const char *p) 3413 { 3414 nub_process_t pid = m_ctx.ProcessID (); 3415 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3416 if (tid == INVALID_NUB_THREAD) 3417 { 3418 if (m_thread_suffix_supported) 3419 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 3420 else 3421 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 3422 } 3423 3424 StringExtractor packet (p); 3425 packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:" 3426 const uint32_t save_id = packet.GetU32(0); 3427 3428 if (save_id != 0) 3429 { 3430 // Get the register context size first by calling with NULL buffer 3431 if (DNBThreadRestoreRegisterState(pid, tid, save_id)) 3432 return SendPacket ("OK"); 3433 else 3434 return SendPacket ("E77"); 3435 } 3436 return SendPacket ("E76"); 3437 } 3438 3439 static bool 3440 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name) 3441 { 3442 bool return_val = true; 3443 while (*p != '\0') 3444 { 3445 char smallbuf[3]; 3446 smallbuf[0] = *p; 3447 smallbuf[1] = *(p + 1); 3448 smallbuf[2] = '\0'; 3449 3450 errno = 0; 3451 int ch = static_cast<int>(strtoul (smallbuf, NULL, 16)); 3452 if (errno != 0 && ch == 0) 3453 { 3454 return_val = false; 3455 break; 3456 } 3457 3458 attach_name.push_back(ch); 3459 p += 2; 3460 } 3461 return return_val; 3462 } 3463 3464 rnb_err_t 3465 RNBRemote::HandlePacket_qSupported (const char *p) 3466 { 3467 uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less 3468 char buf[256]; 3469 snprintf (buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", max_packet_size); 3470 3471 // By default, don't enable compression. It's only worth doing when we are working 3472 // with a low speed communication channel. 3473 bool enable_compression = false; 3474 3475 // Enable compression when debugserver is running on a watchOS device where communication may be over Bluetooth. 3476 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 3477 enable_compression = true; 3478 #endif 3479 3480 #if defined (HAVE_LIBCOMPRESSION) 3481 // libcompression is weak linked so test if compression_decode_buffer() is available 3482 if (enable_compression && compression_decode_buffer != NULL) 3483 { 3484 strcat (buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;DefaultCompressionMinSize="); 3485 char numbuf[16]; 3486 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3487 numbuf[sizeof (numbuf) - 1] = '\0'; 3488 strcat (buf, numbuf); 3489 } 3490 #elif defined (HAVE_LIBZ) 3491 if (enable_compression) 3492 { 3493 strcat (buf, ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize="); 3494 char numbuf[16]; 3495 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3496 numbuf[sizeof (numbuf) - 1] = '\0'; 3497 strcat (buf, numbuf); 3498 } 3499 #endif 3500 3501 return SendPacket (buf); 3502 } 3503 3504 /* 3505 vAttach;pid 3506 3507 Attach to a new process with the specified process ID. pid is a hexadecimal integer 3508 identifying the process. If the stub is currently controlling a process, it is 3509 killed. The attached process is stopped.This packet is only available in extended 3510 mode (see extended mode). 3511 3512 Reply: 3513 "ENN" for an error 3514 "Any Stop Reply Packet" for success 3515 */ 3516 3517 rnb_err_t 3518 RNBRemote::HandlePacket_v (const char *p) 3519 { 3520 if (strcmp (p, "vCont;c") == 0) 3521 { 3522 // Simple continue 3523 return RNBRemote::HandlePacket_c("c"); 3524 } 3525 else if (strcmp (p, "vCont;s") == 0) 3526 { 3527 // Simple step 3528 return RNBRemote::HandlePacket_s("s"); 3529 } 3530 else if (strstr (p, "vCont") == p) 3531 { 3532 typedef struct 3533 { 3534 nub_thread_t tid; 3535 char action; 3536 int signal; 3537 } vcont_action_t; 3538 3539 DNBThreadResumeActions thread_actions; 3540 char *c = (char *)(p += strlen("vCont")); 3541 char *c_end = c + strlen(c); 3542 if (*c == '?') 3543 return SendPacket ("vCont;c;C;s;S"); 3544 3545 while (c < c_end && *c == ';') 3546 { 3547 ++c; // Skip the semi-colon 3548 DNBThreadResumeAction thread_action; 3549 thread_action.tid = INVALID_NUB_THREAD; 3550 thread_action.state = eStateInvalid; 3551 thread_action.signal = 0; 3552 thread_action.addr = INVALID_NUB_ADDRESS; 3553 3554 char action = *c++; 3555 3556 switch (action) 3557 { 3558 case 'C': 3559 errno = 0; 3560 thread_action.signal = static_cast<int>(strtoul (c, &c, 16)); 3561 if (errno != 0) 3562 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3563 // Fall through to next case... 3564 3565 case 'c': 3566 // Continue 3567 thread_action.state = eStateRunning; 3568 break; 3569 3570 case 'S': 3571 errno = 0; 3572 thread_action.signal = static_cast<int>(strtoul (c, &c, 16)); 3573 if (errno != 0) 3574 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3575 // Fall through to next case... 3576 3577 case 's': 3578 // Step 3579 thread_action.state = eStateStepping; 3580 break; 3581 3582 default: 3583 HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet"); 3584 break; 3585 } 3586 if (*c == ':') 3587 { 3588 errno = 0; 3589 thread_action.tid = strtoul (++c, &c, 16); 3590 if (errno != 0) 3591 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet"); 3592 } 3593 3594 thread_actions.Append (thread_action); 3595 } 3596 3597 // If a default action for all other threads wasn't mentioned 3598 // then we should stop the threads 3599 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3600 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize()); 3601 return rnb_success; 3602 } 3603 else if (strstr (p, "vAttach") == p) 3604 { 3605 nub_process_t attach_pid = INVALID_NUB_PROCESS; 3606 char err_str[1024]={'\0'}; 3607 3608 if (strstr (p, "vAttachWait;") == p) 3609 { 3610 p += strlen("vAttachWait;"); 3611 std::string attach_name; 3612 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3613 { 3614 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 3615 } 3616 const bool ignore_existing = true; 3617 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3618 3619 } 3620 else if (strstr (p, "vAttachOrWait;") == p) 3621 { 3622 p += strlen("vAttachOrWait;"); 3623 std::string attach_name; 3624 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3625 { 3626 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt"); 3627 } 3628 const bool ignore_existing = false; 3629 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3630 } 3631 else if (strstr (p, "vAttachName;") == p) 3632 { 3633 p += strlen("vAttachName;"); 3634 std::string attach_name; 3635 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3636 { 3637 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 3638 } 3639 3640 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str)); 3641 3642 } 3643 else if (strstr (p, "vAttach;") == p) 3644 { 3645 p += strlen("vAttach;"); 3646 char *end = NULL; 3647 attach_pid = static_cast<int>(strtoul (p, &end, 16)); // PID will be in hex, so use base 16 to decode 3648 if (p != end && *end == '\0') 3649 { 3650 // Wait at most 30 second for attach 3651 struct timespec attach_timeout_abstime; 3652 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 3653 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str)); 3654 } 3655 } 3656 else 3657 { 3658 return HandlePacket_UNIMPLEMENTED(p); 3659 } 3660 3661 3662 if (attach_pid != INVALID_NUB_PROCESS) 3663 { 3664 if (m_ctx.ProcessID() != attach_pid) 3665 m_ctx.SetProcessID(attach_pid); 3666 // Send a stop reply packet to indicate we successfully attached! 3667 NotifyThatProcessStopped (); 3668 return rnb_success; 3669 } 3670 else 3671 { 3672 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3673 if (err_str[0]) 3674 m_ctx.LaunchStatus().SetErrorString(err_str); 3675 else 3676 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3677 SendPacket ("E01"); // E01 is our magic error value for attach failed. 3678 DNBLogError ("Attach failed: \"%s\".", err_str); 3679 return rnb_err; 3680 } 3681 } 3682 3683 // All other failures come through here 3684 return HandlePacket_UNIMPLEMENTED(p); 3685 } 3686 3687 /* 'T XX' -- status of thread 3688 Check if the specified thread is alive. 3689 The thread number is in hex? */ 3690 3691 rnb_err_t 3692 RNBRemote::HandlePacket_T (const char *p) 3693 { 3694 p++; 3695 if (p == NULL || *p == '\0') 3696 { 3697 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet"); 3698 } 3699 if (!m_ctx.HasValidProcessID()) 3700 { 3701 return SendPacket ("E15"); 3702 } 3703 errno = 0; 3704 nub_thread_t tid = strtoul (p, NULL, 16); 3705 if (errno != 0 && tid == 0) 3706 { 3707 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet"); 3708 } 3709 3710 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid); 3711 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) 3712 { 3713 return SendPacket ("E16"); 3714 } 3715 3716 return SendPacket ("OK"); 3717 } 3718 3719 3720 rnb_err_t 3721 RNBRemote::HandlePacket_z (const char *p) 3722 { 3723 if (p == NULL || *p == '\0') 3724 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet"); 3725 3726 if (!m_ctx.HasValidProcessID()) 3727 return SendPacket ("E15"); 3728 3729 char packet_cmd = *p++; 3730 char break_type = *p++; 3731 3732 if (*p++ != ',') 3733 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3734 3735 char *c = NULL; 3736 nub_process_t pid = m_ctx.ProcessID(); 3737 errno = 0; 3738 nub_addr_t addr = strtoull (p, &c, 16); 3739 if (errno != 0 && addr == 0) 3740 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet"); 3741 p = c; 3742 if (*p++ != ',') 3743 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3744 3745 errno = 0; 3746 auto byte_size = strtoul (p, &c, 16); 3747 if (errno != 0 && byte_size == 0) 3748 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet"); 3749 3750 if (packet_cmd == 'Z') 3751 { 3752 // set 3753 switch (break_type) 3754 { 3755 case '0': // set software breakpoint 3756 case '1': // set hardware breakpoint 3757 { 3758 // gdb can send multiple Z packets for the same address and 3759 // these calls must be ref counted. 3760 bool hardware = (break_type == '1'); 3761 3762 if (DNBBreakpointSet (pid, addr, byte_size, hardware)) 3763 { 3764 // We successfully created a breakpoint, now lets full out 3765 // a ref count structure with the breakID and add it to our 3766 // map. 3767 return SendPacket ("OK"); 3768 } 3769 else 3770 { 3771 // We failed to set the software breakpoint 3772 return SendPacket ("E09"); 3773 } 3774 } 3775 break; 3776 3777 case '2': // set write watchpoint 3778 case '3': // set read watchpoint 3779 case '4': // set access watchpoint 3780 { 3781 bool hardware = true; 3782 uint32_t watch_flags = 0; 3783 if (break_type == '2') 3784 watch_flags = WATCH_TYPE_WRITE; 3785 else if (break_type == '3') 3786 watch_flags = WATCH_TYPE_READ; 3787 else 3788 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3789 3790 if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware)) 3791 { 3792 return SendPacket ("OK"); 3793 } 3794 else 3795 { 3796 // We failed to set the watchpoint 3797 return SendPacket ("E09"); 3798 } 3799 } 3800 break; 3801 3802 default: 3803 break; 3804 } 3805 } 3806 else if (packet_cmd == 'z') 3807 { 3808 // remove 3809 switch (break_type) 3810 { 3811 case '0': // remove software breakpoint 3812 case '1': // remove hardware breakpoint 3813 if (DNBBreakpointClear (pid, addr)) 3814 { 3815 return SendPacket ("OK"); 3816 } 3817 else 3818 { 3819 return SendPacket ("E08"); 3820 } 3821 break; 3822 3823 case '2': // remove write watchpoint 3824 case '3': // remove read watchpoint 3825 case '4': // remove access watchpoint 3826 if (DNBWatchpointClear (pid, addr)) 3827 { 3828 return SendPacket ("OK"); 3829 } 3830 else 3831 { 3832 return SendPacket ("E08"); 3833 } 3834 break; 3835 3836 default: 3837 break; 3838 } 3839 } 3840 return HandlePacket_UNIMPLEMENTED(p); 3841 } 3842 3843 // Extract the thread number from the thread suffix that might be appended to 3844 // thread specific packets. This will only be enabled if m_thread_suffix_supported 3845 // is true. 3846 nub_thread_t 3847 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p) 3848 { 3849 if (m_thread_suffix_supported) 3850 { 3851 nub_thread_t tid = INVALID_NUB_THREAD; 3852 if (p) 3853 { 3854 const char *tid_cstr = strstr (p, "thread:"); 3855 if (tid_cstr) 3856 { 3857 tid_cstr += strlen ("thread:"); 3858 tid = strtoul(tid_cstr, NULL, 16); 3859 } 3860 } 3861 return tid; 3862 } 3863 return GetCurrentThread(); 3864 3865 } 3866 3867 /* 'p XX' 3868 print the contents of register X */ 3869 3870 rnb_err_t 3871 RNBRemote::HandlePacket_p (const char *p) 3872 { 3873 if (g_num_reg_entries == 0) 3874 InitializeRegisters (); 3875 3876 if (p == NULL || *p == '\0') 3877 { 3878 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3879 } 3880 if (!m_ctx.HasValidProcessID()) 3881 { 3882 return SendPacket ("E15"); 3883 } 3884 nub_process_t pid = m_ctx.ProcessID(); 3885 errno = 0; 3886 char *tid_cstr = NULL; 3887 uint32_t reg = static_cast<uint32_t>(strtoul (p + 1, &tid_cstr, 16)); 3888 if (errno != 0 && reg == 0) 3889 { 3890 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet"); 3891 } 3892 3893 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr); 3894 if (tid == INVALID_NUB_THREAD) 3895 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3896 3897 const register_map_entry_t *reg_entry; 3898 3899 if (reg < g_num_reg_entries) 3900 reg_entry = &g_reg_entries[reg]; 3901 else 3902 reg_entry = NULL; 3903 3904 std::ostringstream ostrm; 3905 if (reg_entry == NULL) 3906 { 3907 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg); 3908 ostrm << "00000000"; 3909 } 3910 else if (reg_entry->nub_info.reg == -1) 3911 { 3912 if (reg_entry->nub_info.size > 0) 3913 { 3914 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 3915 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 3916 } 3917 } 3918 else 3919 { 3920 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL); 3921 } 3922 return SendPacket (ostrm.str()); 3923 } 3924 3925 /* 'Pnn=rrrrr' 3926 Set register number n to value r. 3927 n and r are hex strings. */ 3928 3929 rnb_err_t 3930 RNBRemote::HandlePacket_P (const char *p) 3931 { 3932 if (g_num_reg_entries == 0) 3933 InitializeRegisters (); 3934 3935 if (p == NULL || *p == '\0') 3936 { 3937 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet"); 3938 } 3939 if (!m_ctx.HasValidProcessID()) 3940 { 3941 return SendPacket ("E28"); 3942 } 3943 3944 nub_process_t pid = m_ctx.ProcessID(); 3945 3946 StringExtractor packet (p); 3947 3948 const char cmd_char = packet.GetChar(); 3949 // Register ID is always in big endian 3950 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX); 3951 const char equal_char = packet.GetChar(); 3952 3953 if (cmd_char != 'P') 3954 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet"); 3955 3956 if (reg == UINT32_MAX) 3957 return SendPacket ("E29"); 3958 3959 if (equal_char != '=') 3960 return SendPacket ("E30"); 3961 3962 const register_map_entry_t *reg_entry; 3963 3964 if (reg >= g_num_reg_entries) 3965 return SendPacket("E47"); 3966 3967 reg_entry = &g_reg_entries[reg]; 3968 3969 if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1) 3970 { 3971 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); 3972 return SendPacket("E48"); 3973 } 3974 3975 DNBRegisterValue reg_value; 3976 reg_value.info = reg_entry->nub_info; 3977 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 3978 3979 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3980 if (tid == INVALID_NUB_THREAD) 3981 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3982 3983 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 3984 { 3985 return SendPacket ("E32"); 3986 } 3987 return SendPacket ("OK"); 3988 } 3989 3990 /* 'c [addr]' 3991 Continue, optionally from a specified address. */ 3992 3993 rnb_err_t 3994 RNBRemote::HandlePacket_c (const char *p) 3995 { 3996 const nub_process_t pid = m_ctx.ProcessID(); 3997 3998 if (pid == INVALID_NUB_PROCESS) 3999 return SendPacket ("E23"); 4000 4001 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 4002 4003 if (*(p + 1) != '\0') 4004 { 4005 action.tid = GetContinueThread(); 4006 errno = 0; 4007 action.addr = strtoull (p + 1, NULL, 16); 4008 if (errno != 0 && action.addr == 0) 4009 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet"); 4010 } 4011 4012 DNBThreadResumeActions thread_actions; 4013 thread_actions.Append(action); 4014 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 4015 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4016 return SendPacket ("E25"); 4017 // Don't send an "OK" packet; response is the stopped/exited message. 4018 return rnb_success; 4019 } 4020 4021 rnb_err_t 4022 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) 4023 { 4024 /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code) 4025 for the memory region containing a given address and return that information. 4026 4027 Users of this packet must be prepared for three results: 4028 4029 Region information is returned 4030 Region information is unavailable for this address because the address is in unmapped memory 4031 Region lookup cannot be performed on this platform or process is not yet launched 4032 This packet isn't implemented 4033 4034 Examples of use: 4035 qMemoryRegionInfo:3a55140 4036 start:3a50000,size:100000,permissions:rwx 4037 4038 qMemoryRegionInfo:0 4039 error:address in unmapped region 4040 4041 qMemoryRegionInfo:3a551140 (on a different platform) 4042 error:region lookup cannot be performed 4043 4044 qMemoryRegionInfo 4045 OK // this packet is implemented by the remote nub 4046 */ 4047 4048 p += sizeof ("qMemoryRegionInfo") - 1; 4049 if (*p == '\0') 4050 return SendPacket ("OK"); 4051 if (*p++ != ':') 4052 return SendPacket ("E67"); 4053 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 4054 p += 2; 4055 4056 errno = 0; 4057 uint64_t address = strtoul (p, NULL, 16); 4058 if (errno != 0 && address == 0) 4059 { 4060 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 4061 } 4062 4063 DNBRegionInfo region_info = { 0, 0, 0 }; 4064 DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); 4065 std::ostringstream ostrm; 4066 4067 // start:3a50000,size:100000,permissions:rwx 4068 ostrm << "start:" << std::hex << region_info.addr << ';'; 4069 4070 if (region_info.size > 0) 4071 ostrm << "size:" << std::hex << region_info.size << ';'; 4072 4073 if (region_info.permissions) 4074 { 4075 ostrm << "permissions:"; 4076 4077 if (region_info.permissions & eMemoryPermissionsReadable) 4078 ostrm << 'r'; 4079 if (region_info.permissions & eMemoryPermissionsWritable) 4080 ostrm << 'w'; 4081 if (region_info.permissions & eMemoryPermissionsExecutable) 4082 ostrm << 'x'; 4083 ostrm << ';'; 4084 } 4085 return SendPacket (ostrm.str()); 4086 } 4087 4088 // qGetProfileData;scan_type:0xYYYYYYY 4089 rnb_err_t 4090 RNBRemote::HandlePacket_GetProfileData (const char *p) 4091 { 4092 nub_process_t pid = m_ctx.ProcessID(); 4093 if (pid == INVALID_NUB_PROCESS) 4094 return SendPacket ("OK"); 4095 4096 StringExtractor packet(p += sizeof ("qGetProfileData")); 4097 DNBProfileDataScanType scan_type = eProfileAll; 4098 std::string name; 4099 std::string value; 4100 while (packet.GetNameColonValue(name, value)) 4101 { 4102 if (name.compare ("scan_type") == 0) 4103 { 4104 std::istringstream iss(value); 4105 uint32_t int_value = 0; 4106 if (iss >> std::hex >> int_value) 4107 { 4108 scan_type = (DNBProfileDataScanType)int_value; 4109 } 4110 } 4111 } 4112 4113 std::string data = DNBProcessGetProfileData(pid, scan_type); 4114 if (!data.empty()) 4115 { 4116 return SendPacket (data.c_str()); 4117 } 4118 else 4119 { 4120 return SendPacket ("OK"); 4121 } 4122 } 4123 4124 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 4125 rnb_err_t 4126 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p) 4127 { 4128 nub_process_t pid = m_ctx.ProcessID(); 4129 if (pid == INVALID_NUB_PROCESS) 4130 return SendPacket ("OK"); 4131 4132 StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling")); 4133 bool enable = false; 4134 uint64_t interval_usec = 0; 4135 DNBProfileDataScanType scan_type = eProfileAll; 4136 std::string name; 4137 std::string value; 4138 while (packet.GetNameColonValue(name, value)) 4139 { 4140 if (name.compare ("enable") == 0) 4141 { 4142 enable = strtoul(value.c_str(), NULL, 10) > 0; 4143 } 4144 else if (name.compare ("interval_usec") == 0) 4145 { 4146 interval_usec = strtoul(value.c_str(), NULL, 10); 4147 } 4148 else if (name.compare ("scan_type") == 0) 4149 { 4150 std::istringstream iss(value); 4151 uint32_t int_value = 0; 4152 if (iss >> std::hex >> int_value) 4153 { 4154 scan_type = (DNBProfileDataScanType)int_value; 4155 } 4156 } 4157 } 4158 4159 if (interval_usec == 0) 4160 { 4161 enable = 0; 4162 } 4163 4164 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 4165 return SendPacket ("OK"); 4166 } 4167 4168 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO COMPRESS>; 4169 // 4170 // type: must be a type previously reported by the qXfer:features: SupportedCompressions list 4171 // 4172 // minsize: is optional; by default the qXfer:features: DefaultCompressionMinSize value is used 4173 // debugserver may have a better idea of what a good minimum packet size to compress is than lldb. 4174 4175 rnb_err_t 4176 RNBRemote::HandlePacket_QEnableCompression (const char *p) 4177 { 4178 p += sizeof ("QEnableCompression:") - 1; 4179 4180 size_t new_compression_minsize = m_compression_minsize; 4181 const char *new_compression_minsize_str = strstr (p, "minsize:"); 4182 if (new_compression_minsize_str) 4183 { 4184 new_compression_minsize_str += strlen ("minsize:"); 4185 errno = 0; 4186 new_compression_minsize = strtoul (new_compression_minsize_str, NULL, 10); 4187 if (errno != 0 || new_compression_minsize == ULONG_MAX) 4188 { 4189 new_compression_minsize = m_compression_minsize; 4190 } 4191 } 4192 4193 #if defined (HAVE_LIBCOMPRESSION) 4194 if (compression_decode_buffer != NULL) 4195 { 4196 if (strstr (p, "type:zlib-deflate;") != nullptr) 4197 { 4198 EnableCompressionNextSendPacket (compression_types::zlib_deflate); 4199 m_compression_minsize = new_compression_minsize; 4200 return SendPacket ("OK"); 4201 } 4202 else if (strstr (p, "type:lz4;") != nullptr) 4203 { 4204 EnableCompressionNextSendPacket (compression_types::lz4); 4205 m_compression_minsize = new_compression_minsize; 4206 return SendPacket ("OK"); 4207 } 4208 else if (strstr (p, "type:lzma;") != nullptr) 4209 { 4210 EnableCompressionNextSendPacket (compression_types::lzma); 4211 m_compression_minsize = new_compression_minsize; 4212 return SendPacket ("OK"); 4213 } 4214 else if (strstr (p, "type:lzfse;") != nullptr) 4215 { 4216 EnableCompressionNextSendPacket (compression_types::lzfse); 4217 m_compression_minsize = new_compression_minsize; 4218 return SendPacket ("OK"); 4219 } 4220 } 4221 #endif 4222 4223 #if defined (HAVE_LIBZ) 4224 if (strstr (p, "type:zlib-deflate;") != nullptr) 4225 { 4226 EnableCompressionNextSendPacket (compression_types::zlib_deflate); 4227 m_compression_minsize = new_compression_minsize; 4228 return SendPacket ("OK"); 4229 } 4230 #endif 4231 4232 return SendPacket ("E88"); 4233 } 4234 4235 rnb_err_t 4236 RNBRemote::HandlePacket_qSpeedTest (const char *p) 4237 { 4238 p += strlen ("qSpeedTest:response_size:"); 4239 char *end = NULL; 4240 errno = 0; 4241 uint64_t response_size = ::strtoul (p, &end, 16); 4242 if (errno != 0) 4243 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Didn't find response_size value at right offset"); 4244 else if (*end == ';') 4245 { 4246 static char g_data[4*1024*1024+16] = "data:"; 4247 memset(g_data + 5, 'a', response_size); 4248 g_data[response_size + 5] = '\0'; 4249 return SendPacket (g_data); 4250 } 4251 else 4252 { 4253 return SendPacket ("E79"); 4254 } 4255 } 4256 4257 rnb_err_t 4258 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p) 4259 { 4260 /* This packet simply returns the number of supported hardware watchpoints. 4261 4262 Examples of use: 4263 qWatchpointSupportInfo: 4264 num:4 4265 4266 qWatchpointSupportInfo 4267 OK // this packet is implemented by the remote nub 4268 */ 4269 4270 p += sizeof ("qWatchpointSupportInfo") - 1; 4271 if (*p == '\0') 4272 return SendPacket ("OK"); 4273 if (*p++ != ':') 4274 return SendPacket ("E67"); 4275 4276 errno = 0; 4277 uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID()); 4278 std::ostringstream ostrm; 4279 4280 // size:4 4281 ostrm << "num:" << std::dec << num << ';'; 4282 return SendPacket (ostrm.str()); 4283 } 4284 4285 /* 'C sig [;addr]' 4286 Resume with signal sig, optionally at address addr. */ 4287 4288 rnb_err_t 4289 RNBRemote::HandlePacket_C (const char *p) 4290 { 4291 const nub_process_t pid = m_ctx.ProcessID(); 4292 4293 if (pid == INVALID_NUB_PROCESS) 4294 return SendPacket ("E36"); 4295 4296 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 4297 int process_signo = -1; 4298 if (*(p + 1) != '\0') 4299 { 4300 action.tid = GetContinueThread(); 4301 char *end = NULL; 4302 errno = 0; 4303 process_signo = static_cast<int>(strtoul (p + 1, &end, 16)); 4304 if (errno != 0) 4305 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet"); 4306 else if (*end == ';') 4307 { 4308 errno = 0; 4309 action.addr = strtoull (end + 1, NULL, 16); 4310 if (errno != 0 && action.addr == 0) 4311 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet"); 4312 } 4313 } 4314 4315 DNBThreadResumeActions thread_actions; 4316 thread_actions.Append (action); 4317 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal); 4318 if (!DNBProcessSignal(pid, process_signo)) 4319 return SendPacket ("E52"); 4320 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4321 return SendPacket ("E38"); 4322 /* Don't send an "OK" packet; response is the stopped/exited message. */ 4323 return rnb_success; 4324 } 4325 4326 //---------------------------------------------------------------------- 4327 // 'D' packet 4328 // Detach from gdb. 4329 //---------------------------------------------------------------------- 4330 rnb_err_t 4331 RNBRemote::HandlePacket_D (const char *p) 4332 { 4333 if (m_ctx.HasValidProcessID()) 4334 { 4335 if (DNBProcessDetach(m_ctx.ProcessID())) 4336 SendPacket ("OK"); 4337 else 4338 SendPacket ("E"); 4339 } 4340 else 4341 { 4342 SendPacket ("E"); 4343 } 4344 return rnb_success; 4345 } 4346 4347 /* 'k' 4348 Kill the inferior process. */ 4349 4350 rnb_err_t 4351 RNBRemote::HandlePacket_k (const char *p) 4352 { 4353 DNBLog ("Got a 'k' packet, killing the inferior process."); 4354 // No response to should be sent to the kill packet 4355 if (m_ctx.HasValidProcessID()) 4356 DNBProcessKill (m_ctx.ProcessID()); 4357 SendPacket ("X09"); 4358 return rnb_success; 4359 } 4360 4361 rnb_err_t 4362 RNBRemote::HandlePacket_stop_process (const char *p) 4363 { 4364 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt 4365 #if defined(TEST_EXIT_ON_INTERRUPT) 4366 rnb_err_t err = HandlePacket_k (p); 4367 m_comm.Disconnect(true); 4368 return err; 4369 #else 4370 if (!DNBProcessInterrupt(m_ctx.ProcessID())) 4371 { 4372 // If we failed to interrupt the process, then send a stop 4373 // reply packet as the process was probably already stopped 4374 HandlePacket_last_signal (NULL); 4375 } 4376 return rnb_success; 4377 #endif 4378 } 4379 4380 /* 's' 4381 Step the inferior process. */ 4382 4383 rnb_err_t 4384 RNBRemote::HandlePacket_s (const char *p) 4385 { 4386 const nub_process_t pid = m_ctx.ProcessID(); 4387 if (pid == INVALID_NUB_PROCESS) 4388 return SendPacket ("E32"); 4389 4390 // Hardware supported stepping not supported on arm 4391 nub_thread_t tid = GetContinueThread (); 4392 if (tid == 0 || tid == -1) 4393 tid = GetCurrentThread(); 4394 4395 if (tid == INVALID_NUB_THREAD) 4396 return SendPacket ("E33"); 4397 4398 DNBThreadResumeActions thread_actions; 4399 thread_actions.AppendAction(tid, eStateStepping); 4400 4401 // Make all other threads stop when we are stepping 4402 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 4403 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4404 return SendPacket ("E49"); 4405 // Don't send an "OK" packet; response is the stopped/exited message. 4406 return rnb_success; 4407 } 4408 4409 /* 'S sig [;addr]' 4410 Step with signal sig, optionally at address addr. */ 4411 4412 rnb_err_t 4413 RNBRemote::HandlePacket_S (const char *p) 4414 { 4415 const nub_process_t pid = m_ctx.ProcessID(); 4416 if (pid == INVALID_NUB_PROCESS) 4417 return SendPacket ("E36"); 4418 4419 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 4420 4421 if (*(p + 1) != '\0') 4422 { 4423 char *end = NULL; 4424 errno = 0; 4425 action.signal = static_cast<int>(strtoul (p + 1, &end, 16)); 4426 if (errno != 0) 4427 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 4428 else if (*end == ';') 4429 { 4430 errno = 0; 4431 action.addr = strtoull (end + 1, NULL, 16); 4432 if (errno != 0 && action.addr == 0) 4433 { 4434 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 4435 } 4436 } 4437 } 4438 4439 action.tid = GetContinueThread (); 4440 if (action.tid == 0 || action.tid == -1) 4441 return SendPacket ("E40"); 4442 4443 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 4444 if (tstate == eStateInvalid || tstate == eStateExited) 4445 return SendPacket ("E37"); 4446 4447 4448 DNBThreadResumeActions thread_actions; 4449 thread_actions.Append (action); 4450 4451 // Make all other threads stop when we are stepping 4452 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4453 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4454 return SendPacket ("E39"); 4455 4456 // Don't send an "OK" packet; response is the stopped/exited message. 4457 return rnb_success; 4458 } 4459 4460 static const char * 4461 GetArchName (const uint32_t cputype, const uint32_t cpusubtype) 4462 { 4463 switch (cputype) 4464 { 4465 case CPU_TYPE_ARM: 4466 switch (cpusubtype) 4467 { 4468 case 5: return "armv4"; 4469 case 6: return "armv6"; 4470 case 7: return "armv5t"; 4471 case 8: return "xscale"; 4472 case 9: return "armv7"; 4473 case 10: return "armv7f"; 4474 case 11: return "armv7s"; 4475 case 12: return "armv7k"; 4476 case 14: return "armv6m"; 4477 case 15: return "armv7m"; 4478 case 16: return "armv7em"; 4479 default: return "arm"; 4480 } 4481 break; 4482 case CPU_TYPE_ARM64: return "arm64"; 4483 case CPU_TYPE_I386: return "i386"; 4484 case CPU_TYPE_X86_64: 4485 switch (cpusubtype) 4486 { 4487 default: return "x86_64"; 4488 case 8: return "x86_64h"; 4489 } 4490 break; 4491 } 4492 return NULL; 4493 } 4494 4495 static bool 4496 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64) 4497 { 4498 static uint32_t g_host_cputype = 0; 4499 static uint32_t g_host_cpusubtype = 0; 4500 static uint32_t g_is_64_bit_capable = 0; 4501 static bool g_promoted_to_64 = false; 4502 4503 if (g_host_cputype == 0) 4504 { 4505 g_promoted_to_64 = false; 4506 size_t len = sizeof(uint32_t); 4507 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) 4508 { 4509 len = sizeof (uint32_t); 4510 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0) 4511 { 4512 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) 4513 { 4514 g_promoted_to_64 = true; 4515 g_host_cputype |= CPU_ARCH_ABI64; 4516 } 4517 } 4518 } 4519 4520 len = sizeof(uint32_t); 4521 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0) 4522 { 4523 if (g_promoted_to_64 && 4524 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486) 4525 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4526 } 4527 } 4528 4529 cputype = g_host_cputype; 4530 cpusubtype = g_host_cpusubtype; 4531 is_64_bit_capable = g_is_64_bit_capable; 4532 promoted_to_64 = g_promoted_to_64; 4533 return g_host_cputype != 0; 4534 } 4535 4536 rnb_err_t 4537 RNBRemote::HandlePacket_qHostInfo (const char *p) 4538 { 4539 std::ostringstream strm; 4540 4541 uint32_t cputype = 0; 4542 uint32_t cpusubtype = 0; 4543 uint32_t is_64_bit_capable = 0; 4544 bool promoted_to_64 = false; 4545 if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) 4546 { 4547 strm << "cputype:" << std::dec << cputype << ';'; 4548 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4549 } 4550 4551 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4552 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4553 // this for now. 4554 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 4555 { 4556 strm << "ostype:ios;"; 4557 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 4558 strm << "watchpoint_exceptions_received:before;"; 4559 } 4560 else 4561 { 4562 strm << "ostype:macosx;"; 4563 strm << "watchpoint_exceptions_received:after;"; 4564 } 4565 // char ostype[64]; 4566 // len = sizeof(ostype); 4567 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4568 // { 4569 // len = strlen(ostype); 4570 // std::transform (ostype, ostype + len, ostype, tolower); 4571 // strm << "ostype:" << std::dec << ostype << ';'; 4572 // } 4573 4574 strm << "vendor:apple;"; 4575 4576 #if defined (__LITTLE_ENDIAN__) 4577 strm << "endian:little;"; 4578 #elif defined (__BIG_ENDIAN__) 4579 strm << "endian:big;"; 4580 #elif defined (__PDP_ENDIAN__) 4581 strm << "endian:pdp;"; 4582 #endif 4583 4584 if (promoted_to_64) 4585 strm << "ptrsize:8;"; 4586 else 4587 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4588 return SendPacket (strm.str()); 4589 } 4590 4591 void 4592 XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes) 4593 { 4594 if (indent) 4595 s << INDENT_WITH_SPACES(indent); 4596 s << '<' << name; 4597 if (!has_attributes) 4598 s << '>' << std::endl; 4599 } 4600 4601 void 4602 XMLElementStartEndAttributes (std::ostringstream &s, bool empty) 4603 { 4604 if (empty) 4605 s << '/'; 4606 s << '>' << std::endl; 4607 } 4608 4609 void 4610 XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name) 4611 { 4612 if (indent) 4613 s << INDENT_WITH_SPACES(indent); 4614 s << '<' << '/' << name << '>' << std::endl; 4615 } 4616 4617 void 4618 XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true) 4619 { 4620 if (value) 4621 { 4622 if (indent) 4623 s << INDENT_WITH_SPACES(indent); 4624 s << '<' << name << '>' << value; 4625 if (close) 4626 XMLElementEnd(s, 0, name); 4627 } 4628 } 4629 4630 void 4631 XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true) 4632 { 4633 if (indent) 4634 s << INDENT_WITH_SPACES(indent); 4635 4636 s << '<' << name << '>' << DECIMAL << value; 4637 if (close) 4638 XMLElementEnd(s, 0, name); 4639 } 4640 4641 void 4642 XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL) 4643 { 4644 if (value) 4645 { 4646 if (default_value && strcmp(value, default_value) == 0) 4647 return; // No need to emit the attribute because it matches the default value 4648 s <<' ' << name << "=\"" << value << "\""; 4649 } 4650 } 4651 4652 void 4653 XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value) 4654 { 4655 s <<' ' << name << "=\"" << DECIMAL << value << "\""; 4656 } 4657 4658 void 4659 GenerateTargetXMLRegister (std::ostringstream &s, 4660 const uint32_t reg_num, 4661 nub_size_t num_reg_sets, 4662 const DNBRegisterSetInfo *reg_set_info, 4663 const register_map_entry_t ®) 4664 { 4665 const char *default_lldb_encoding = "uint"; 4666 const char *lldb_encoding = default_lldb_encoding; 4667 const char *gdb_group = "general"; 4668 const char *default_gdb_type = "int"; 4669 const char *gdb_type = default_gdb_type; 4670 const char *default_lldb_format = "hex"; 4671 const char *lldb_format = default_lldb_format; 4672 const char *lldb_set = NULL; 4673 4674 switch (reg.nub_info.type) 4675 { 4676 case Uint: lldb_encoding = "uint"; break; 4677 case Sint: lldb_encoding = "sint"; break; 4678 case IEEE754: lldb_encoding = "ieee754"; if (reg.nub_info.set > 0) gdb_group = "float"; break; 4679 case Vector: lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break; 4680 } 4681 4682 switch (reg.nub_info.format) 4683 { 4684 case Binary: lldb_format = "binary"; break; 4685 case Decimal: lldb_format = "decimal"; break; 4686 case Hex: lldb_format = "hex"; break; 4687 case Float: gdb_type = "float"; lldb_format = "float"; break; 4688 case VectorOfSInt8: gdb_type = "float"; lldb_format = "vector-sint8"; break; 4689 case VectorOfUInt8: gdb_type = "float"; lldb_format = "vector-uint8"; break; 4690 case VectorOfSInt16: gdb_type = "float"; lldb_format = "vector-sint16"; break; 4691 case VectorOfUInt16: gdb_type = "float"; lldb_format = "vector-uint16"; break; 4692 case VectorOfSInt32: gdb_type = "float"; lldb_format = "vector-sint32"; break; 4693 case VectorOfUInt32: gdb_type = "float"; lldb_format = "vector-uint32"; break; 4694 case VectorOfFloat32: gdb_type = "float"; lldb_format = "vector-float32"; break; 4695 case VectorOfUInt128: gdb_type = "float"; lldb_format = "vector-uint128"; break; 4696 }; 4697 if (reg_set_info && reg.nub_info.set < num_reg_sets) 4698 lldb_set = reg_set_info[reg.nub_info.set].name; 4699 4700 uint32_t indent = 2; 4701 4702 XMLElementStart(s, indent, "reg", true); 4703 XMLAttributeString(s, "name", reg.nub_info.name); 4704 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 4705 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 4706 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 4707 XMLAttributeString(s, "group", gdb_group); 4708 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 4709 XMLAttributeString (s, "altname", reg.nub_info.alt); 4710 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 4711 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 4712 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 4713 if (reg.nub_info.reg_gcc != INVALID_NUB_REGNUM) 4714 XMLAttributeUnsignedDecimal(s, "gcc_regnum", reg.nub_info.reg_gcc); 4715 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 4716 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 4717 4718 const char *lldb_generic = NULL; 4719 switch (reg.nub_info.reg_generic) 4720 { 4721 case GENERIC_REGNUM_FP: lldb_generic = "fp"; break; 4722 case GENERIC_REGNUM_PC: lldb_generic = "pc"; break; 4723 case GENERIC_REGNUM_SP: lldb_generic = "sp"; break; 4724 case GENERIC_REGNUM_RA: lldb_generic = "ra"; break; 4725 case GENERIC_REGNUM_FLAGS: lldb_generic = "flags"; break; 4726 case GENERIC_REGNUM_ARG1: lldb_generic = "arg1"; break; 4727 case GENERIC_REGNUM_ARG2: lldb_generic = "arg2"; break; 4728 case GENERIC_REGNUM_ARG3: lldb_generic = "arg3"; break; 4729 case GENERIC_REGNUM_ARG4: lldb_generic = "arg4"; break; 4730 case GENERIC_REGNUM_ARG5: lldb_generic = "arg5"; break; 4731 case GENERIC_REGNUM_ARG6: lldb_generic = "arg6"; break; 4732 case GENERIC_REGNUM_ARG7: lldb_generic = "arg7"; break; 4733 case GENERIC_REGNUM_ARG8: lldb_generic = "arg8"; break; 4734 default: break; 4735 } 4736 XMLAttributeString(s, "generic", lldb_generic); 4737 4738 4739 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 4740 if (!empty) 4741 { 4742 if (!reg.value_regnums.empty()) 4743 { 4744 std::ostringstream regnums; 4745 bool first = true; 4746 regnums << DECIMAL; 4747 for (auto regnum : reg.value_regnums) 4748 { 4749 if (!first) 4750 regnums << ','; 4751 regnums << regnum; 4752 first = false; 4753 } 4754 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 4755 } 4756 4757 if (!reg.invalidate_regnums.empty()) 4758 { 4759 std::ostringstream regnums; 4760 bool first = true; 4761 regnums << DECIMAL; 4762 for (auto regnum : reg.invalidate_regnums) 4763 { 4764 if (!first) 4765 regnums << ','; 4766 regnums << regnum; 4767 first = false; 4768 } 4769 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 4770 } 4771 } 4772 XMLElementStartEndAttributes(s, true); 4773 } 4774 4775 void 4776 GenerateTargetXMLRegisters (std::ostringstream &s) 4777 { 4778 nub_size_t num_reg_sets = 0; 4779 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets); 4780 4781 4782 uint32_t cputype = DNBGetRegisterCPUType(); 4783 if (cputype) 4784 { 4785 XMLElementStart(s, 0, "feature", true); 4786 std::ostringstream name_strm; 4787 name_strm << "com.apple.debugserver." << GetArchName (cputype, 0); 4788 XMLAttributeString(s, "name", name_strm.str().c_str()); 4789 XMLElementStartEndAttributes(s, false); 4790 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 4791 // for (const auto ®: g_dynamic_register_map) 4792 { 4793 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]); 4794 } 4795 XMLElementEnd(s, 0, "feature"); 4796 4797 if (num_reg_sets > 0) 4798 { 4799 XMLElementStart(s, 0, "groups", false); 4800 for (uint32_t set=1; set<num_reg_sets; ++set) 4801 { 4802 XMLElementStart(s, 2, "group", true); 4803 XMLAttributeUnsignedDecimal(s, "id", set); 4804 XMLAttributeString(s, "name", reg_sets[set].name); 4805 XMLElementStartEndAttributes(s, true); 4806 } 4807 XMLElementEnd(s, 0, "groups"); 4808 } 4809 } 4810 } 4811 4812 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 4813 <target version="1.0">)"; 4814 4815 static const char *g_target_xml_footer = "</target>"; 4816 4817 static std::string g_target_xml; 4818 4819 void 4820 UpdateTargetXML () 4821 { 4822 std::ostringstream s; 4823 s << g_target_xml_header << std::endl; 4824 4825 // Set the architecture 4826 //s << "<architecture>" << arch "</architecture>" << std::endl; 4827 4828 // Set the OSABI 4829 //s << "<osabi>abi-name</osabi>" 4830 4831 GenerateTargetXMLRegisters(s); 4832 4833 s << g_target_xml_footer << std::endl; 4834 4835 // Save the XML output in case it gets retrieved in chunks 4836 g_target_xml = s.str(); 4837 } 4838 4839 rnb_err_t 4840 RNBRemote::HandlePacket_qXfer (const char *command) 4841 { 4842 const char *p = command; 4843 p += strlen ("qXfer:"); 4844 const char *sep = strchr(p, ':'); 4845 if (sep) 4846 { 4847 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 4848 p = sep + 1; 4849 sep = strchr(p, ':'); 4850 if (sep) 4851 { 4852 std::string rw(p, sep - p); // "read" or "write" 4853 p = sep + 1; 4854 sep = strchr(p, ':'); 4855 if (sep) 4856 { 4857 std::string annex(p, sep - p); // "read" or "write" 4858 4859 p = sep + 1; 4860 sep = strchr(p, ','); 4861 if (sep) 4862 { 4863 std::string offset_str(p, sep - p); // read the length as a string 4864 p = sep + 1; 4865 std::string length_str(p); // read the offset as a string 4866 char *end = nullptr; 4867 const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset 4868 if (*end == '\0') 4869 { 4870 const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length 4871 if (*end == '\0') 4872 { 4873 if (object == "features" && 4874 rw == "read" && 4875 annex == "target.xml") 4876 { 4877 std::ostringstream xml_out; 4878 4879 if (offset == 0) 4880 { 4881 InitializeRegisters (true); 4882 4883 UpdateTargetXML(); 4884 if (g_target_xml.empty()) 4885 return SendPacket("E83"); 4886 4887 if (length > g_target_xml.size()) 4888 { 4889 xml_out << 'l'; // No more data 4890 xml_out << binary_encode_string(g_target_xml); 4891 } 4892 else 4893 { 4894 xml_out << 'm'; // More data needs to be read with a subsequent call 4895 xml_out << binary_encode_string(std::string(g_target_xml, offset, length)); 4896 } 4897 } 4898 else 4899 { 4900 // Retrieving target XML in chunks 4901 if (offset < g_target_xml.size()) 4902 { 4903 std::string chunk(g_target_xml, offset, length); 4904 if (chunk.size() < length) 4905 xml_out << 'l'; // No more data 4906 else 4907 xml_out << 'm'; // More data needs to be read with a subsequent call 4908 xml_out << binary_encode_string(chunk.data()); 4909 } 4910 } 4911 return SendPacket(xml_out.str()); 4912 } 4913 // Well formed, put not supported 4914 return HandlePacket_UNIMPLEMENTED (command); 4915 } 4916 } 4917 } 4918 } 4919 else 4920 { 4921 SendPacket ("E85"); 4922 } 4923 } 4924 else 4925 { 4926 SendPacket ("E86"); 4927 } 4928 } 4929 return SendPacket ("E82"); 4930 } 4931 4932 4933 rnb_err_t 4934 RNBRemote::HandlePacket_qGDBServerVersion (const char *p) 4935 { 4936 std::ostringstream strm; 4937 4938 #if defined(DEBUGSERVER_PROGRAM_NAME) 4939 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 4940 #else 4941 strm << "name:debugserver;"; 4942 #endif 4943 strm << "version:" << DEBUGSERVER_VERSION_STR << ";"; 4944 4945 return SendPacket (strm.str()); 4946 } 4947 4948 // A helper function that retrieves a single integer value from 4949 // a one-level-deep JSON dictionary of key-value pairs. e.g. 4950 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 4951 // 4952 uint64_t 4953 get_integer_value_for_key_name_from_json (const char *key, const char *json_string) 4954 { 4955 uint64_t retval = INVALID_NUB_ADDRESS; 4956 std::string key_with_quotes = "\""; 4957 key_with_quotes += key; 4958 key_with_quotes += "\""; 4959 const char *c = strstr (json_string, key_with_quotes.c_str()); 4960 if (c) 4961 { 4962 c += key_with_quotes.size(); 4963 4964 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 4965 c++; 4966 4967 if (*c == ':') 4968 { 4969 c++; 4970 4971 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 4972 c++; 4973 4974 errno = 0; 4975 retval = strtoul (c, NULL, 10); 4976 if (errno != 0) 4977 { 4978 retval = INVALID_NUB_ADDRESS; 4979 } 4980 } 4981 } 4982 return retval; 4983 4984 } 4985 4986 JSONGenerator::ObjectSP 4987 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) 4988 { 4989 JSONGenerator::ArraySP threads_array_sp; 4990 if (m_ctx.HasValidProcessID()) 4991 { 4992 threads_array_sp.reset(new JSONGenerator::Array()); 4993 4994 nub_process_t pid = m_ctx.ProcessID(); 4995 4996 nub_size_t numthreads = DNBProcessGetNumThreads (pid); 4997 for (nub_size_t i = 0; i < numthreads; ++i) 4998 { 4999 nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i); 5000 5001 struct DNBThreadStopInfo tid_stop_info; 5002 5003 const bool stop_info_valid = DNBThreadGetStopReason (pid, tid, &tid_stop_info); 5004 5005 // If we are doing stop info only, then we only show threads that have a 5006 // valid stop reason 5007 if (threads_with_valid_stop_info_only) 5008 { 5009 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5010 continue; 5011 } 5012 5013 JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary()); 5014 thread_dict_sp->AddIntegerItem("tid", tid); 5015 5016 std::string reason_value("none"); 5017 5018 if (stop_info_valid) 5019 { 5020 switch (tid_stop_info.reason) 5021 { 5022 case eStopTypeInvalid: 5023 break; 5024 5025 case eStopTypeSignal: 5026 if (tid_stop_info.details.signal.signo != 0) 5027 { 5028 thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo); 5029 reason_value = "signal"; 5030 } 5031 break; 5032 5033 case eStopTypeException: 5034 if (tid_stop_info.details.exception.type != 0) 5035 { 5036 reason_value = "exception"; 5037 thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type); 5038 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5039 for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i) 5040 { 5041 medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i]))); 5042 } 5043 thread_dict_sp->AddItem("medata", medata_array_sp); 5044 } 5045 break; 5046 5047 case eStopTypeExec: 5048 reason_value = "exec"; 5049 break; 5050 } 5051 } 5052 5053 thread_dict_sp->AddStringItem("reason", reason_value); 5054 5055 if (threads_with_valid_stop_info_only == false) 5056 { 5057 const char *thread_name = DNBThreadGetName (pid, tid); 5058 if (thread_name && thread_name[0]) 5059 thread_dict_sp->AddStringItem("name", thread_name); 5060 5061 thread_identifier_info_data_t thread_ident_info; 5062 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 5063 { 5064 if (thread_ident_info.dispatch_qaddr != 0) 5065 { 5066 thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr); 5067 5068 const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets(); 5069 if (dispatch_queue_offsets) 5070 { 5071 std::string queue_name; 5072 uint64_t queue_width = 0; 5073 uint64_t queue_serialnum = 0; 5074 dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum); 5075 if (!queue_name.empty()) 5076 thread_dict_sp->AddStringItem("qname", queue_name); 5077 if (queue_width == 1) 5078 thread_dict_sp->AddStringItem("qkind", "serial"); 5079 else if (queue_width > 1) 5080 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5081 if (queue_serialnum > 0) 5082 thread_dict_sp->AddIntegerItem("qserial", queue_serialnum); 5083 } 5084 } 5085 } 5086 5087 DNBRegisterValue reg_value; 5088 5089 if (g_reg_entries != NULL) 5090 { 5091 JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary()); 5092 5093 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 5094 { 5095 // Expedite all registers in the first register set that aren't 5096 // contained in other registers 5097 if (g_reg_entries[reg].nub_info.set == 1 && 5098 g_reg_entries[reg].nub_info.value_regs == NULL) 5099 { 5100 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 5101 continue; 5102 5103 std::ostringstream reg_num; 5104 reg_num << std::dec << g_reg_entries[reg].gdb_regnum; 5105 // Encode native byte ordered bytes as hex ascii 5106 registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size); 5107 } 5108 } 5109 thread_dict_sp->AddItem("registers", registers_dict_sp); 5110 } 5111 5112 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 5113 // frame pointer chain. 5114 StackMemoryMap stack_mmap; 5115 ReadStackMemory (pid, tid, stack_mmap); 5116 if (!stack_mmap.empty()) 5117 { 5118 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5119 5120 for (const auto &stack_memory : stack_mmap) 5121 { 5122 JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary()); 5123 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5124 stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length); 5125 memory_array_sp->AddItem(stack_memory_sp); 5126 } 5127 thread_dict_sp->AddItem("memory", memory_array_sp); 5128 } 5129 } 5130 5131 threads_array_sp->AddItem(thread_dict_sp); 5132 } 5133 } 5134 return threads_array_sp; 5135 } 5136 5137 rnb_err_t 5138 RNBRemote::HandlePacket_jThreadsInfo (const char *p) 5139 { 5140 JSONGenerator::ObjectSP threads_info_sp; 5141 std::ostringstream json; 5142 std::ostringstream reply_strm; 5143 // If we haven't run the process yet, return an error. 5144 if (m_ctx.HasValidProcessID()) 5145 { 5146 const bool threads_with_valid_stop_info_only = false; 5147 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5148 5149 if (threads_info_sp) 5150 { 5151 std::ostringstream strm; 5152 threads_info_sp->Dump (strm); 5153 std::string binary_packet = binary_encode_string (strm.str()); 5154 if (!binary_packet.empty()) 5155 return SendPacket (binary_packet.c_str()); 5156 } 5157 } 5158 return SendPacket ("E85"); 5159 5160 } 5161 5162 rnb_err_t 5163 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) 5164 { 5165 nub_process_t pid; 5166 std::ostringstream json; 5167 // If we haven't run the process yet, return an error. 5168 if (!m_ctx.HasValidProcessID()) 5169 { 5170 return SendPacket ("E81"); 5171 } 5172 5173 pid = m_ctx.ProcessID(); 5174 5175 const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" }; 5176 if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0) 5177 { 5178 p += strlen (thread_extended_info_str); 5179 5180 uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p); 5181 uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p); 5182 uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p); 5183 uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p); 5184 uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p); 5185 // Commented out the two variables below as they are not being used 5186 // uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p); 5187 // uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p); 5188 5189 if (tid != INVALID_NUB_ADDRESS) 5190 { 5191 nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid); 5192 5193 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5194 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS 5195 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS 5196 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) 5197 { 5198 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5199 } 5200 5201 bool timed_out = false; 5202 Genealogy::ThreadActivitySP thread_activity_sp; 5203 5204 // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base 5205 // and got an invalid value back, then we have a thread in early startup or shutdown and 5206 // it's possible that gathering the genealogy information for this thread go badly. 5207 // Ideally fetching this info for a thread in these odd states shouldn't matter - but 5208 // we've seen some problems with these new SPI and threads in edge-casey states. 5209 5210 double genealogy_fetch_time = 0; 5211 if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS) 5212 { 5213 DNBTimer timer(false); 5214 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out); 5215 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5216 } 5217 5218 std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen 5219 5220 json << "{"; 5221 5222 bool need_to_print_comma = false; 5223 5224 if (thread_activity_sp && timed_out == false) 5225 { 5226 const Genealogy::Activity *activity = &thread_activity_sp->current_activity; 5227 bool need_vouchers_comma_sep = false; 5228 json << "\"activity_query_timed_out\":false,"; 5229 if (genealogy_fetch_time != 0) 5230 { 5231 // If we append the floating point value with << we'll get it in scientific 5232 // notation. 5233 char floating_point_ascii_buffer[64]; 5234 floating_point_ascii_buffer[0] = '\0'; 5235 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5236 if (strlen (floating_point_ascii_buffer) > 0) 5237 { 5238 if (need_to_print_comma) 5239 json << ","; 5240 need_to_print_comma = true; 5241 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5242 } 5243 } 5244 if (activity->activity_id != 0) 5245 { 5246 if (need_to_print_comma) 5247 json << ","; 5248 need_to_print_comma = true; 5249 need_vouchers_comma_sep = true; 5250 json << "\"activity\":{"; 5251 json << "\"start\":" << activity->activity_start << ","; 5252 json << "\"id\":" << activity->activity_id << ","; 5253 json << "\"parent_id\":" << activity->parent_id << ","; 5254 json << "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\","; 5255 json << "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\""; 5256 json << "}"; 5257 } 5258 if (thread_activity_sp->messages.size() > 0) 5259 { 5260 need_to_print_comma = true; 5261 if (need_vouchers_comma_sep) 5262 json << ","; 5263 need_vouchers_comma_sep = true; 5264 json << "\"trace_messages\":["; 5265 bool printed_one_message = false; 5266 for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter) 5267 { 5268 if (printed_one_message) 5269 json << ","; 5270 else 5271 printed_one_message = true; 5272 json << "{"; 5273 json << "\"timestamp\":" << iter->timestamp << ","; 5274 json << "\"activity_id\":" << iter->activity_id << ","; 5275 json << "\"trace_id\":" << iter->trace_id << ","; 5276 json << "\"thread\":" << iter->thread << ","; 5277 json << "\"type\":" << (int) iter->type << ","; 5278 json << "\"process_info_index\":" << iter->process_info_index << ","; 5279 process_info_indexes.insert (iter->process_info_index); 5280 json << "\"message\":\"" << json_string_quote_metachars (iter->message) << "\""; 5281 json << "}"; 5282 } 5283 json << "]"; 5284 } 5285 if (thread_activity_sp->breadcrumbs.size() == 1) 5286 { 5287 need_to_print_comma = true; 5288 if (need_vouchers_comma_sep) 5289 json << ","; 5290 need_vouchers_comma_sep = true; 5291 json << "\"breadcrumb\":{"; 5292 for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter) 5293 { 5294 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5295 json << "\"activity_id\":" << iter->activity_id << ","; 5296 json << "\"timestamp\":" << iter->timestamp << ","; 5297 json << "\"name\":\"" << json_string_quote_metachars (iter->name) << "\""; 5298 } 5299 json << "}"; 5300 } 5301 if (process_info_indexes.size() > 0) 5302 { 5303 need_to_print_comma = true; 5304 if (need_vouchers_comma_sep) 5305 json << ","; 5306 need_vouchers_comma_sep = true; 5307 json << "\"process_infos\":["; 5308 bool printed_one_process_info = false; 5309 for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter) 5310 { 5311 if (printed_one_process_info) 5312 json << ","; 5313 else 5314 printed_one_process_info = true; 5315 Genealogy::ProcessExecutableInfoSP image_info_sp; 5316 uint32_t idx = *iter; 5317 image_info_sp = DNBGetGenealogyImageInfo (pid, idx); 5318 json << "{"; 5319 char uuid_buf[37]; 5320 uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf); 5321 json << "\"process_info_index\":" << idx << ","; 5322 json << "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\","; 5323 json << "\"image_uuid\":\"" << uuid_buf <<"\""; 5324 json << "}"; 5325 } 5326 json << "]"; 5327 } 5328 } 5329 else 5330 { 5331 if (timed_out) 5332 { 5333 if (need_to_print_comma) 5334 json << ","; 5335 need_to_print_comma = true; 5336 json << "\"activity_query_timed_out\":true"; 5337 if (genealogy_fetch_time != 0) 5338 { 5339 // If we append the floating point value with << we'll get it in scientific 5340 // notation. 5341 char floating_point_ascii_buffer[64]; 5342 floating_point_ascii_buffer[0] = '\0'; 5343 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5344 if (strlen (floating_point_ascii_buffer) > 0) 5345 { 5346 json << ","; 5347 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5348 } 5349 } 5350 } 5351 } 5352 5353 if (tsd_address != INVALID_NUB_ADDRESS) 5354 { 5355 if (need_to_print_comma) 5356 json << ","; 5357 need_to_print_comma = true; 5358 json << "\"tsd_address\":" << tsd_address; 5359 5360 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) 5361 { 5362 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index); 5363 if (requested_qos.IsValid()) 5364 { 5365 if (need_to_print_comma) 5366 json << ","; 5367 need_to_print_comma = true; 5368 json << "\"requested_qos\":{"; 5369 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5370 json << "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\","; 5371 json << "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\""; 5372 json << "}"; 5373 } 5374 } 5375 } 5376 5377 if (pthread_t_value != INVALID_NUB_ADDRESS) 5378 { 5379 if (need_to_print_comma) 5380 json << ","; 5381 need_to_print_comma = true; 5382 json << "\"pthread_t\":" << pthread_t_value; 5383 } 5384 5385 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid); 5386 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) 5387 { 5388 if (need_to_print_comma) 5389 json << ","; 5390 need_to_print_comma = true; 5391 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5392 } 5393 5394 json << "}"; 5395 std::string json_quoted = binary_encode_string (json.str()); 5396 return SendPacket (json_quoted); 5397 } 5398 } 5399 return SendPacket ("OK"); 5400 } 5401 5402 rnb_err_t 5403 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p) 5404 { 5405 nub_process_t pid; 5406 // If we haven't run the process yet, return an error. 5407 if (!m_ctx.HasValidProcessID()) 5408 { 5409 return SendPacket ("E83"); 5410 } 5411 5412 pid = m_ctx.ProcessID(); 5413 5414 const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" }; 5415 if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0) 5416 { 5417 p += strlen (get_loaded_dynamic_libraries_infos_str); 5418 5419 nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p); 5420 nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p); 5421 5422 if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS) 5423 { 5424 JSONGenerator::ObjectSP json_sp; 5425 5426 json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count); 5427 5428 if (json_sp.get()) 5429 { 5430 std::ostringstream json_str; 5431 json_sp->Dump (json_str); 5432 if (json_str.str().size() > 0) 5433 { 5434 std::string json_str_quoted = binary_encode_string (json_str.str()); 5435 return SendPacket (json_str_quoted.c_str()); 5436 } 5437 else 5438 { 5439 SendPacket ("E84"); 5440 } 5441 } 5442 } 5443 } 5444 return SendPacket ("OK"); 5445 } 5446 5447 rnb_err_t 5448 RNBRemote::HandlePacket_qSymbol (const char *command) 5449 { 5450 const char *p = command; 5451 p += strlen ("qSymbol:"); 5452 const char *sep = strchr(p, ':'); 5453 5454 std::string symbol_name; 5455 std::string symbol_value_str; 5456 // Extract the symbol value if there is one 5457 if (sep > p) 5458 symbol_value_str.assign(p, sep - p); 5459 p = sep + 1; 5460 5461 if (*p) 5462 { 5463 // We have a symbol name 5464 symbol_name = std::move(decode_hex_ascii_string(p)); 5465 if (!symbol_value_str.empty()) 5466 { 5467 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5468 if (symbol_name == "dispatch_queue_offsets") 5469 m_dispatch_queue_offsets_addr = symbol_value; 5470 } 5471 ++m_qSymbol_index; 5472 } 5473 else 5474 { 5475 // No symbol name, set our symbol index to zero so we can 5476 // read any symbols that we need 5477 m_qSymbol_index = 0; 5478 } 5479 5480 symbol_name.clear(); 5481 5482 if (m_qSymbol_index == 0) 5483 { 5484 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5485 symbol_name = "dispatch_queue_offsets"; 5486 else 5487 ++m_qSymbol_index; 5488 } 5489 5490 // // Lookup next symbol when we have one... 5491 // if (m_qSymbol_index == 1) 5492 // { 5493 // } 5494 5495 5496 if (symbol_name.empty()) 5497 { 5498 // Done with symbol lookups 5499 return SendPacket ("OK"); 5500 } 5501 else 5502 { 5503 std::ostringstream reply; 5504 reply << "qSymbol:"; 5505 for (size_t i = 0; i < symbol_name.size(); ++i) 5506 reply << RAWHEX8(symbol_name[i]); 5507 return SendPacket (reply.str().c_str()); 5508 } 5509 } 5510 5511 // Note that all numeric values returned by qProcessInfo are hex encoded, 5512 // including the pid and the cpu type. 5513 5514 rnb_err_t 5515 RNBRemote::HandlePacket_qProcessInfo (const char *p) 5516 { 5517 nub_process_t pid; 5518 std::ostringstream rep; 5519 5520 // If we haven't run the process yet, return an error. 5521 if (!m_ctx.HasValidProcessID()) 5522 return SendPacket ("E68"); 5523 5524 pid = m_ctx.ProcessID(); 5525 5526 rep << "pid:" << std::hex << pid << ";"; 5527 5528 int procpid_mib[4]; 5529 procpid_mib[0] = CTL_KERN; 5530 procpid_mib[1] = KERN_PROC; 5531 procpid_mib[2] = KERN_PROC_PID; 5532 procpid_mib[3] = pid; 5533 struct kinfo_proc proc_kinfo; 5534 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 5535 5536 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 5537 { 5538 if (proc_kinfo_size > 0) 5539 { 5540 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";"; 5541 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";"; 5542 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";"; 5543 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";"; 5544 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 5545 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";"; 5546 } 5547 } 5548 5549 cpu_type_t cputype = DNBProcessGetCPUType (pid); 5550 if (cputype == 0) 5551 { 5552 DNBLog ("Unable to get the process cpu_type, making a best guess."); 5553 cputype = best_guess_cpu_type(); 5554 } 5555 5556 if (cputype != 0) 5557 { 5558 rep << "cputype:" << std::hex << cputype << ";"; 5559 } 5560 5561 bool host_cpu_is_64bit = false; 5562 uint32_t is64bit_capable; 5563 size_t is64bit_capable_len = sizeof (is64bit_capable); 5564 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0) 5565 host_cpu_is_64bit = is64bit_capable != 0; 5566 5567 uint32_t cpusubtype; 5568 size_t cpusubtype_len = sizeof(cpusubtype); 5569 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 5570 { 5571 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 5572 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 5573 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype 5574 // for i386... 5575 if (host_cpu_is_64bit) 5576 { 5577 if (cputype == CPU_TYPE_X86) 5578 { 5579 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 5580 } 5581 else if (cputype == CPU_TYPE_ARM) 5582 { 5583 // We can query a process' cputype but we cannot query a process' cpusubtype. 5584 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we 5585 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace) 5586 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 5587 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S 5588 } 5589 } 5590 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 5591 } 5592 5593 // The OS in the triple should be "ios" or "macosx" which doesn't match our 5594 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 5595 // this for now. 5596 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 5597 rep << "ostype:ios;"; 5598 else 5599 { 5600 bool is_ios_simulator = false; 5601 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) 5602 { 5603 // Check for iOS simulator binaries by getting the process argument 5604 // and environment and checking for SIMULATOR_UDID in the environment 5605 int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid }; 5606 5607 uint8_t arg_data[8192]; 5608 size_t arg_data_size = sizeof(arg_data); 5609 if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) 5610 { 5611 DNBDataRef data (arg_data, arg_data_size, false); 5612 DNBDataRef::offset_t offset = 0; 5613 uint32_t argc = data.Get32 (&offset); 5614 const char *cstr; 5615 5616 cstr = data.GetCStr (&offset); 5617 if (cstr) 5618 { 5619 // Skip NULLs 5620 while (1) 5621 { 5622 const char *p = data.PeekCStr(offset); 5623 if ((p == NULL) || (*p != '\0')) 5624 break; 5625 ++offset; 5626 } 5627 // Now skip all arguments 5628 for (uint32_t i = 0; i < argc; ++i) 5629 { 5630 data.GetCStr(&offset); 5631 } 5632 5633 // Now iterate across all environment variables 5634 while ((cstr = data.GetCStr(&offset))) 5635 { 5636 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) 5637 { 5638 is_ios_simulator = true; 5639 break; 5640 } 5641 if (cstr[0] == '\0') 5642 break; 5643 5644 } 5645 } 5646 } 5647 } 5648 if (is_ios_simulator) 5649 rep << "ostype:ios;"; 5650 else 5651 rep << "ostype:macosx;"; 5652 } 5653 5654 rep << "vendor:apple;"; 5655 5656 #if defined (__LITTLE_ENDIAN__) 5657 rep << "endian:little;"; 5658 #elif defined (__BIG_ENDIAN__) 5659 rep << "endian:big;"; 5660 #elif defined (__PDP_ENDIAN__) 5661 rep << "endian:pdp;"; 5662 #endif 5663 5664 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 5665 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5666 kern_return_t kr; 5667 x86_thread_state_t gp_regs; 5668 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 5669 kr = thread_get_state (static_cast<thread_act_t>(thread), 5670 x86_THREAD_STATE, 5671 (thread_state_t) &gp_regs, 5672 &gp_count); 5673 if (kr == KERN_SUCCESS) 5674 { 5675 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 5676 rep << "ptrsize:8;"; 5677 else 5678 rep << "ptrsize:4;"; 5679 } 5680 #elif defined (__arm__) 5681 rep << "ptrsize:4;"; 5682 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE) 5683 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5684 kern_return_t kr; 5685 arm_unified_thread_state_t gp_regs; 5686 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 5687 kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE, 5688 (thread_state_t) &gp_regs, &gp_count); 5689 if (kr == KERN_SUCCESS) 5690 { 5691 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 5692 rep << "ptrsize:8;"; 5693 else 5694 rep << "ptrsize:4;"; 5695 } 5696 #endif 5697 5698 return SendPacket (rep.str()); 5699 } 5700 5701 const RNBRemote::DispatchQueueOffsets * 5702 RNBRemote::GetDispatchQueueOffsets() 5703 { 5704 if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID()) 5705 { 5706 nub_process_t pid = m_ctx.ProcessID(); 5707 nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets); 5708 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 5709 m_dispatch_queue_offsets.Clear(); 5710 } 5711 5712 if (m_dispatch_queue_offsets.IsValid()) 5713 return &m_dispatch_queue_offsets; 5714 else 5715 return nullptr; 5716 } 5717 5718 void 5719 RNBRemote::EnableCompressionNextSendPacket (compression_types type) 5720 { 5721 m_compression_mode = type; 5722 m_enable_compression_next_send_packet = true; 5723 } 5724 5725 compression_types 5726 RNBRemote::GetCompressionType () 5727 { 5728 // The first packet we send back to the debugger after a QEnableCompression request 5729 // should be uncompressed -- so we can indicate whether the compression was enabled 5730 // or not via OK / Enn returns. After that, all packets sent will be using the 5731 // compression protocol. 5732 5733 if (m_enable_compression_next_send_packet) 5734 { 5735 // One time, we send back "None" as our compression type 5736 m_enable_compression_next_send_packet = false; 5737 return compression_types::none; 5738 } 5739 return m_compression_mode; 5740 } 5741