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