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