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