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