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 (size_t 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 == (size_t)-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 (size_t 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 (size_t 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 (nub_size_t 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 (unsigned long 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 (nub_size_t 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 (unsigned long 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 (void)enable_compression; 3475 3476 // Enable compression when debugserver is running on a watchOS device where communication may be over Bluetooth. 3477 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 3478 enable_compression = true; 3479 #endif 3480 3481 #if defined (HAVE_LIBCOMPRESSION) 3482 // libcompression is weak linked so test if compression_decode_buffer() is available 3483 if (enable_compression && compression_decode_buffer != NULL) 3484 { 3485 strcat (buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;DefaultCompressionMinSize="); 3486 char numbuf[16]; 3487 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3488 numbuf[sizeof (numbuf) - 1] = '\0'; 3489 strcat (buf, numbuf); 3490 } 3491 #elif defined (HAVE_LIBZ) 3492 if (enable_compression) 3493 { 3494 strcat (buf, ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize="); 3495 char numbuf[16]; 3496 snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize); 3497 numbuf[sizeof (numbuf) - 1] = '\0'; 3498 strcat (buf, numbuf); 3499 } 3500 #endif 3501 3502 return SendPacket (buf); 3503 } 3504 3505 /* 3506 vAttach;pid 3507 3508 Attach to a new process with the specified process ID. pid is a hexadecimal integer 3509 identifying the process. If the stub is currently controlling a process, it is 3510 killed. The attached process is stopped.This packet is only available in extended 3511 mode (see extended mode). 3512 3513 Reply: 3514 "ENN" for an error 3515 "Any Stop Reply Packet" for success 3516 */ 3517 3518 rnb_err_t 3519 RNBRemote::HandlePacket_v (const char *p) 3520 { 3521 if (strcmp (p, "vCont;c") == 0) 3522 { 3523 // Simple continue 3524 return RNBRemote::HandlePacket_c("c"); 3525 } 3526 else if (strcmp (p, "vCont;s") == 0) 3527 { 3528 // Simple step 3529 return RNBRemote::HandlePacket_s("s"); 3530 } 3531 else if (strstr (p, "vCont") == p) 3532 { 3533 typedef struct 3534 { 3535 nub_thread_t tid; 3536 char action; 3537 int signal; 3538 } vcont_action_t; 3539 3540 DNBThreadResumeActions thread_actions; 3541 char *c = (char *)(p += strlen("vCont")); 3542 char *c_end = c + strlen(c); 3543 if (*c == '?') 3544 return SendPacket ("vCont;c;C;s;S"); 3545 3546 while (c < c_end && *c == ';') 3547 { 3548 ++c; // Skip the semi-colon 3549 DNBThreadResumeAction thread_action; 3550 thread_action.tid = INVALID_NUB_THREAD; 3551 thread_action.state = eStateInvalid; 3552 thread_action.signal = 0; 3553 thread_action.addr = INVALID_NUB_ADDRESS; 3554 3555 char action = *c++; 3556 3557 switch (action) 3558 { 3559 case 'C': 3560 errno = 0; 3561 thread_action.signal = static_cast<int>(strtoul (c, &c, 16)); 3562 if (errno != 0) 3563 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3564 // Fall through to next case... 3565 3566 case 'c': 3567 // Continue 3568 thread_action.state = eStateRunning; 3569 break; 3570 3571 case 'S': 3572 errno = 0; 3573 thread_action.signal = static_cast<int>(strtoul (c, &c, 16)); 3574 if (errno != 0) 3575 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 3576 // Fall through to next case... 3577 3578 case 's': 3579 // Step 3580 thread_action.state = eStateStepping; 3581 break; 3582 3583 default: 3584 HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet"); 3585 break; 3586 } 3587 if (*c == ':') 3588 { 3589 errno = 0; 3590 thread_action.tid = strtoul (++c, &c, 16); 3591 if (errno != 0) 3592 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet"); 3593 } 3594 3595 thread_actions.Append (thread_action); 3596 } 3597 3598 // If a default action for all other threads wasn't mentioned 3599 // then we should stop the threads 3600 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3601 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize()); 3602 return rnb_success; 3603 } 3604 else if (strstr (p, "vAttach") == p) 3605 { 3606 nub_process_t attach_pid = INVALID_NUB_PROCESS; 3607 char err_str[1024]={'\0'}; 3608 3609 if (strstr (p, "vAttachWait;") == p) 3610 { 3611 p += strlen("vAttachWait;"); 3612 std::string attach_name; 3613 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3614 { 3615 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 3616 } 3617 const bool ignore_existing = true; 3618 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3619 3620 } 3621 else if (strstr (p, "vAttachOrWait;") == p) 3622 { 3623 p += strlen("vAttachOrWait;"); 3624 std::string attach_name; 3625 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3626 { 3627 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt"); 3628 } 3629 const bool ignore_existing = false; 3630 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 3631 } 3632 else if (strstr (p, "vAttachName;") == p) 3633 { 3634 p += strlen("vAttachName;"); 3635 std::string attach_name; 3636 if (!GetProcessNameFrom_vAttach(p, attach_name)) 3637 { 3638 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 3639 } 3640 3641 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str)); 3642 3643 } 3644 else if (strstr (p, "vAttach;") == p) 3645 { 3646 p += strlen("vAttach;"); 3647 char *end = NULL; 3648 attach_pid = static_cast<int>(strtoul (p, &end, 16)); // PID will be in hex, so use base 16 to decode 3649 if (p != end && *end == '\0') 3650 { 3651 // Wait at most 30 second for attach 3652 struct timespec attach_timeout_abstime; 3653 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 3654 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str)); 3655 } 3656 } 3657 else 3658 { 3659 return HandlePacket_UNIMPLEMENTED(p); 3660 } 3661 3662 3663 if (attach_pid != INVALID_NUB_PROCESS) 3664 { 3665 if (m_ctx.ProcessID() != attach_pid) 3666 m_ctx.SetProcessID(attach_pid); 3667 // Send a stop reply packet to indicate we successfully attached! 3668 NotifyThatProcessStopped (); 3669 return rnb_success; 3670 } 3671 else 3672 { 3673 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3674 if (err_str[0]) 3675 m_ctx.LaunchStatus().SetErrorString(err_str); 3676 else 3677 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3678 SendPacket ("E01"); // E01 is our magic error value for attach failed. 3679 DNBLogError ("Attach failed: \"%s\".", err_str); 3680 return rnb_err; 3681 } 3682 } 3683 3684 // All other failures come through here 3685 return HandlePacket_UNIMPLEMENTED(p); 3686 } 3687 3688 /* 'T XX' -- status of thread 3689 Check if the specified thread is alive. 3690 The thread number is in hex? */ 3691 3692 rnb_err_t 3693 RNBRemote::HandlePacket_T (const char *p) 3694 { 3695 p++; 3696 if (p == NULL || *p == '\0') 3697 { 3698 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet"); 3699 } 3700 if (!m_ctx.HasValidProcessID()) 3701 { 3702 return SendPacket ("E15"); 3703 } 3704 errno = 0; 3705 nub_thread_t tid = strtoul (p, NULL, 16); 3706 if (errno != 0 && tid == 0) 3707 { 3708 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet"); 3709 } 3710 3711 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid); 3712 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) 3713 { 3714 return SendPacket ("E16"); 3715 } 3716 3717 return SendPacket ("OK"); 3718 } 3719 3720 3721 rnb_err_t 3722 RNBRemote::HandlePacket_z (const char *p) 3723 { 3724 if (p == NULL || *p == '\0') 3725 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet"); 3726 3727 if (!m_ctx.HasValidProcessID()) 3728 return SendPacket ("E15"); 3729 3730 char packet_cmd = *p++; 3731 char break_type = *p++; 3732 3733 if (*p++ != ',') 3734 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3735 3736 char *c = NULL; 3737 nub_process_t pid = m_ctx.ProcessID(); 3738 errno = 0; 3739 nub_addr_t addr = strtoull (p, &c, 16); 3740 if (errno != 0 && addr == 0) 3741 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet"); 3742 p = c; 3743 if (*p++ != ',') 3744 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3745 3746 errno = 0; 3747 auto byte_size = strtoul (p, &c, 16); 3748 if (errno != 0 && byte_size == 0) 3749 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet"); 3750 3751 if (packet_cmd == 'Z') 3752 { 3753 // set 3754 switch (break_type) 3755 { 3756 case '0': // set software breakpoint 3757 case '1': // set hardware breakpoint 3758 { 3759 // gdb can send multiple Z packets for the same address and 3760 // these calls must be ref counted. 3761 bool hardware = (break_type == '1'); 3762 3763 if (DNBBreakpointSet (pid, addr, byte_size, hardware)) 3764 { 3765 // We successfully created a breakpoint, now lets full out 3766 // a ref count structure with the breakID and add it to our 3767 // map. 3768 return SendPacket ("OK"); 3769 } 3770 else 3771 { 3772 // We failed to set the software breakpoint 3773 return SendPacket ("E09"); 3774 } 3775 } 3776 break; 3777 3778 case '2': // set write watchpoint 3779 case '3': // set read watchpoint 3780 case '4': // set access watchpoint 3781 { 3782 bool hardware = true; 3783 uint32_t watch_flags = 0; 3784 if (break_type == '2') 3785 watch_flags = WATCH_TYPE_WRITE; 3786 else if (break_type == '3') 3787 watch_flags = WATCH_TYPE_READ; 3788 else 3789 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3790 3791 if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware)) 3792 { 3793 return SendPacket ("OK"); 3794 } 3795 else 3796 { 3797 // We failed to set the watchpoint 3798 return SendPacket ("E09"); 3799 } 3800 } 3801 break; 3802 3803 default: 3804 break; 3805 } 3806 } 3807 else if (packet_cmd == 'z') 3808 { 3809 // remove 3810 switch (break_type) 3811 { 3812 case '0': // remove software breakpoint 3813 case '1': // remove hardware breakpoint 3814 if (DNBBreakpointClear (pid, addr)) 3815 { 3816 return SendPacket ("OK"); 3817 } 3818 else 3819 { 3820 return SendPacket ("E08"); 3821 } 3822 break; 3823 3824 case '2': // remove write watchpoint 3825 case '3': // remove read watchpoint 3826 case '4': // remove access watchpoint 3827 if (DNBWatchpointClear (pid, addr)) 3828 { 3829 return SendPacket ("OK"); 3830 } 3831 else 3832 { 3833 return SendPacket ("E08"); 3834 } 3835 break; 3836 3837 default: 3838 break; 3839 } 3840 } 3841 return HandlePacket_UNIMPLEMENTED(p); 3842 } 3843 3844 // Extract the thread number from the thread suffix that might be appended to 3845 // thread specific packets. This will only be enabled if m_thread_suffix_supported 3846 // is true. 3847 nub_thread_t 3848 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p) 3849 { 3850 if (m_thread_suffix_supported) 3851 { 3852 nub_thread_t tid = INVALID_NUB_THREAD; 3853 if (p) 3854 { 3855 const char *tid_cstr = strstr (p, "thread:"); 3856 if (tid_cstr) 3857 { 3858 tid_cstr += strlen ("thread:"); 3859 tid = strtoul(tid_cstr, NULL, 16); 3860 } 3861 } 3862 return tid; 3863 } 3864 return GetCurrentThread(); 3865 3866 } 3867 3868 /* 'p XX' 3869 print the contents of register X */ 3870 3871 rnb_err_t 3872 RNBRemote::HandlePacket_p (const char *p) 3873 { 3874 if (g_num_reg_entries == 0) 3875 InitializeRegisters (); 3876 3877 if (p == NULL || *p == '\0') 3878 { 3879 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3880 } 3881 if (!m_ctx.HasValidProcessID()) 3882 { 3883 return SendPacket ("E15"); 3884 } 3885 nub_process_t pid = m_ctx.ProcessID(); 3886 errno = 0; 3887 char *tid_cstr = NULL; 3888 uint32_t reg = static_cast<uint32_t>(strtoul (p + 1, &tid_cstr, 16)); 3889 if (errno != 0 && reg == 0) 3890 { 3891 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet"); 3892 } 3893 3894 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr); 3895 if (tid == INVALID_NUB_THREAD) 3896 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3897 3898 const register_map_entry_t *reg_entry; 3899 3900 if (reg < g_num_reg_entries) 3901 reg_entry = &g_reg_entries[reg]; 3902 else 3903 reg_entry = NULL; 3904 3905 std::ostringstream ostrm; 3906 if (reg_entry == NULL) 3907 { 3908 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg); 3909 ostrm << "00000000"; 3910 } 3911 else if (reg_entry->nub_info.reg == (uint32_t)-1) 3912 { 3913 if (reg_entry->nub_info.size > 0) 3914 { 3915 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 3916 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 3917 } 3918 } 3919 else 3920 { 3921 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL); 3922 } 3923 return SendPacket (ostrm.str()); 3924 } 3925 3926 /* 'Pnn=rrrrr' 3927 Set register number n to value r. 3928 n and r are hex strings. */ 3929 3930 rnb_err_t 3931 RNBRemote::HandlePacket_P (const char *p) 3932 { 3933 if (g_num_reg_entries == 0) 3934 InitializeRegisters (); 3935 3936 if (p == NULL || *p == '\0') 3937 { 3938 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet"); 3939 } 3940 if (!m_ctx.HasValidProcessID()) 3941 { 3942 return SendPacket ("E28"); 3943 } 3944 3945 nub_process_t pid = m_ctx.ProcessID(); 3946 3947 StringExtractor packet (p); 3948 3949 const char cmd_char = packet.GetChar(); 3950 // Register ID is always in big endian 3951 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX); 3952 const char equal_char = packet.GetChar(); 3953 3954 if (cmd_char != 'P') 3955 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet"); 3956 3957 if (reg == UINT32_MAX) 3958 return SendPacket ("E29"); 3959 3960 if (equal_char != '=') 3961 return SendPacket ("E30"); 3962 3963 const register_map_entry_t *reg_entry; 3964 3965 if (reg >= g_num_reg_entries) 3966 return SendPacket("E47"); 3967 3968 reg_entry = &g_reg_entries[reg]; 3969 3970 if (reg_entry->nub_info.set == (uint32_t)-1 && reg_entry->nub_info.reg == (uint32_t)-1) 3971 { 3972 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); 3973 return SendPacket("E48"); 3974 } 3975 3976 DNBRegisterValue reg_value; 3977 reg_value.info = reg_entry->nub_info; 3978 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 3979 3980 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3981 if (tid == INVALID_NUB_THREAD) 3982 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3983 3984 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 3985 { 3986 return SendPacket ("E32"); 3987 } 3988 return SendPacket ("OK"); 3989 } 3990 3991 /* 'c [addr]' 3992 Continue, optionally from a specified address. */ 3993 3994 rnb_err_t 3995 RNBRemote::HandlePacket_c (const char *p) 3996 { 3997 const nub_process_t pid = m_ctx.ProcessID(); 3998 3999 if (pid == INVALID_NUB_PROCESS) 4000 return SendPacket ("E23"); 4001 4002 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 4003 4004 if (*(p + 1) != '\0') 4005 { 4006 action.tid = GetContinueThread(); 4007 errno = 0; 4008 action.addr = strtoull (p + 1, NULL, 16); 4009 if (errno != 0 && action.addr == 0) 4010 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet"); 4011 } 4012 4013 DNBThreadResumeActions thread_actions; 4014 thread_actions.Append(action); 4015 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 4016 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4017 return SendPacket ("E25"); 4018 // Don't send an "OK" packet; response is the stopped/exited message. 4019 return rnb_success; 4020 } 4021 4022 rnb_err_t 4023 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) 4024 { 4025 /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code) 4026 for the memory region containing a given address and return that information. 4027 4028 Users of this packet must be prepared for three results: 4029 4030 Region information is returned 4031 Region information is unavailable for this address because the address is in unmapped memory 4032 Region lookup cannot be performed on this platform or process is not yet launched 4033 This packet isn't implemented 4034 4035 Examples of use: 4036 qMemoryRegionInfo:3a55140 4037 start:3a50000,size:100000,permissions:rwx 4038 4039 qMemoryRegionInfo:0 4040 error:address in unmapped region 4041 4042 qMemoryRegionInfo:3a551140 (on a different platform) 4043 error:region lookup cannot be performed 4044 4045 qMemoryRegionInfo 4046 OK // this packet is implemented by the remote nub 4047 */ 4048 4049 p += sizeof ("qMemoryRegionInfo") - 1; 4050 if (*p == '\0') 4051 return SendPacket ("OK"); 4052 if (*p++ != ':') 4053 return SendPacket ("E67"); 4054 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 4055 p += 2; 4056 4057 errno = 0; 4058 uint64_t address = strtoul (p, NULL, 16); 4059 if (errno != 0 && address == 0) 4060 { 4061 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 4062 } 4063 4064 DNBRegionInfo region_info = { 0, 0, 0 }; 4065 DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); 4066 std::ostringstream ostrm; 4067 4068 // start:3a50000,size:100000,permissions:rwx 4069 ostrm << "start:" << std::hex << region_info.addr << ';'; 4070 4071 if (region_info.size > 0) 4072 ostrm << "size:" << std::hex << region_info.size << ';'; 4073 4074 if (region_info.permissions) 4075 { 4076 ostrm << "permissions:"; 4077 4078 if (region_info.permissions & eMemoryPermissionsReadable) 4079 ostrm << 'r'; 4080 if (region_info.permissions & eMemoryPermissionsWritable) 4081 ostrm << 'w'; 4082 if (region_info.permissions & eMemoryPermissionsExecutable) 4083 ostrm << 'x'; 4084 ostrm << ';'; 4085 } 4086 return SendPacket (ostrm.str()); 4087 } 4088 4089 // qGetProfileData;scan_type:0xYYYYYYY 4090 rnb_err_t 4091 RNBRemote::HandlePacket_GetProfileData (const char *p) 4092 { 4093 nub_process_t pid = m_ctx.ProcessID(); 4094 if (pid == INVALID_NUB_PROCESS) 4095 return SendPacket ("OK"); 4096 4097 StringExtractor packet(p += sizeof ("qGetProfileData")); 4098 DNBProfileDataScanType scan_type = eProfileAll; 4099 std::string name; 4100 std::string value; 4101 while (packet.GetNameColonValue(name, value)) 4102 { 4103 if (name.compare ("scan_type") == 0) 4104 { 4105 std::istringstream iss(value); 4106 uint32_t int_value = 0; 4107 if (iss >> std::hex >> int_value) 4108 { 4109 scan_type = (DNBProfileDataScanType)int_value; 4110 } 4111 } 4112 } 4113 4114 std::string data = DNBProcessGetProfileData(pid, scan_type); 4115 if (!data.empty()) 4116 { 4117 return SendPacket (data.c_str()); 4118 } 4119 else 4120 { 4121 return SendPacket ("OK"); 4122 } 4123 } 4124 4125 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 4126 rnb_err_t 4127 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p) 4128 { 4129 nub_process_t pid = m_ctx.ProcessID(); 4130 if (pid == INVALID_NUB_PROCESS) 4131 return SendPacket ("OK"); 4132 4133 StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling")); 4134 bool enable = false; 4135 uint64_t interval_usec = 0; 4136 DNBProfileDataScanType scan_type = eProfileAll; 4137 std::string name; 4138 std::string value; 4139 while (packet.GetNameColonValue(name, value)) 4140 { 4141 if (name.compare ("enable") == 0) 4142 { 4143 enable = strtoul(value.c_str(), NULL, 10) > 0; 4144 } 4145 else if (name.compare ("interval_usec") == 0) 4146 { 4147 interval_usec = strtoul(value.c_str(), NULL, 10); 4148 } 4149 else if (name.compare ("scan_type") == 0) 4150 { 4151 std::istringstream iss(value); 4152 uint32_t int_value = 0; 4153 if (iss >> std::hex >> int_value) 4154 { 4155 scan_type = (DNBProfileDataScanType)int_value; 4156 } 4157 } 4158 } 4159 4160 if (interval_usec == 0) 4161 { 4162 enable = 0; 4163 } 4164 4165 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 4166 return SendPacket ("OK"); 4167 } 4168 4169 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO COMPRESS>; 4170 // 4171 // type: must be a type previously reported by the qXfer:features: SupportedCompressions list 4172 // 4173 // minsize: is optional; by default the qXfer:features: DefaultCompressionMinSize value is used 4174 // debugserver may have a better idea of what a good minimum packet size to compress is than lldb. 4175 4176 rnb_err_t 4177 RNBRemote::HandlePacket_QEnableCompression (const char *p) 4178 { 4179 p += sizeof ("QEnableCompression:") - 1; 4180 4181 size_t new_compression_minsize = m_compression_minsize; 4182 const char *new_compression_minsize_str = strstr (p, "minsize:"); 4183 if (new_compression_minsize_str) 4184 { 4185 new_compression_minsize_str += strlen ("minsize:"); 4186 errno = 0; 4187 new_compression_minsize = strtoul (new_compression_minsize_str, NULL, 10); 4188 if (errno != 0 || new_compression_minsize == ULONG_MAX) 4189 { 4190 new_compression_minsize = m_compression_minsize; 4191 } 4192 } 4193 4194 #if defined (HAVE_LIBCOMPRESSION) 4195 if (compression_decode_buffer != NULL) 4196 { 4197 if (strstr (p, "type:zlib-deflate;") != nullptr) 4198 { 4199 EnableCompressionNextSendPacket (compression_types::zlib_deflate); 4200 m_compression_minsize = new_compression_minsize; 4201 return SendPacket ("OK"); 4202 } 4203 else if (strstr (p, "type:lz4;") != nullptr) 4204 { 4205 EnableCompressionNextSendPacket (compression_types::lz4); 4206 m_compression_minsize = new_compression_minsize; 4207 return SendPacket ("OK"); 4208 } 4209 else if (strstr (p, "type:lzma;") != nullptr) 4210 { 4211 EnableCompressionNextSendPacket (compression_types::lzma); 4212 m_compression_minsize = new_compression_minsize; 4213 return SendPacket ("OK"); 4214 } 4215 else if (strstr (p, "type:lzfse;") != nullptr) 4216 { 4217 EnableCompressionNextSendPacket (compression_types::lzfse); 4218 m_compression_minsize = new_compression_minsize; 4219 return SendPacket ("OK"); 4220 } 4221 } 4222 #endif 4223 4224 #if defined (HAVE_LIBZ) 4225 if (strstr (p, "type:zlib-deflate;") != nullptr) 4226 { 4227 EnableCompressionNextSendPacket (compression_types::zlib_deflate); 4228 m_compression_minsize = new_compression_minsize; 4229 return SendPacket ("OK"); 4230 } 4231 #endif 4232 4233 return SendPacket ("E88"); 4234 } 4235 4236 rnb_err_t 4237 RNBRemote::HandlePacket_qSpeedTest (const char *p) 4238 { 4239 p += strlen ("qSpeedTest:response_size:"); 4240 char *end = NULL; 4241 errno = 0; 4242 uint64_t response_size = ::strtoul (p, &end, 16); 4243 if (errno != 0) 4244 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Didn't find response_size value at right offset"); 4245 else if (*end == ';') 4246 { 4247 static char g_data[4*1024*1024+16] = "data:"; 4248 memset(g_data + 5, 'a', response_size); 4249 g_data[response_size + 5] = '\0'; 4250 return SendPacket (g_data); 4251 } 4252 else 4253 { 4254 return SendPacket ("E79"); 4255 } 4256 } 4257 4258 rnb_err_t 4259 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p) 4260 { 4261 /* This packet simply returns the number of supported hardware watchpoints. 4262 4263 Examples of use: 4264 qWatchpointSupportInfo: 4265 num:4 4266 4267 qWatchpointSupportInfo 4268 OK // this packet is implemented by the remote nub 4269 */ 4270 4271 p += sizeof ("qWatchpointSupportInfo") - 1; 4272 if (*p == '\0') 4273 return SendPacket ("OK"); 4274 if (*p++ != ':') 4275 return SendPacket ("E67"); 4276 4277 errno = 0; 4278 uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID()); 4279 std::ostringstream ostrm; 4280 4281 // size:4 4282 ostrm << "num:" << std::dec << num << ';'; 4283 return SendPacket (ostrm.str()); 4284 } 4285 4286 /* 'C sig [;addr]' 4287 Resume with signal sig, optionally at address addr. */ 4288 4289 rnb_err_t 4290 RNBRemote::HandlePacket_C (const char *p) 4291 { 4292 const nub_process_t pid = m_ctx.ProcessID(); 4293 4294 if (pid == INVALID_NUB_PROCESS) 4295 return SendPacket ("E36"); 4296 4297 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 4298 int process_signo = -1; 4299 if (*(p + 1) != '\0') 4300 { 4301 action.tid = GetContinueThread(); 4302 char *end = NULL; 4303 errno = 0; 4304 process_signo = static_cast<int>(strtoul (p + 1, &end, 16)); 4305 if (errno != 0) 4306 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet"); 4307 else if (*end == ';') 4308 { 4309 errno = 0; 4310 action.addr = strtoull (end + 1, NULL, 16); 4311 if (errno != 0 && action.addr == 0) 4312 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet"); 4313 } 4314 } 4315 4316 DNBThreadResumeActions thread_actions; 4317 thread_actions.Append (action); 4318 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal); 4319 if (!DNBProcessSignal(pid, process_signo)) 4320 return SendPacket ("E52"); 4321 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4322 return SendPacket ("E38"); 4323 /* Don't send an "OK" packet; response is the stopped/exited message. */ 4324 return rnb_success; 4325 } 4326 4327 //---------------------------------------------------------------------- 4328 // 'D' packet 4329 // Detach from gdb. 4330 //---------------------------------------------------------------------- 4331 rnb_err_t 4332 RNBRemote::HandlePacket_D (const char *p) 4333 { 4334 if (m_ctx.HasValidProcessID()) 4335 { 4336 if (DNBProcessDetach(m_ctx.ProcessID())) 4337 SendPacket ("OK"); 4338 else 4339 SendPacket ("E"); 4340 } 4341 else 4342 { 4343 SendPacket ("E"); 4344 } 4345 return rnb_success; 4346 } 4347 4348 /* 'k' 4349 Kill the inferior process. */ 4350 4351 rnb_err_t 4352 RNBRemote::HandlePacket_k (const char *p) 4353 { 4354 DNBLog ("Got a 'k' packet, killing the inferior process."); 4355 // No response to should be sent to the kill packet 4356 if (m_ctx.HasValidProcessID()) 4357 DNBProcessKill (m_ctx.ProcessID()); 4358 SendPacket ("X09"); 4359 return rnb_success; 4360 } 4361 4362 rnb_err_t 4363 RNBRemote::HandlePacket_stop_process (const char *p) 4364 { 4365 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt 4366 #if defined(TEST_EXIT_ON_INTERRUPT) 4367 rnb_err_t err = HandlePacket_k (p); 4368 m_comm.Disconnect(true); 4369 return err; 4370 #else 4371 if (!DNBProcessInterrupt(m_ctx.ProcessID())) 4372 { 4373 // If we failed to interrupt the process, then send a stop 4374 // reply packet as the process was probably already stopped 4375 HandlePacket_last_signal (NULL); 4376 } 4377 return rnb_success; 4378 #endif 4379 } 4380 4381 /* 's' 4382 Step the inferior process. */ 4383 4384 rnb_err_t 4385 RNBRemote::HandlePacket_s (const char *p) 4386 { 4387 const nub_process_t pid = m_ctx.ProcessID(); 4388 if (pid == INVALID_NUB_PROCESS) 4389 return SendPacket ("E32"); 4390 4391 // Hardware supported stepping not supported on arm 4392 nub_thread_t tid = GetContinueThread (); 4393 if (tid == 0 || tid == (nub_thread_t)-1) 4394 tid = GetCurrentThread(); 4395 4396 if (tid == INVALID_NUB_THREAD) 4397 return SendPacket ("E33"); 4398 4399 DNBThreadResumeActions thread_actions; 4400 thread_actions.AppendAction(tid, eStateStepping); 4401 4402 // Make all other threads stop when we are stepping 4403 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 4404 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4405 return SendPacket ("E49"); 4406 // Don't send an "OK" packet; response is the stopped/exited message. 4407 return rnb_success; 4408 } 4409 4410 /* 'S sig [;addr]' 4411 Step with signal sig, optionally at address addr. */ 4412 4413 rnb_err_t 4414 RNBRemote::HandlePacket_S (const char *p) 4415 { 4416 const nub_process_t pid = m_ctx.ProcessID(); 4417 if (pid == INVALID_NUB_PROCESS) 4418 return SendPacket ("E36"); 4419 4420 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 4421 4422 if (*(p + 1) != '\0') 4423 { 4424 char *end = NULL; 4425 errno = 0; 4426 action.signal = static_cast<int>(strtoul (p + 1, &end, 16)); 4427 if (errno != 0) 4428 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 4429 else if (*end == ';') 4430 { 4431 errno = 0; 4432 action.addr = strtoull (end + 1, NULL, 16); 4433 if (errno != 0 && action.addr == 0) 4434 { 4435 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 4436 } 4437 } 4438 } 4439 4440 action.tid = GetContinueThread (); 4441 if (action.tid == 0 || action.tid == (nub_thread_t)-1) 4442 return SendPacket ("E40"); 4443 4444 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 4445 if (tstate == eStateInvalid || tstate == eStateExited) 4446 return SendPacket ("E37"); 4447 4448 4449 DNBThreadResumeActions thread_actions; 4450 thread_actions.Append (action); 4451 4452 // Make all other threads stop when we are stepping 4453 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 4454 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 4455 return SendPacket ("E39"); 4456 4457 // Don't send an "OK" packet; response is the stopped/exited message. 4458 return rnb_success; 4459 } 4460 4461 static const char * 4462 GetArchName (const uint32_t cputype, const uint32_t cpusubtype) 4463 { 4464 switch (cputype) 4465 { 4466 case CPU_TYPE_ARM: 4467 switch (cpusubtype) 4468 { 4469 case 5: return "armv4"; 4470 case 6: return "armv6"; 4471 case 7: return "armv5t"; 4472 case 8: return "xscale"; 4473 case 9: return "armv7"; 4474 case 10: return "armv7f"; 4475 case 11: return "armv7s"; 4476 case 12: return "armv7k"; 4477 case 14: return "armv6m"; 4478 case 15: return "armv7m"; 4479 case 16: return "armv7em"; 4480 default: return "arm"; 4481 } 4482 break; 4483 case CPU_TYPE_ARM64: return "arm64"; 4484 case CPU_TYPE_I386: return "i386"; 4485 case CPU_TYPE_X86_64: 4486 switch (cpusubtype) 4487 { 4488 default: return "x86_64"; 4489 case 8: return "x86_64h"; 4490 } 4491 break; 4492 } 4493 return NULL; 4494 } 4495 4496 static bool 4497 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64) 4498 { 4499 static uint32_t g_host_cputype = 0; 4500 static uint32_t g_host_cpusubtype = 0; 4501 static uint32_t g_is_64_bit_capable = 0; 4502 static bool g_promoted_to_64 = false; 4503 4504 if (g_host_cputype == 0) 4505 { 4506 g_promoted_to_64 = false; 4507 size_t len = sizeof(uint32_t); 4508 if (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0) 4509 { 4510 len = sizeof (uint32_t); 4511 if (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0) 4512 { 4513 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0)) 4514 { 4515 g_promoted_to_64 = true; 4516 g_host_cputype |= CPU_ARCH_ABI64; 4517 } 4518 } 4519 } 4520 4521 len = sizeof(uint32_t); 4522 if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0) 4523 { 4524 if (g_promoted_to_64 && 4525 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486) 4526 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL; 4527 } 4528 } 4529 4530 cputype = g_host_cputype; 4531 cpusubtype = g_host_cpusubtype; 4532 is_64_bit_capable = g_is_64_bit_capable; 4533 promoted_to_64 = g_promoted_to_64; 4534 return g_host_cputype != 0; 4535 } 4536 4537 rnb_err_t 4538 RNBRemote::HandlePacket_qHostInfo (const char *p) 4539 { 4540 std::ostringstream strm; 4541 4542 uint32_t cputype = 0; 4543 uint32_t cpusubtype = 0; 4544 uint32_t is_64_bit_capable = 0; 4545 bool promoted_to_64 = false; 4546 if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64)) 4547 { 4548 strm << "cputype:" << std::dec << cputype << ';'; 4549 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 4550 } 4551 4552 // The OS in the triple should be "ios" or "macosx" which doesn't match our 4553 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 4554 // this for now. 4555 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 4556 { 4557 strm << "ostype:ios;"; 4558 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 4559 strm << "watchpoint_exceptions_received:before;"; 4560 } 4561 else 4562 { 4563 strm << "ostype:macosx;"; 4564 strm << "watchpoint_exceptions_received:after;"; 4565 } 4566 // char ostype[64]; 4567 // len = sizeof(ostype); 4568 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 4569 // { 4570 // len = strlen(ostype); 4571 // std::transform (ostype, ostype + len, ostype, tolower); 4572 // strm << "ostype:" << std::dec << ostype << ';'; 4573 // } 4574 4575 strm << "vendor:apple;"; 4576 4577 #if defined (__LITTLE_ENDIAN__) 4578 strm << "endian:little;"; 4579 #elif defined (__BIG_ENDIAN__) 4580 strm << "endian:big;"; 4581 #elif defined (__PDP_ENDIAN__) 4582 strm << "endian:pdp;"; 4583 #endif 4584 4585 if (promoted_to_64) 4586 strm << "ptrsize:8;"; 4587 else 4588 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 4589 return SendPacket (strm.str()); 4590 } 4591 4592 void 4593 XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes) 4594 { 4595 if (indent) 4596 s << INDENT_WITH_SPACES(indent); 4597 s << '<' << name; 4598 if (!has_attributes) 4599 s << '>' << std::endl; 4600 } 4601 4602 void 4603 XMLElementStartEndAttributes (std::ostringstream &s, bool empty) 4604 { 4605 if (empty) 4606 s << '/'; 4607 s << '>' << std::endl; 4608 } 4609 4610 void 4611 XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name) 4612 { 4613 if (indent) 4614 s << INDENT_WITH_SPACES(indent); 4615 s << '<' << '/' << name << '>' << std::endl; 4616 } 4617 4618 void 4619 XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true) 4620 { 4621 if (value) 4622 { 4623 if (indent) 4624 s << INDENT_WITH_SPACES(indent); 4625 s << '<' << name << '>' << value; 4626 if (close) 4627 XMLElementEnd(s, 0, name); 4628 } 4629 } 4630 4631 void 4632 XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true) 4633 { 4634 if (indent) 4635 s << INDENT_WITH_SPACES(indent); 4636 4637 s << '<' << name << '>' << DECIMAL << value; 4638 if (close) 4639 XMLElementEnd(s, 0, name); 4640 } 4641 4642 void 4643 XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL) 4644 { 4645 if (value) 4646 { 4647 if (default_value && strcmp(value, default_value) == 0) 4648 return; // No need to emit the attribute because it matches the default value 4649 s <<' ' << name << "=\"" << value << "\""; 4650 } 4651 } 4652 4653 void 4654 XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value) 4655 { 4656 s <<' ' << name << "=\"" << DECIMAL << value << "\""; 4657 } 4658 4659 void 4660 GenerateTargetXMLRegister (std::ostringstream &s, 4661 const uint32_t reg_num, 4662 nub_size_t num_reg_sets, 4663 const DNBRegisterSetInfo *reg_set_info, 4664 const register_map_entry_t ®) 4665 { 4666 const char *default_lldb_encoding = "uint"; 4667 const char *lldb_encoding = default_lldb_encoding; 4668 const char *gdb_group = "general"; 4669 const char *default_gdb_type = "int"; 4670 const char *gdb_type = default_gdb_type; 4671 const char *default_lldb_format = "hex"; 4672 const char *lldb_format = default_lldb_format; 4673 const char *lldb_set = NULL; 4674 4675 switch (reg.nub_info.type) 4676 { 4677 case Uint: lldb_encoding = "uint"; break; 4678 case Sint: lldb_encoding = "sint"; break; 4679 case IEEE754: lldb_encoding = "ieee754"; if (reg.nub_info.set > 0) gdb_group = "float"; break; 4680 case Vector: lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break; 4681 } 4682 4683 switch (reg.nub_info.format) 4684 { 4685 case Binary: lldb_format = "binary"; break; 4686 case Decimal: lldb_format = "decimal"; break; 4687 case Hex: lldb_format = "hex"; break; 4688 case Float: gdb_type = "float"; lldb_format = "float"; break; 4689 case VectorOfSInt8: gdb_type = "float"; lldb_format = "vector-sint8"; break; 4690 case VectorOfUInt8: gdb_type = "float"; lldb_format = "vector-uint8"; break; 4691 case VectorOfSInt16: gdb_type = "float"; lldb_format = "vector-sint16"; break; 4692 case VectorOfUInt16: gdb_type = "float"; lldb_format = "vector-uint16"; break; 4693 case VectorOfSInt32: gdb_type = "float"; lldb_format = "vector-sint32"; break; 4694 case VectorOfUInt32: gdb_type = "float"; lldb_format = "vector-uint32"; break; 4695 case VectorOfFloat32: gdb_type = "float"; lldb_format = "vector-float32"; break; 4696 case VectorOfUInt128: gdb_type = "float"; lldb_format = "vector-uint128"; break; 4697 }; 4698 if (reg_set_info && reg.nub_info.set < num_reg_sets) 4699 lldb_set = reg_set_info[reg.nub_info.set].name; 4700 4701 uint32_t indent = 2; 4702 4703 XMLElementStart(s, indent, "reg", true); 4704 XMLAttributeString(s, "name", reg.nub_info.name); 4705 XMLAttributeUnsignedDecimal(s, "regnum", reg_num); 4706 XMLAttributeUnsignedDecimal(s, "offset", reg.offset); 4707 XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8); 4708 XMLAttributeString(s, "group", gdb_group); 4709 XMLAttributeString(s, "type", gdb_type, default_gdb_type); 4710 XMLAttributeString (s, "altname", reg.nub_info.alt); 4711 XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding); 4712 XMLAttributeString(s, "format", lldb_format, default_lldb_format); 4713 XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set); 4714 if (reg.nub_info.reg_gcc != INVALID_NUB_REGNUM) 4715 XMLAttributeUnsignedDecimal(s, "gcc_regnum", reg.nub_info.reg_gcc); 4716 if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM) 4717 XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf); 4718 4719 const char *lldb_generic = NULL; 4720 switch (reg.nub_info.reg_generic) 4721 { 4722 case GENERIC_REGNUM_FP: lldb_generic = "fp"; break; 4723 case GENERIC_REGNUM_PC: lldb_generic = "pc"; break; 4724 case GENERIC_REGNUM_SP: lldb_generic = "sp"; break; 4725 case GENERIC_REGNUM_RA: lldb_generic = "ra"; break; 4726 case GENERIC_REGNUM_FLAGS: lldb_generic = "flags"; break; 4727 case GENERIC_REGNUM_ARG1: lldb_generic = "arg1"; break; 4728 case GENERIC_REGNUM_ARG2: lldb_generic = "arg2"; break; 4729 case GENERIC_REGNUM_ARG3: lldb_generic = "arg3"; break; 4730 case GENERIC_REGNUM_ARG4: lldb_generic = "arg4"; break; 4731 case GENERIC_REGNUM_ARG5: lldb_generic = "arg5"; break; 4732 case GENERIC_REGNUM_ARG6: lldb_generic = "arg6"; break; 4733 case GENERIC_REGNUM_ARG7: lldb_generic = "arg7"; break; 4734 case GENERIC_REGNUM_ARG8: lldb_generic = "arg8"; break; 4735 default: break; 4736 } 4737 XMLAttributeString(s, "generic", lldb_generic); 4738 4739 4740 bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty(); 4741 if (!empty) 4742 { 4743 if (!reg.value_regnums.empty()) 4744 { 4745 std::ostringstream regnums; 4746 bool first = true; 4747 regnums << DECIMAL; 4748 for (auto regnum : reg.value_regnums) 4749 { 4750 if (!first) 4751 regnums << ','; 4752 regnums << regnum; 4753 first = false; 4754 } 4755 XMLAttributeString(s, "value_regnums", regnums.str().c_str()); 4756 } 4757 4758 if (!reg.invalidate_regnums.empty()) 4759 { 4760 std::ostringstream regnums; 4761 bool first = true; 4762 regnums << DECIMAL; 4763 for (auto regnum : reg.invalidate_regnums) 4764 { 4765 if (!first) 4766 regnums << ','; 4767 regnums << regnum; 4768 first = false; 4769 } 4770 XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str()); 4771 } 4772 } 4773 XMLElementStartEndAttributes(s, true); 4774 } 4775 4776 void 4777 GenerateTargetXMLRegisters (std::ostringstream &s) 4778 { 4779 nub_size_t num_reg_sets = 0; 4780 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets); 4781 4782 4783 uint32_t cputype = DNBGetRegisterCPUType(); 4784 if (cputype) 4785 { 4786 XMLElementStart(s, 0, "feature", true); 4787 std::ostringstream name_strm; 4788 name_strm << "com.apple.debugserver." << GetArchName (cputype, 0); 4789 XMLAttributeString(s, "name", name_strm.str().c_str()); 4790 XMLElementStartEndAttributes(s, false); 4791 for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num) 4792 // for (const auto ®: g_dynamic_register_map) 4793 { 4794 GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]); 4795 } 4796 XMLElementEnd(s, 0, "feature"); 4797 4798 if (num_reg_sets > 0) 4799 { 4800 XMLElementStart(s, 0, "groups", false); 4801 for (uint32_t set=1; set<num_reg_sets; ++set) 4802 { 4803 XMLElementStart(s, 2, "group", true); 4804 XMLAttributeUnsignedDecimal(s, "id", set); 4805 XMLAttributeString(s, "name", reg_sets[set].name); 4806 XMLElementStartEndAttributes(s, true); 4807 } 4808 XMLElementEnd(s, 0, "groups"); 4809 } 4810 } 4811 } 4812 4813 static const char *g_target_xml_header = R"(<?xml version="1.0"?> 4814 <target version="1.0">)"; 4815 4816 static const char *g_target_xml_footer = "</target>"; 4817 4818 static std::string g_target_xml; 4819 4820 void 4821 UpdateTargetXML () 4822 { 4823 std::ostringstream s; 4824 s << g_target_xml_header << std::endl; 4825 4826 // Set the architecture 4827 //s << "<architecture>" << arch "</architecture>" << std::endl; 4828 4829 // Set the OSABI 4830 //s << "<osabi>abi-name</osabi>" 4831 4832 GenerateTargetXMLRegisters(s); 4833 4834 s << g_target_xml_footer << std::endl; 4835 4836 // Save the XML output in case it gets retrieved in chunks 4837 g_target_xml = s.str(); 4838 } 4839 4840 rnb_err_t 4841 RNBRemote::HandlePacket_qXfer (const char *command) 4842 { 4843 const char *p = command; 4844 p += strlen ("qXfer:"); 4845 const char *sep = strchr(p, ':'); 4846 if (sep) 4847 { 4848 std::string object(p, sep - p); // "auxv", "backtrace", "features", etc 4849 p = sep + 1; 4850 sep = strchr(p, ':'); 4851 if (sep) 4852 { 4853 std::string rw(p, sep - p); // "read" or "write" 4854 p = sep + 1; 4855 sep = strchr(p, ':'); 4856 if (sep) 4857 { 4858 std::string annex(p, sep - p); // "read" or "write" 4859 4860 p = sep + 1; 4861 sep = strchr(p, ','); 4862 if (sep) 4863 { 4864 std::string offset_str(p, sep - p); // read the length as a string 4865 p = sep + 1; 4866 std::string length_str(p); // read the offset as a string 4867 char *end = nullptr; 4868 const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset 4869 if (*end == '\0') 4870 { 4871 const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length 4872 if (*end == '\0') 4873 { 4874 if (object == "features" && 4875 rw == "read" && 4876 annex == "target.xml") 4877 { 4878 std::ostringstream xml_out; 4879 4880 if (offset == 0) 4881 { 4882 InitializeRegisters (true); 4883 4884 UpdateTargetXML(); 4885 if (g_target_xml.empty()) 4886 return SendPacket("E83"); 4887 4888 if (length > g_target_xml.size()) 4889 { 4890 xml_out << 'l'; // No more data 4891 xml_out << binary_encode_string(g_target_xml); 4892 } 4893 else 4894 { 4895 xml_out << 'm'; // More data needs to be read with a subsequent call 4896 xml_out << binary_encode_string(std::string(g_target_xml, offset, length)); 4897 } 4898 } 4899 else 4900 { 4901 // Retrieving target XML in chunks 4902 if (offset < g_target_xml.size()) 4903 { 4904 std::string chunk(g_target_xml, offset, length); 4905 if (chunk.size() < length) 4906 xml_out << 'l'; // No more data 4907 else 4908 xml_out << 'm'; // More data needs to be read with a subsequent call 4909 xml_out << binary_encode_string(chunk.data()); 4910 } 4911 } 4912 return SendPacket(xml_out.str()); 4913 } 4914 // Well formed, put not supported 4915 return HandlePacket_UNIMPLEMENTED (command); 4916 } 4917 } 4918 } 4919 } 4920 else 4921 { 4922 SendPacket ("E85"); 4923 } 4924 } 4925 else 4926 { 4927 SendPacket ("E86"); 4928 } 4929 } 4930 return SendPacket ("E82"); 4931 } 4932 4933 4934 rnb_err_t 4935 RNBRemote::HandlePacket_qGDBServerVersion (const char *p) 4936 { 4937 std::ostringstream strm; 4938 4939 #if defined(DEBUGSERVER_PROGRAM_NAME) 4940 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 4941 #else 4942 strm << "name:debugserver;"; 4943 #endif 4944 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 4945 4946 return SendPacket (strm.str()); 4947 } 4948 4949 // A helper function that retrieves a single integer value from 4950 // a one-level-deep JSON dictionary of key-value pairs. e.g. 4951 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}] 4952 // 4953 uint64_t 4954 get_integer_value_for_key_name_from_json (const char *key, const char *json_string) 4955 { 4956 uint64_t retval = INVALID_NUB_ADDRESS; 4957 std::string key_with_quotes = "\""; 4958 key_with_quotes += key; 4959 key_with_quotes += "\""; 4960 const char *c = strstr (json_string, key_with_quotes.c_str()); 4961 if (c) 4962 { 4963 c += key_with_quotes.size(); 4964 4965 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 4966 c++; 4967 4968 if (*c == ':') 4969 { 4970 c++; 4971 4972 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) 4973 c++; 4974 4975 errno = 0; 4976 retval = strtoul (c, NULL, 10); 4977 if (errno != 0) 4978 { 4979 retval = INVALID_NUB_ADDRESS; 4980 } 4981 } 4982 } 4983 return retval; 4984 4985 } 4986 4987 JSONGenerator::ObjectSP 4988 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) 4989 { 4990 JSONGenerator::ArraySP threads_array_sp; 4991 if (m_ctx.HasValidProcessID()) 4992 { 4993 threads_array_sp.reset(new JSONGenerator::Array()); 4994 4995 nub_process_t pid = m_ctx.ProcessID(); 4996 4997 nub_size_t numthreads = DNBProcessGetNumThreads (pid); 4998 for (nub_size_t i = 0; i < numthreads; ++i) 4999 { 5000 nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i); 5001 5002 struct DNBThreadStopInfo tid_stop_info; 5003 5004 const bool stop_info_valid = DNBThreadGetStopReason (pid, tid, &tid_stop_info); 5005 5006 // If we are doing stop info only, then we only show threads that have a 5007 // valid stop reason 5008 if (threads_with_valid_stop_info_only) 5009 { 5010 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid) 5011 continue; 5012 } 5013 5014 JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary()); 5015 thread_dict_sp->AddIntegerItem("tid", tid); 5016 5017 std::string reason_value("none"); 5018 5019 if (stop_info_valid) 5020 { 5021 switch (tid_stop_info.reason) 5022 { 5023 case eStopTypeInvalid: 5024 break; 5025 5026 case eStopTypeSignal: 5027 if (tid_stop_info.details.signal.signo != 0) 5028 { 5029 thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo); 5030 reason_value = "signal"; 5031 } 5032 break; 5033 5034 case eStopTypeException: 5035 if (tid_stop_info.details.exception.type != 0) 5036 { 5037 reason_value = "exception"; 5038 thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type); 5039 JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array()); 5040 for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i) 5041 { 5042 medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i]))); 5043 } 5044 thread_dict_sp->AddItem("medata", medata_array_sp); 5045 } 5046 break; 5047 5048 case eStopTypeExec: 5049 reason_value = "exec"; 5050 break; 5051 } 5052 } 5053 5054 thread_dict_sp->AddStringItem("reason", reason_value); 5055 5056 if (threads_with_valid_stop_info_only == false) 5057 { 5058 const char *thread_name = DNBThreadGetName (pid, tid); 5059 if (thread_name && thread_name[0]) 5060 thread_dict_sp->AddStringItem("name", thread_name); 5061 5062 thread_identifier_info_data_t thread_ident_info; 5063 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 5064 { 5065 if (thread_ident_info.dispatch_qaddr != 0) 5066 { 5067 thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr); 5068 5069 const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets(); 5070 if (dispatch_queue_offsets) 5071 { 5072 std::string queue_name; 5073 uint64_t queue_width = 0; 5074 uint64_t queue_serialnum = 0; 5075 dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum); 5076 if (!queue_name.empty()) 5077 thread_dict_sp->AddStringItem("qname", queue_name); 5078 if (queue_width == 1) 5079 thread_dict_sp->AddStringItem("qkind", "serial"); 5080 else if (queue_width > 1) 5081 thread_dict_sp->AddStringItem("qkind", "concurrent"); 5082 if (queue_serialnum > 0) 5083 thread_dict_sp->AddIntegerItem("qserial", queue_serialnum); 5084 } 5085 } 5086 } 5087 5088 DNBRegisterValue reg_value; 5089 5090 if (g_reg_entries != NULL) 5091 { 5092 JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary()); 5093 5094 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 5095 { 5096 // Expedite all registers in the first register set that aren't 5097 // contained in other registers 5098 if (g_reg_entries[reg].nub_info.set == 1 && 5099 g_reg_entries[reg].nub_info.value_regs == NULL) 5100 { 5101 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 5102 continue; 5103 5104 std::ostringstream reg_num; 5105 reg_num << std::dec << g_reg_entries[reg].gdb_regnum; 5106 // Encode native byte ordered bytes as hex ascii 5107 registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size); 5108 } 5109 } 5110 thread_dict_sp->AddItem("registers", registers_dict_sp); 5111 } 5112 5113 // Add expedited stack memory so stack backtracing doesn't need to read anything from the 5114 // frame pointer chain. 5115 StackMemoryMap stack_mmap; 5116 ReadStackMemory (pid, tid, stack_mmap); 5117 if (!stack_mmap.empty()) 5118 { 5119 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array()); 5120 5121 for (const auto &stack_memory : stack_mmap) 5122 { 5123 JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary()); 5124 stack_memory_sp->AddIntegerItem("address", stack_memory.first); 5125 stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length); 5126 memory_array_sp->AddItem(stack_memory_sp); 5127 } 5128 thread_dict_sp->AddItem("memory", memory_array_sp); 5129 } 5130 } 5131 5132 threads_array_sp->AddItem(thread_dict_sp); 5133 } 5134 } 5135 return threads_array_sp; 5136 } 5137 5138 rnb_err_t 5139 RNBRemote::HandlePacket_jThreadsInfo (const char *p) 5140 { 5141 JSONGenerator::ObjectSP threads_info_sp; 5142 std::ostringstream json; 5143 std::ostringstream reply_strm; 5144 // If we haven't run the process yet, return an error. 5145 if (m_ctx.HasValidProcessID()) 5146 { 5147 const bool threads_with_valid_stop_info_only = false; 5148 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only); 5149 5150 if (threads_info_sp) 5151 { 5152 std::ostringstream strm; 5153 threads_info_sp->Dump (strm); 5154 std::string binary_packet = binary_encode_string (strm.str()); 5155 if (!binary_packet.empty()) 5156 return SendPacket (binary_packet.c_str()); 5157 } 5158 } 5159 return SendPacket ("E85"); 5160 5161 } 5162 5163 rnb_err_t 5164 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) 5165 { 5166 nub_process_t pid; 5167 std::ostringstream json; 5168 // If we haven't run the process yet, return an error. 5169 if (!m_ctx.HasValidProcessID()) 5170 { 5171 return SendPacket ("E81"); 5172 } 5173 5174 pid = m_ctx.ProcessID(); 5175 5176 const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" }; 5177 if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0) 5178 { 5179 p += strlen (thread_extended_info_str); 5180 5181 uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p); 5182 uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p); 5183 uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p); 5184 uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p); 5185 uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p); 5186 // Commented out the two variables below as they are not being used 5187 // uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p); 5188 // uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p); 5189 5190 if (tid != INVALID_NUB_ADDRESS) 5191 { 5192 nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid); 5193 5194 uint64_t tsd_address = INVALID_NUB_ADDRESS; 5195 if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS 5196 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS 5197 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS) 5198 { 5199 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); 5200 } 5201 5202 bool timed_out = false; 5203 Genealogy::ThreadActivitySP thread_activity_sp; 5204 5205 // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base 5206 // and got an invalid value back, then we have a thread in early startup or shutdown and 5207 // it's possible that gathering the genealogy information for this thread go badly. 5208 // Ideally fetching this info for a thread in these odd states shouldn't matter - but 5209 // we've seen some problems with these new SPI and threads in edge-casey states. 5210 5211 double genealogy_fetch_time = 0; 5212 if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS) 5213 { 5214 DNBTimer timer(false); 5215 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out); 5216 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0; 5217 } 5218 5219 std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen 5220 5221 json << "{"; 5222 5223 bool need_to_print_comma = false; 5224 5225 if (thread_activity_sp && timed_out == false) 5226 { 5227 const Genealogy::Activity *activity = &thread_activity_sp->current_activity; 5228 bool need_vouchers_comma_sep = false; 5229 json << "\"activity_query_timed_out\":false,"; 5230 if (genealogy_fetch_time != 0) 5231 { 5232 // If we append the floating point value with << we'll get it in scientific 5233 // notation. 5234 char floating_point_ascii_buffer[64]; 5235 floating_point_ascii_buffer[0] = '\0'; 5236 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5237 if (strlen (floating_point_ascii_buffer) > 0) 5238 { 5239 if (need_to_print_comma) 5240 json << ","; 5241 need_to_print_comma = true; 5242 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5243 } 5244 } 5245 if (activity->activity_id != 0) 5246 { 5247 if (need_to_print_comma) 5248 json << ","; 5249 need_to_print_comma = true; 5250 need_vouchers_comma_sep = true; 5251 json << "\"activity\":{"; 5252 json << "\"start\":" << activity->activity_start << ","; 5253 json << "\"id\":" << activity->activity_id << ","; 5254 json << "\"parent_id\":" << activity->parent_id << ","; 5255 json << "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\","; 5256 json << "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\""; 5257 json << "}"; 5258 } 5259 if (thread_activity_sp->messages.size() > 0) 5260 { 5261 need_to_print_comma = true; 5262 if (need_vouchers_comma_sep) 5263 json << ","; 5264 need_vouchers_comma_sep = true; 5265 json << "\"trace_messages\":["; 5266 bool printed_one_message = false; 5267 for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter) 5268 { 5269 if (printed_one_message) 5270 json << ","; 5271 else 5272 printed_one_message = true; 5273 json << "{"; 5274 json << "\"timestamp\":" << iter->timestamp << ","; 5275 json << "\"activity_id\":" << iter->activity_id << ","; 5276 json << "\"trace_id\":" << iter->trace_id << ","; 5277 json << "\"thread\":" << iter->thread << ","; 5278 json << "\"type\":" << (int) iter->type << ","; 5279 json << "\"process_info_index\":" << iter->process_info_index << ","; 5280 process_info_indexes.insert (iter->process_info_index); 5281 json << "\"message\":\"" << json_string_quote_metachars (iter->message) << "\""; 5282 json << "}"; 5283 } 5284 json << "]"; 5285 } 5286 if (thread_activity_sp->breadcrumbs.size() == 1) 5287 { 5288 need_to_print_comma = true; 5289 if (need_vouchers_comma_sep) 5290 json << ","; 5291 need_vouchers_comma_sep = true; 5292 json << "\"breadcrumb\":{"; 5293 for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter) 5294 { 5295 json << "\"breadcrumb_id\":" << iter->breadcrumb_id << ","; 5296 json << "\"activity_id\":" << iter->activity_id << ","; 5297 json << "\"timestamp\":" << iter->timestamp << ","; 5298 json << "\"name\":\"" << json_string_quote_metachars (iter->name) << "\""; 5299 } 5300 json << "}"; 5301 } 5302 if (process_info_indexes.size() > 0) 5303 { 5304 need_to_print_comma = true; 5305 if (need_vouchers_comma_sep) 5306 json << ","; 5307 need_vouchers_comma_sep = true; 5308 json << "\"process_infos\":["; 5309 bool printed_one_process_info = false; 5310 for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter) 5311 { 5312 if (printed_one_process_info) 5313 json << ","; 5314 else 5315 printed_one_process_info = true; 5316 Genealogy::ProcessExecutableInfoSP image_info_sp; 5317 uint32_t idx = *iter; 5318 image_info_sp = DNBGetGenealogyImageInfo (pid, idx); 5319 json << "{"; 5320 char uuid_buf[37]; 5321 uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf); 5322 json << "\"process_info_index\":" << idx << ","; 5323 json << "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\","; 5324 json << "\"image_uuid\":\"" << uuid_buf <<"\""; 5325 json << "}"; 5326 } 5327 json << "]"; 5328 } 5329 } 5330 else 5331 { 5332 if (timed_out) 5333 { 5334 if (need_to_print_comma) 5335 json << ","; 5336 need_to_print_comma = true; 5337 json << "\"activity_query_timed_out\":true"; 5338 if (genealogy_fetch_time != 0) 5339 { 5340 // If we append the floating point value with << we'll get it in scientific 5341 // notation. 5342 char floating_point_ascii_buffer[64]; 5343 floating_point_ascii_buffer[0] = '\0'; 5344 snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time); 5345 if (strlen (floating_point_ascii_buffer) > 0) 5346 { 5347 json << ","; 5348 json << "\"activity_query_duration\":" << floating_point_ascii_buffer; 5349 } 5350 } 5351 } 5352 } 5353 5354 if (tsd_address != INVALID_NUB_ADDRESS) 5355 { 5356 if (need_to_print_comma) 5357 json << ","; 5358 need_to_print_comma = true; 5359 json << "\"tsd_address\":" << tsd_address; 5360 5361 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX) 5362 { 5363 ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index); 5364 if (requested_qos.IsValid()) 5365 { 5366 if (need_to_print_comma) 5367 json << ","; 5368 need_to_print_comma = true; 5369 json << "\"requested_qos\":{"; 5370 json << "\"enum_value\":" << requested_qos.enum_value << ","; 5371 json << "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\","; 5372 json << "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\""; 5373 json << "}"; 5374 } 5375 } 5376 } 5377 5378 if (pthread_t_value != INVALID_NUB_ADDRESS) 5379 { 5380 if (need_to_print_comma) 5381 json << ","; 5382 need_to_print_comma = true; 5383 json << "\"pthread_t\":" << pthread_t_value; 5384 } 5385 5386 nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid); 5387 if (dispatch_queue_t_value != INVALID_NUB_ADDRESS) 5388 { 5389 if (need_to_print_comma) 5390 json << ","; 5391 need_to_print_comma = true; 5392 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value; 5393 } 5394 5395 json << "}"; 5396 std::string json_quoted = binary_encode_string (json.str()); 5397 return SendPacket (json_quoted); 5398 } 5399 } 5400 return SendPacket ("OK"); 5401 } 5402 5403 rnb_err_t 5404 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p) 5405 { 5406 nub_process_t pid; 5407 // If we haven't run the process yet, return an error. 5408 if (!m_ctx.HasValidProcessID()) 5409 { 5410 return SendPacket ("E83"); 5411 } 5412 5413 pid = m_ctx.ProcessID(); 5414 5415 const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" }; 5416 if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0) 5417 { 5418 p += strlen (get_loaded_dynamic_libraries_infos_str); 5419 5420 nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p); 5421 nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p); 5422 5423 if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS) 5424 { 5425 JSONGenerator::ObjectSP json_sp; 5426 5427 json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count); 5428 5429 if (json_sp.get()) 5430 { 5431 std::ostringstream json_str; 5432 json_sp->Dump (json_str); 5433 if (json_str.str().size() > 0) 5434 { 5435 std::string json_str_quoted = binary_encode_string (json_str.str()); 5436 return SendPacket (json_str_quoted.c_str()); 5437 } 5438 else 5439 { 5440 SendPacket ("E84"); 5441 } 5442 } 5443 } 5444 } 5445 return SendPacket ("OK"); 5446 } 5447 5448 rnb_err_t 5449 RNBRemote::HandlePacket_qSymbol (const char *command) 5450 { 5451 const char *p = command; 5452 p += strlen ("qSymbol:"); 5453 const char *sep = strchr(p, ':'); 5454 5455 std::string symbol_name; 5456 std::string symbol_value_str; 5457 // Extract the symbol value if there is one 5458 if (sep > p) 5459 symbol_value_str.assign(p, sep - p); 5460 p = sep + 1; 5461 5462 if (*p) 5463 { 5464 // We have a symbol name 5465 symbol_name = std::move(decode_hex_ascii_string(p)); 5466 if (!symbol_value_str.empty()) 5467 { 5468 nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); 5469 if (symbol_name == "dispatch_queue_offsets") 5470 m_dispatch_queue_offsets_addr = symbol_value; 5471 } 5472 ++m_qSymbol_index; 5473 } 5474 else 5475 { 5476 // No symbol name, set our symbol index to zero so we can 5477 // read any symbols that we need 5478 m_qSymbol_index = 0; 5479 } 5480 5481 symbol_name.clear(); 5482 5483 if (m_qSymbol_index == 0) 5484 { 5485 if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS) 5486 symbol_name = "dispatch_queue_offsets"; 5487 else 5488 ++m_qSymbol_index; 5489 } 5490 5491 // // Lookup next symbol when we have one... 5492 // if (m_qSymbol_index == 1) 5493 // { 5494 // } 5495 5496 5497 if (symbol_name.empty()) 5498 { 5499 // Done with symbol lookups 5500 return SendPacket ("OK"); 5501 } 5502 else 5503 { 5504 std::ostringstream reply; 5505 reply << "qSymbol:"; 5506 for (size_t i = 0; i < symbol_name.size(); ++i) 5507 reply << RAWHEX8(symbol_name[i]); 5508 return SendPacket (reply.str().c_str()); 5509 } 5510 } 5511 5512 // Note that all numeric values returned by qProcessInfo are hex encoded, 5513 // including the pid and the cpu type. 5514 5515 rnb_err_t 5516 RNBRemote::HandlePacket_qProcessInfo (const char *p) 5517 { 5518 nub_process_t pid; 5519 std::ostringstream rep; 5520 5521 // If we haven't run the process yet, return an error. 5522 if (!m_ctx.HasValidProcessID()) 5523 return SendPacket ("E68"); 5524 5525 pid = m_ctx.ProcessID(); 5526 5527 rep << "pid:" << std::hex << pid << ";"; 5528 5529 int procpid_mib[4]; 5530 procpid_mib[0] = CTL_KERN; 5531 procpid_mib[1] = KERN_PROC; 5532 procpid_mib[2] = KERN_PROC_PID; 5533 procpid_mib[3] = pid; 5534 struct kinfo_proc proc_kinfo; 5535 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 5536 5537 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 5538 { 5539 if (proc_kinfo_size > 0) 5540 { 5541 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";"; 5542 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";"; 5543 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";"; 5544 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";"; 5545 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 5546 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";"; 5547 } 5548 } 5549 5550 cpu_type_t cputype = DNBProcessGetCPUType (pid); 5551 if (cputype == 0) 5552 { 5553 DNBLog ("Unable to get the process cpu_type, making a best guess."); 5554 cputype = best_guess_cpu_type(); 5555 } 5556 5557 if (cputype != 0) 5558 { 5559 rep << "cputype:" << std::hex << cputype << ";"; 5560 } 5561 5562 bool host_cpu_is_64bit = false; 5563 uint32_t is64bit_capable; 5564 size_t is64bit_capable_len = sizeof (is64bit_capable); 5565 if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0) 5566 host_cpu_is_64bit = is64bit_capable != 0; 5567 5568 uint32_t cpusubtype; 5569 size_t cpusubtype_len = sizeof(cpusubtype); 5570 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 5571 { 5572 // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected 5573 // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the 5574 // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype 5575 // for i386... 5576 if (host_cpu_is_64bit) 5577 { 5578 if (cputype == CPU_TYPE_X86) 5579 { 5580 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 5581 } 5582 else if (cputype == CPU_TYPE_ARM) 5583 { 5584 // We can query a process' cputype but we cannot query a process' cpusubtype. 5585 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we 5586 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace) 5587 // with a reasonable CPU_SUBTYPE_ARMV7 subtype. 5588 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S 5589 } 5590 } 5591 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 5592 } 5593 5594 // The OS in the triple should be "ios" or "macosx" which doesn't match our 5595 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 5596 // this for now. 5597 if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) 5598 rep << "ostype:ios;"; 5599 else 5600 { 5601 bool is_ios_simulator = false; 5602 if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64) 5603 { 5604 // Check for iOS simulator binaries by getting the process argument 5605 // and environment and checking for SIMULATOR_UDID in the environment 5606 int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid }; 5607 5608 uint8_t arg_data[8192]; 5609 size_t arg_data_size = sizeof(arg_data); 5610 if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) 5611 { 5612 DNBDataRef data (arg_data, arg_data_size, false); 5613 DNBDataRef::offset_t offset = 0; 5614 uint32_t argc = data.Get32 (&offset); 5615 const char *cstr; 5616 5617 cstr = data.GetCStr (&offset); 5618 if (cstr) 5619 { 5620 // Skip NULLs 5621 while (1) 5622 { 5623 const char *p = data.PeekCStr(offset); 5624 if ((p == NULL) || (*p != '\0')) 5625 break; 5626 ++offset; 5627 } 5628 // Now skip all arguments 5629 for (uint32_t i = 0; i < argc; ++i) 5630 { 5631 data.GetCStr(&offset); 5632 } 5633 5634 // Now iterate across all environment variables 5635 while ((cstr = data.GetCStr(&offset))) 5636 { 5637 if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) 5638 { 5639 is_ios_simulator = true; 5640 break; 5641 } 5642 if (cstr[0] == '\0') 5643 break; 5644 5645 } 5646 } 5647 } 5648 } 5649 if (is_ios_simulator) 5650 rep << "ostype:ios;"; 5651 else 5652 rep << "ostype:macosx;"; 5653 } 5654 5655 rep << "vendor:apple;"; 5656 5657 #if defined (__LITTLE_ENDIAN__) 5658 rep << "endian:little;"; 5659 #elif defined (__BIG_ENDIAN__) 5660 rep << "endian:big;"; 5661 #elif defined (__PDP_ENDIAN__) 5662 rep << "endian:pdp;"; 5663 #endif 5664 5665 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 5666 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5667 kern_return_t kr; 5668 x86_thread_state_t gp_regs; 5669 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 5670 kr = thread_get_state (static_cast<thread_act_t>(thread), 5671 x86_THREAD_STATE, 5672 (thread_state_t) &gp_regs, 5673 &gp_count); 5674 if (kr == KERN_SUCCESS) 5675 { 5676 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 5677 rep << "ptrsize:8;"; 5678 else 5679 rep << "ptrsize:4;"; 5680 } 5681 #elif defined (__arm__) 5682 rep << "ptrsize:4;"; 5683 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE) 5684 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 5685 kern_return_t kr; 5686 arm_unified_thread_state_t gp_regs; 5687 mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT; 5688 kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE, 5689 (thread_state_t) &gp_regs, &gp_count); 5690 if (kr == KERN_SUCCESS) 5691 { 5692 if (gp_regs.ash.flavor == ARM_THREAD_STATE64) 5693 rep << "ptrsize:8;"; 5694 else 5695 rep << "ptrsize:4;"; 5696 } 5697 #endif 5698 5699 return SendPacket (rep.str()); 5700 } 5701 5702 const RNBRemote::DispatchQueueOffsets * 5703 RNBRemote::GetDispatchQueueOffsets() 5704 { 5705 if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID()) 5706 { 5707 nub_process_t pid = m_ctx.ProcessID(); 5708 nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets); 5709 if (bytes_read != sizeof(m_dispatch_queue_offsets)) 5710 m_dispatch_queue_offsets.Clear(); 5711 } 5712 5713 if (m_dispatch_queue_offsets.IsValid()) 5714 return &m_dispatch_queue_offsets; 5715 else 5716 return nullptr; 5717 } 5718 5719 void 5720 RNBRemote::EnableCompressionNextSendPacket (compression_types type) 5721 { 5722 m_compression_mode = type; 5723 m_enable_compression_next_send_packet = true; 5724 } 5725 5726 compression_types 5727 RNBRemote::GetCompressionType () 5728 { 5729 // The first packet we send back to the debugger after a QEnableCompression request 5730 // should be uncompressed -- so we can indicate whether the compression was enabled 5731 // or not via OK / Enn returns. After that, all packets sent will be using the 5732 // compression protocol. 5733 5734 if (m_enable_compression_next_send_packet) 5735 { 5736 // One time, we send back "None" as our compression type 5737 m_enable_compression_next_send_packet = false; 5738 return compression_types::none; 5739 } 5740 return m_compression_mode; 5741 } 5742