1 // Copyright 2013 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 // Originally written by Sven Peter <sven@fail0verflow.com> for anergistic.
6 
7 #include <algorithm>
8 #include <atomic>
9 #include <climits>
10 #include <csignal>
11 #include <cstdarg>
12 #include <cstdio>
13 #include <cstring>
14 #include <map>
15 #include <numeric>
16 #include <fcntl.h>
17 #include <fmt/format.h>
18 
19 #ifdef _WIN32
20 #include <winsock2.h>
21 // winsock2.h needs to be included first to prevent winsock.h being included by other includes
22 #include <io.h>
23 #include <iphlpapi.h>
24 #include <ws2tcpip.h>
25 #define SHUT_RDWR 2
26 #else
27 #include <netinet/in.h>
28 #include <sys/select.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #include <unistd.h>
32 #endif
33 
34 #include "common/logging/log.h"
35 #include "core/arm/arm_interface.h"
36 #include "core/core.h"
37 #include "core/gdbstub/gdbstub.h"
38 #include "core/hle/kernel/process.h"
39 #include "core/loader/loader.h"
40 #include "core/memory.h"
41 
42 namespace GDBStub {
43 namespace {
44 constexpr int GDB_BUFFER_SIZE = 10000;
45 
46 constexpr char GDB_STUB_START = '$';
47 constexpr char GDB_STUB_END = '#';
48 constexpr char GDB_STUB_ACK = '+';
49 constexpr char GDB_STUB_NACK = '-';
50 
51 #ifndef SIGTRAP
52 constexpr u32 SIGTRAP = 5;
53 #endif
54 
55 #ifndef SIGTERM
56 constexpr u32 SIGTERM = 15;
57 #endif
58 
59 #ifndef MSG_WAITALL
60 constexpr u32 MSG_WAITALL = 8;
61 #endif
62 
63 constexpr u32 SP_REGISTER = 13;
64 constexpr u32 LR_REGISTER = 14;
65 constexpr u32 PC_REGISTER = 15;
66 constexpr u32 CPSR_REGISTER = 25;
67 constexpr u32 D0_REGISTER = 26;
68 constexpr u32 FPSCR_REGISTER = 42;
69 
70 // For sample XML files see the GDB source /gdb/features
71 // GDB also wants the l character at the start
72 // This XML defines what the registers are for this specific ARM device
73 constexpr char target_xml[] =
74     R"(l<?xml version="1.0"?>
75 <!DOCTYPE target SYSTEM "gdb-target.dtd">
76 <target version="1.0">
77   <feature name="org.gnu.gdb.arm.core">
78     <reg name="r0" bitsize="32"/>
79     <reg name="r1" bitsize="32"/>
80     <reg name="r2" bitsize="32"/>
81     <reg name="r3" bitsize="32"/>
82     <reg name="r4" bitsize="32"/>
83     <reg name="r5" bitsize="32"/>
84     <reg name="r6" bitsize="32"/>
85     <reg name="r7" bitsize="32"/>
86     <reg name="r8" bitsize="32"/>
87     <reg name="r9" bitsize="32"/>
88     <reg name="r10" bitsize="32"/>
89     <reg name="r11" bitsize="32"/>
90     <reg name="r12" bitsize="32"/>
91     <reg name="sp" bitsize="32" type="data_ptr"/>
92     <reg name="lr" bitsize="32"/>
93     <reg name="pc" bitsize="32" type="code_ptr"/>
94 
95     <!-- The CPSR is register 25, rather than register 16, because
96          the FPA registers historically were placed between the PC
97          and the CPSR in the "g" packet.  -->
98 
99     <reg name="cpsr" bitsize="32" regnum="25"/>
100   </feature>
101   <feature name="org.gnu.gdb.arm.vfp">
102     <reg name="d0" bitsize="64" type="float"/>
103     <reg name="d1" bitsize="64" type="float"/>
104     <reg name="d2" bitsize="64" type="float"/>
105     <reg name="d3" bitsize="64" type="float"/>
106     <reg name="d4" bitsize="64" type="float"/>
107     <reg name="d5" bitsize="64" type="float"/>
108     <reg name="d6" bitsize="64" type="float"/>
109     <reg name="d7" bitsize="64" type="float"/>
110     <reg name="d8" bitsize="64" type="float"/>
111     <reg name="d9" bitsize="64" type="float"/>
112     <reg name="d10" bitsize="64" type="float"/>
113     <reg name="d11" bitsize="64" type="float"/>
114     <reg name="d12" bitsize="64" type="float"/>
115     <reg name="d13" bitsize="64" type="float"/>
116     <reg name="d14" bitsize="64" type="float"/>
117     <reg name="d15" bitsize="64" type="float"/>
118     <reg name="fpscr" bitsize="32" type="int" group="float"/>
119   </feature>
120 </target>
121 )";
122 
123 int gdbserver_socket = -1;
124 bool defer_start = false;
125 
126 u8 command_buffer[GDB_BUFFER_SIZE];
127 u32 command_length;
128 
129 u32 latest_signal = 0;
130 bool memory_break = false;
131 
132 static Kernel::Thread* current_thread = nullptr;
133 
134 // Binding to a port within the reserved ports range (0-1023) requires root permissions,
135 // so default to a port outside of that range.
136 u16 gdbstub_port = 24689;
137 
138 bool halt_loop = true;
139 bool step_loop = false;
140 bool send_trap = false;
141 
142 // If set to false, the server will never be started and no
143 // gdbstub-related functions will be executed.
144 std::atomic<bool> server_enabled(false);
145 
146 #ifdef _WIN32
147 WSADATA InitData;
148 #endif
149 
150 struct Breakpoint {
151     bool active;
152     VAddr addr;
153     u32 len;
154     std::array<u8, 4> inst;
155 };
156 
157 using BreakpointMap = std::map<VAddr, Breakpoint>;
158 BreakpointMap breakpoints_execute;
159 BreakpointMap breakpoints_read;
160 BreakpointMap breakpoints_write;
161 } // Anonymous namespace
162 
FindThreadById(int id)163 static Kernel::Thread* FindThreadById(int id) {
164     u32 num_cores = Core::GetNumCores();
165     for (u32 i = 0; i < num_cores; ++i) {
166         const auto& threads =
167             Core::System::GetInstance().Kernel().GetThreadManager(i).GetThreadList();
168         for (auto& thread : threads) {
169             if (thread->GetThreadId() == static_cast<u32>(id)) {
170                 return thread.get();
171             }
172         }
173     }
174     return nullptr;
175 }
176 
RegRead(std::size_t id,Kernel::Thread * thread=nullptr)177 static u32 RegRead(std::size_t id, Kernel::Thread* thread = nullptr) {
178     if (!thread) {
179         return 0;
180     }
181 
182     if (id <= PC_REGISTER) {
183         return thread->context->GetCpuRegister(id);
184     } else if (id == CPSR_REGISTER) {
185         return thread->context->GetCpsr();
186     } else {
187         return 0;
188     }
189 }
190 
RegWrite(std::size_t id,u32 val,Kernel::Thread * thread=nullptr)191 static void RegWrite(std::size_t id, u32 val, Kernel::Thread* thread = nullptr) {
192     if (!thread) {
193         return;
194     }
195 
196     if (id <= PC_REGISTER) {
197         return thread->context->SetCpuRegister(id, val);
198     } else if (id == CPSR_REGISTER) {
199         return thread->context->SetCpsr(val);
200     }
201 }
202 
FpuRead(std::size_t id,Kernel::Thread * thread=nullptr)203 static u64 FpuRead(std::size_t id, Kernel::Thread* thread = nullptr) {
204     if (!thread) {
205         return 0;
206     }
207 
208     if (id >= D0_REGISTER && id < FPSCR_REGISTER) {
209         u64 ret = thread->context->GetFpuRegister(2 * (id - D0_REGISTER));
210         ret |= static_cast<u64>(thread->context->GetFpuRegister(2 * (id - D0_REGISTER) + 1)) << 32;
211         return ret;
212     } else if (id == FPSCR_REGISTER) {
213         return thread->context->GetFpscr();
214     } else {
215         return 0;
216     }
217 }
218 
FpuWrite(std::size_t id,u64 val,Kernel::Thread * thread=nullptr)219 static void FpuWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr) {
220     if (!thread) {
221         return;
222     }
223 
224     if (id >= D0_REGISTER && id < FPSCR_REGISTER) {
225         thread->context->SetFpuRegister(2 * (id - D0_REGISTER), static_cast<u32>(val));
226         thread->context->SetFpuRegister(2 * (id - D0_REGISTER) + 1, static_cast<u32>(val >> 32));
227     } else if (id == FPSCR_REGISTER) {
228         return thread->context->SetFpscr(static_cast<u32>(val));
229     }
230 }
231 
232 /**
233  * Turns hex string character into the equivalent byte.
234  *
235  * @param hex Input hex character to be turned into byte.
236  */
HexCharToValue(u8 hex)237 static u8 HexCharToValue(u8 hex) {
238     if (hex >= '0' && hex <= '9') {
239         return hex - '0';
240     } else if (hex >= 'a' && hex <= 'f') {
241         return hex - 'a' + 0xA;
242     } else if (hex >= 'A' && hex <= 'F') {
243         return hex - 'A' + 0xA;
244     }
245 
246     LOG_ERROR(Debug_GDBStub, "Invalid nibble: {:c} {:02x}\n", hex, hex);
247     return 0;
248 }
249 
250 /**
251  * Turn nibble of byte into hex string character.
252  *
253  * @param n Nibble to be turned into hex character.
254  */
NibbleToHex(u8 n)255 static u8 NibbleToHex(u8 n) {
256     n &= 0xF;
257     if (n < 0xA) {
258         return '0' + n;
259     } else {
260         return 'a' + n - 0xA;
261     }
262 }
263 
264 /**
265  * Converts input hex string characters into an array of equivalent of u8 bytes.
266  *
267  * @param src Pointer to array of output hex string characters.
268  * @param len Length of src array.
269  */
HexToInt(const u8 * src,std::size_t len)270 static u32 HexToInt(const u8* src, std::size_t len) {
271     u32 output = 0;
272     while (len-- > 0) {
273         output = (output << 4) | HexCharToValue(src[0]);
274         src++;
275     }
276     return output;
277 }
278 
279 /**
280  * Converts input array of u8 bytes into their equivalent hex string characters.
281  *
282  * @param dest Pointer to buffer to store output hex string characters.
283  * @param src Pointer to array of u8 bytes.
284  * @param len Length of src array.
285  */
MemToGdbHex(u8 * dest,const u8 * src,std::size_t len)286 static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
287     while (len-- > 0) {
288         u8 tmp = *src++;
289         *dest++ = NibbleToHex(tmp >> 4);
290         *dest++ = NibbleToHex(tmp);
291     }
292 }
293 
294 /**
295  * Converts input gdb-formatted hex string characters into an array of equivalent of u8 bytes.
296  *
297  * @param dest Pointer to buffer to store u8 bytes.
298  * @param src Pointer to array of output hex string characters.
299  * @param len Length of src array.
300  */
GdbHexToMem(u8 * dest,const u8 * src,std::size_t len)301 static void GdbHexToMem(u8* dest, const u8* src, std::size_t len) {
302     while (len-- > 0) {
303         *dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]);
304         src += 2;
305     }
306 }
307 
308 /**
309  * Convert a u32 into a gdb-formatted hex string.
310  *
311  * @param dest Pointer to buffer to store output hex string characters.
312  * @param v    Value to convert.
313  */
IntToGdbHex(u8 * dest,u32 v)314 static void IntToGdbHex(u8* dest, u32 v) {
315     for (int i = 0; i < 8; i += 2) {
316         dest[i + 1] = NibbleToHex(v >> (4 * i));
317         dest[i] = NibbleToHex(v >> (4 * (i + 1)));
318     }
319 }
320 
321 /**
322  * Convert a gdb-formatted hex string into a u32.
323  *
324  * @param src Pointer to hex string.
325  */
GdbHexToInt(const u8 * src)326 static u32 GdbHexToInt(const u8* src) {
327     u32 output = 0;
328 
329     for (int i = 0; i < 8; i += 2) {
330         output = (output << 4) | HexCharToValue(src[7 - i - 1]);
331         output = (output << 4) | HexCharToValue(src[7 - i]);
332     }
333 
334     return output;
335 }
336 
337 /**
338  * Convert a u64 into a gdb-formatted hex string.
339  *
340  * @param dest Pointer to buffer to store output hex string characters.
341  * @param v    Value to convert.
342  */
LongToGdbHex(u8 * dest,u64 v)343 static void LongToGdbHex(u8* dest, u64 v) {
344     for (int i = 0; i < 16; i += 2) {
345         dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
346         dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
347     }
348 }
349 
350 /**
351  * Convert a gdb-formatted hex string into a u64.
352  *
353  * @param src Pointer to hex string.
354  */
GdbHexToLong(const u8 * src)355 static u64 GdbHexToLong(const u8* src) {
356     u64 output = 0;
357 
358     for (int i = 0; i < 16; i += 2) {
359         output = (output << 4) | HexCharToValue(src[15 - i - 1]);
360         output = (output << 4) | HexCharToValue(src[15 - i]);
361     }
362 
363     return output;
364 }
365 
366 /// Read a byte from the gdb client.
ReadByte()367 static u8 ReadByte() {
368     u8 c;
369     std::size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
370     if (received_size != 1) {
371         LOG_ERROR(Debug_GDBStub, "recv failed : {}", received_size);
372         Shutdown();
373     }
374 
375     return c;
376 }
377 
378 /// Calculate the checksum of the current command buffer.
CalculateChecksum(const u8 * buffer,std::size_t length)379 static u8 CalculateChecksum(const u8* buffer, std::size_t length) {
380     return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>()));
381 }
382 
383 /**
384  * Get the map of breakpoints for a given breakpoint type.
385  *
386  * @param type Type of breakpoint map.
387  */
GetBreakpointMap(BreakpointType type)388 static BreakpointMap& GetBreakpointMap(BreakpointType type) {
389     switch (type) {
390     case BreakpointType::Execute:
391         return breakpoints_execute;
392     case BreakpointType::Read:
393         return breakpoints_read;
394     case BreakpointType::Write:
395         return breakpoints_write;
396     default:
397         return breakpoints_read;
398     }
399 }
400 
401 /**
402  * Remove the breakpoint from the given address of the specified type.
403  *
404  * @param type Type of breakpoint.
405  * @param addr Address of breakpoint.
406  */
RemoveBreakpoint(BreakpointType type,VAddr addr)407 static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
408     BreakpointMap& p = GetBreakpointMap(type);
409 
410     const auto bp = p.find(addr);
411     if (bp == p.end()) {
412         return;
413     }
414 
415     LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:08x} bytes at {:08x} of type {}",
416               bp->second.len, bp->second.addr, type);
417 
418     if (type == BreakpointType::Execute) {
419         Core::System::GetInstance().Memory().WriteBlock(
420             *Core::System::GetInstance().Kernel().GetCurrentProcess(), bp->second.addr,
421             bp->second.inst.data(), bp->second.inst.size());
422         u32 num_cores = Core::GetNumCores();
423         for (u32 i = 0; i < num_cores; ++i) {
424             Core::GetCore(i).ClearInstructionCache();
425         }
426     }
427     p.erase(addr);
428 }
429 
GetNextBreakpointFromAddress(VAddr addr,BreakpointType type)430 BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) {
431     const BreakpointMap& p = GetBreakpointMap(type);
432     const auto next_breakpoint = p.lower_bound(addr);
433     BreakpointAddress breakpoint;
434 
435     if (next_breakpoint != p.end()) {
436         breakpoint.address = next_breakpoint->first;
437         breakpoint.type = type;
438     } else {
439         breakpoint.address = 0;
440         breakpoint.type = BreakpointType::None;
441     }
442 
443     return breakpoint;
444 }
445 
CheckBreakpoint(VAddr addr,BreakpointType type)446 bool CheckBreakpoint(VAddr addr, BreakpointType type) {
447     if (!IsConnected()) {
448         return false;
449     }
450 
451     const BreakpointMap& p = GetBreakpointMap(type);
452     const auto bp = p.find(addr);
453 
454     if (bp == p.end()) {
455         return false;
456     }
457 
458     u32 len = bp->second.len;
459 
460     // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
461     // no matter if it's a 4-byte or 2-byte instruction. When you execute a
462     // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
463     // two instructions instead of the single instruction you placed the breakpoint
464     // on. So, as a way to make sure that execution breakpoints are only breaking
465     // on the instruction that was specified, set the length of an execution
466     // breakpoint to 1. This should be fine since the CPU should never begin executing
467     // an instruction anywhere except the beginning of the instruction.
468     if (type == BreakpointType::Execute) {
469         len = 1;
470     }
471 
472     if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
473         LOG_DEBUG(Debug_GDBStub,
474                   "Found breakpoint type {} @ {:08x}, range: {:08x}"
475                   " - {:08x} ({:x} bytes)",
476                   type, addr, bp->second.addr, bp->second.addr + len, len);
477         return true;
478     }
479 
480     return false;
481 }
482 
483 /**
484  * Send packet to gdb client.
485  *
486  * @param packet Packet to be sent to client.
487  */
SendPacket(const char packet)488 static void SendPacket(const char packet) {
489     std::size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
490     if (sent_size != 1) {
491         LOG_ERROR(Debug_GDBStub, "send failed");
492     }
493 }
494 
495 /**
496  * Send reply to gdb client.
497  *
498  * @param reply Reply to be sent to client.
499  */
SendReply(const char * reply)500 static void SendReply(const char* reply) {
501     if (!IsConnected()) {
502         return;
503     }
504 
505     memset(command_buffer, 0, sizeof(command_buffer));
506 
507     command_length = static_cast<u32>(strlen(reply));
508     if (command_length + 4 > sizeof(command_buffer)) {
509         LOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply");
510         return;
511     }
512 
513     memcpy(command_buffer + 1, reply, command_length);
514 
515     u8 checksum = CalculateChecksum(command_buffer, command_length + 1);
516     command_buffer[0] = GDB_STUB_START;
517     command_buffer[command_length + 1] = GDB_STUB_END;
518     command_buffer[command_length + 2] = NibbleToHex(checksum >> 4);
519     command_buffer[command_length + 3] = NibbleToHex(checksum);
520 
521     u8* ptr = command_buffer;
522     u32 left = command_length + 4;
523     while (left > 0) {
524         int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
525         if (sent_size < 0) {
526             LOG_ERROR(Debug_GDBStub, "gdb: send failed");
527             return Shutdown();
528         }
529 
530         left -= sent_size;
531         ptr += sent_size;
532     }
533 }
534 
535 /// Handle query command from gdb client.
HandleQuery()536 static void HandleQuery() {
537     LOG_DEBUG(Debug_GDBStub, "gdb: query '{}'\n", command_buffer + 1);
538 
539     const char* query = reinterpret_cast<const char*>(command_buffer + 1);
540 
541     if (strcmp(query, "TStatus") == 0) {
542         SendReply("T0");
543     } else if (strncmp(query, "Supported", strlen("Supported")) == 0) {
544         // PacketSize needs to be large enough for target xml
545         SendReply("PacketSize=2000;qXfer:features:read+;qXfer:threads:read+");
546     } else if (strncmp(query, "Xfer:features:read:target.xml:",
547                        strlen("Xfer:features:read:target.xml:")) == 0) {
548         SendReply(target_xml);
549     } else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
550         std::string val = "m";
551         u32 num_cores = Core::GetNumCores();
552         for (u32 i = 0; i < num_cores; ++i) {
553             const auto& threads =
554                 Core::System::GetInstance().Kernel().GetThreadManager(i).GetThreadList();
555             for (const auto& thread : threads) {
556                 val += fmt::format("{:x},", thread->GetThreadId());
557             }
558         }
559         val.pop_back();
560         SendReply(val.c_str());
561     } else if (strncmp(query, "sThreadInfo", strlen("sThreadInfo")) == 0) {
562         SendReply("l");
563     } else if (strncmp(query, "Xfer:threads:read", strlen("Xfer:threads:read")) == 0) {
564         std::string buffer;
565         buffer += "l<?xml version=\"1.0\"?>";
566         buffer += "<threads>";
567         u32 num_cores = Core::GetNumCores();
568         for (u32 i = 0; i < num_cores; ++i) {
569             const auto& threads =
570                 Core::System::GetInstance().Kernel().GetThreadManager(i).GetThreadList();
571             for (const auto& thread : threads) {
572                 buffer += fmt::format(R"*(<thread id="{:x}" name="Thread {:x}"></thread>)*",
573                                       thread->GetThreadId(), thread->GetThreadId());
574             }
575         }
576         buffer += "</threads>";
577         SendReply(buffer.c_str());
578     } else {
579         SendReply("");
580     }
581 }
582 
583 /// Handle set thread command from gdb client.
HandleSetThread()584 static void HandleSetThread() {
585     int thread_id = -1;
586     if (command_buffer[2] != '-') {
587         thread_id = static_cast<int>(HexToInt(command_buffer + 2, command_length - 2));
588     }
589     if (thread_id >= 1) {
590         current_thread = FindThreadById(thread_id);
591     }
592     if (!current_thread) {
593         thread_id = 1;
594         current_thread = FindThreadById(thread_id);
595     }
596     if (current_thread) {
597         SendReply("OK");
598         return;
599     }
600     SendReply("E01");
601 }
602 
603 /// Handle thread alive command from gdb client.
HandleThreadAlive()604 static void HandleThreadAlive() {
605     int thread_id = static_cast<int>(HexToInt(command_buffer + 1, command_length - 1));
606     if (thread_id == 0) {
607         thread_id = 1;
608     }
609     if (FindThreadById(thread_id)) {
610         SendReply("OK");
611         return;
612     }
613     SendReply("E01");
614 }
615 
616 /**
617  * Send signal packet to client.
618  *
619  * @param signal Signal to be sent to client.
620  */
SendSignal(Kernel::Thread * thread,u32 signal,bool full=true)621 static void SendSignal(Kernel::Thread* thread, u32 signal, bool full = true) {
622     if (gdbserver_socket == -1) {
623         return;
624     }
625 
626     latest_signal = signal;
627 
628     if (!thread) {
629         full = false;
630     }
631 
632     std::string buffer;
633     if (full) {
634 
635         buffer = fmt::format("T{:02x}{:02x}:{:08x};{:02x}:{:08x};{:02x}:{:08x}", latest_signal,
636                              PC_REGISTER, htonl(Core::GetRunningCore().GetPC()), SP_REGISTER,
637                              htonl(Core::GetRunningCore().GetReg(SP_REGISTER)), LR_REGISTER,
638                              htonl(Core::GetRunningCore().GetReg(LR_REGISTER)));
639     } else {
640         buffer = fmt::format("T{:02x}", latest_signal);
641     }
642 
643     if (thread) {
644         buffer += fmt::format(";thread:{:x};", thread->GetThreadId());
645     }
646 
647     LOG_DEBUG(Debug_GDBStub, "Response: {}", buffer);
648     SendReply(buffer.c_str());
649 }
650 
651 /// Read command from gdb client.
ReadCommand()652 static void ReadCommand() {
653     command_length = 0;
654     memset(command_buffer, 0, sizeof(command_buffer));
655 
656     u8 c = ReadByte();
657     if (c == '+') {
658         // ignore ack
659         return;
660     } else if (c == 0x03) {
661         LOG_INFO(Debug_GDBStub, "gdb: found break command\n");
662         halt_loop = true;
663         SendSignal(current_thread, SIGTRAP);
664         return;
665     } else if (c != GDB_STUB_START) {
666         LOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02x}\n", c);
667         return;
668     }
669 
670     while ((c = ReadByte()) != GDB_STUB_END) {
671         if (command_length >= sizeof(command_buffer)) {
672             LOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow\n");
673             SendPacket(GDB_STUB_NACK);
674             return;
675         }
676         command_buffer[command_length++] = c;
677     }
678 
679     u8 checksum_received = HexCharToValue(ReadByte()) << 4;
680     checksum_received |= HexCharToValue(ReadByte());
681 
682     u8 checksum_calculated = CalculateChecksum(command_buffer, command_length);
683 
684     if (checksum_received != checksum_calculated) {
685         LOG_ERROR(
686             Debug_GDBStub,
687             "gdb: invalid checksum: calculated {:02x} and read {:02x} for ${}# (length: {})\n",
688             checksum_calculated, checksum_received, command_buffer, command_length);
689 
690         command_length = 0;
691 
692         SendPacket(GDB_STUB_NACK);
693         return;
694     }
695 
696     SendPacket(GDB_STUB_ACK);
697 }
698 
699 /// Check if there is data to be read from the gdb client.
IsDataAvailable()700 static bool IsDataAvailable() {
701     if (!IsConnected()) {
702         return false;
703     }
704 
705     fd_set fd_socket;
706 
707     FD_ZERO(&fd_socket);
708     FD_SET(gdbserver_socket, &fd_socket);
709 
710     struct timeval t;
711     t.tv_sec = 0;
712     t.tv_usec = 0;
713 
714     if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) {
715         LOG_ERROR(Debug_GDBStub, "select failed");
716         return false;
717     }
718 
719     return FD_ISSET(gdbserver_socket, &fd_socket) != 0;
720 }
721 
722 /// Send requested register to gdb client.
ReadRegister()723 static void ReadRegister() {
724     static u8 reply[64];
725     memset(reply, 0, sizeof(reply));
726 
727     u32 id = HexCharToValue(command_buffer[1]);
728     if (command_buffer[2] != '\0') {
729         id <<= 4;
730         id |= HexCharToValue(command_buffer[2]);
731     }
732 
733     if (id <= PC_REGISTER) {
734         IntToGdbHex(reply, RegRead(id, current_thread));
735     } else if (id == CPSR_REGISTER) {
736         IntToGdbHex(reply, RegRead(id, current_thread));
737     } else if (id >= D0_REGISTER && id < FPSCR_REGISTER) {
738         LongToGdbHex(reply, FpuRead(id, current_thread));
739     } else if (id == FPSCR_REGISTER) {
740         IntToGdbHex(reply, static_cast<u32>(FpuRead(id, current_thread)));
741     } else {
742         return SendReply("E01");
743     }
744 
745     SendReply(reinterpret_cast<char*>(reply));
746 }
747 
748 /// Send all registers to the gdb client.
ReadRegisters()749 static void ReadRegisters() {
750     static u8 buffer[GDB_BUFFER_SIZE - 4];
751     memset(buffer, 0, sizeof(buffer));
752 
753     u8* bufptr = buffer;
754 
755     for (u32 reg = 0; reg <= PC_REGISTER; reg++) {
756         IntToGdbHex(bufptr + reg * 8, RegRead(reg, current_thread));
757     }
758 
759     bufptr += 16 * 8;
760 
761     IntToGdbHex(bufptr, RegRead(CPSR_REGISTER, current_thread));
762 
763     bufptr += 8;
764 
765     for (u32 reg = D0_REGISTER; reg < FPSCR_REGISTER; reg++) {
766         LongToGdbHex(bufptr + reg * 16, FpuRead(reg, current_thread));
767     }
768 
769     bufptr += 16 * 16;
770 
771     IntToGdbHex(bufptr, static_cast<u32>(FpuRead(FPSCR_REGISTER, current_thread)));
772 
773     SendReply(reinterpret_cast<char*>(buffer));
774 }
775 
776 /// Modify data of register specified by gdb client.
WriteRegister()777 static void WriteRegister() {
778     const u8* buffer_ptr = command_buffer + 3;
779 
780     u32 id = HexCharToValue(command_buffer[1]);
781     if (command_buffer[2] != '=') {
782         ++buffer_ptr;
783         id <<= 4;
784         id |= HexCharToValue(command_buffer[2]);
785     }
786 
787     if (id <= PC_REGISTER) {
788         RegWrite(id, GdbHexToInt(buffer_ptr), current_thread);
789     } else if (id == CPSR_REGISTER) {
790         RegWrite(id, GdbHexToInt(buffer_ptr), current_thread);
791     } else if (id >= D0_REGISTER && id < FPSCR_REGISTER) {
792         FpuWrite(id, GdbHexToLong(buffer_ptr), current_thread);
793     } else if (id == FPSCR_REGISTER) {
794         FpuWrite(id, GdbHexToInt(buffer_ptr), current_thread);
795     } else {
796         return SendReply("E01");
797     }
798 
799     Core::GetRunningCore().LoadContext(current_thread->context);
800 
801     SendReply("OK");
802 }
803 
804 /// Modify all registers with data received from the client.
WriteRegisters()805 static void WriteRegisters() {
806     const u8* buffer_ptr = command_buffer + 1;
807 
808     if (command_buffer[0] != 'G')
809         return SendReply("E01");
810 
811     for (u32 i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
812         if (reg <= PC_REGISTER) {
813             RegWrite(reg, GdbHexToInt(buffer_ptr + i * 8));
814         } else if (reg == CPSR_REGISTER) {
815             RegWrite(reg, GdbHexToInt(buffer_ptr + i * 8));
816         } else if (reg == CPSR_REGISTER - 1) {
817             // Dummy FPA register, ignore
818         } else if (reg < CPSR_REGISTER) {
819             // Dummy FPA registers, ignore
820             i += 2;
821         } else if (reg >= D0_REGISTER && reg < FPSCR_REGISTER) {
822             FpuWrite(reg, GdbHexToLong(buffer_ptr + i * 16));
823             i++; // Skip padding
824         } else if (reg == FPSCR_REGISTER) {
825             FpuWrite(reg, GdbHexToInt(buffer_ptr + i * 8));
826         }
827     }
828 
829     Core::GetRunningCore().LoadContext(current_thread->context);
830 
831     SendReply("OK");
832 }
833 
834 /// Read location in memory specified by gdb client.
ReadMemory()835 static void ReadMemory() {
836     static u8 reply[GDB_BUFFER_SIZE - 4];
837 
838     auto start_offset = command_buffer + 1;
839     auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
840     VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
841 
842     start_offset = addr_pos + 1;
843     u32 len =
844         HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
845 
846     LOG_DEBUG(Debug_GDBStub, "gdb: addr: {:08x} len: {:08x}\n", addr, len);
847 
848     if (len * 2 > sizeof(reply)) {
849         SendReply("E01");
850     }
851 
852     if (!Memory::IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
853                                        addr)) {
854         return SendReply("E00");
855     }
856 
857     std::vector<u8> data(len);
858     Core::System::GetInstance().Memory().ReadBlock(
859         *Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, data.data(), len);
860 
861     MemToGdbHex(reply, data.data(), len);
862     reply[len * 2] = '\0';
863     SendReply(reinterpret_cast<char*>(reply));
864 }
865 
866 /// Modify location in memory with data received from the gdb client.
WriteMemory()867 static void WriteMemory() {
868     auto start_offset = command_buffer + 1;
869     auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
870     VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
871 
872     start_offset = addr_pos + 1;
873     auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
874     u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
875 
876     if (!Memory::IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(),
877                                        addr)) {
878         return SendReply("E00");
879     }
880 
881     std::vector<u8> data(len);
882 
883     GdbHexToMem(data.data(), len_pos + 1, len);
884     Core::System::GetInstance().Memory().WriteBlock(
885         *Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, data.data(), len);
886     Core::GetRunningCore().ClearInstructionCache();
887     SendReply("OK");
888 }
889 
Break(bool is_memory_break)890 void Break(bool is_memory_break) {
891     send_trap = true;
892 
893     memory_break = is_memory_break;
894 }
895 
896 /// Tell the CPU that it should perform a single step.
Step()897 static void Step() {
898     if (command_length > 1) {
899         RegWrite(PC_REGISTER, GdbHexToInt(command_buffer + 1), current_thread);
900         Core::GetRunningCore().LoadContext(current_thread->context);
901     }
902     step_loop = true;
903     halt_loop = true;
904     send_trap = true;
905     Core::GetRunningCore().ClearInstructionCache();
906 }
907 
IsMemoryBreak()908 bool IsMemoryBreak() {
909     if (!IsConnected()) {
910         return false;
911     }
912 
913     return memory_break;
914 }
915 
916 /// Tell the CPU to continue executing.
Continue()917 static void Continue() {
918     memory_break = false;
919     step_loop = false;
920     halt_loop = false;
921     Core::GetRunningCore().ClearInstructionCache();
922 }
923 
924 /**
925  * Commit breakpoint to list of breakpoints.
926  *
927  * @param type Type of breakpoint.
928  * @param addr Address of breakpoint.
929  * @param len Length of breakpoint.
930  */
CommitBreakpoint(BreakpointType type,VAddr addr,u32 len)931 static bool CommitBreakpoint(BreakpointType type, VAddr addr, u32 len) {
932     BreakpointMap& p = GetBreakpointMap(type);
933 
934     Breakpoint breakpoint;
935     breakpoint.active = true;
936     breakpoint.addr = addr;
937     breakpoint.len = len;
938     Core::System::GetInstance().Memory().ReadBlock(
939         *Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, breakpoint.inst.data(),
940         breakpoint.inst.size());
941 
942     static constexpr std::array<u8, 4> btrap{0x70, 0x00, 0x20, 0xe1};
943     if (type == BreakpointType::Execute) {
944         Core::System::GetInstance().Memory().WriteBlock(
945             *Core::System::GetInstance().Kernel().GetCurrentProcess(), addr, btrap.data(),
946             btrap.size());
947         Core::GetRunningCore().ClearInstructionCache();
948     }
949     p.insert({addr, breakpoint});
950 
951     LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:08x} bytes at {:08x}\n", type,
952               breakpoint.len, breakpoint.addr);
953 
954     return true;
955 }
956 
957 /// Handle add breakpoint command from gdb client.
AddBreakpoint()958 static void AddBreakpoint() {
959     BreakpointType type;
960 
961     u8 type_id = HexCharToValue(command_buffer[1]);
962     switch (type_id) {
963     case 0:
964     case 1:
965         type = BreakpointType::Execute;
966         break;
967     case 2:
968         type = BreakpointType::Write;
969         break;
970     case 3:
971         type = BreakpointType::Read;
972         break;
973     case 4:
974         type = BreakpointType::Access;
975         break;
976     default:
977         return SendReply("E01");
978     }
979 
980     auto start_offset = command_buffer + 3;
981     auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
982     VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
983 
984     start_offset = addr_pos + 1;
985     u32 len =
986         HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
987 
988     if (type == BreakpointType::Access) {
989         // Access is made up of Read and Write types, so add both breakpoints
990         type = BreakpointType::Read;
991 
992         if (!CommitBreakpoint(type, addr, len)) {
993             return SendReply("E02");
994         }
995 
996         type = BreakpointType::Write;
997     }
998 
999     if (!CommitBreakpoint(type, addr, len)) {
1000         return SendReply("E02");
1001     }
1002 
1003     SendReply("OK");
1004 }
1005 
1006 /// Handle remove breakpoint command from gdb client.
RemoveBreakpoint()1007 static void RemoveBreakpoint() {
1008     BreakpointType type;
1009 
1010     u8 type_id = HexCharToValue(command_buffer[1]);
1011     switch (type_id) {
1012     case 0:
1013     case 1:
1014         type = BreakpointType::Execute;
1015         break;
1016     case 2:
1017         type = BreakpointType::Write;
1018         break;
1019     case 3:
1020         type = BreakpointType::Read;
1021         break;
1022     case 4:
1023         type = BreakpointType::Access;
1024         break;
1025     default:
1026         return SendReply("E01");
1027     }
1028 
1029     auto start_offset = command_buffer + 3;
1030     auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
1031     VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
1032 
1033     if (type == BreakpointType::Access) {
1034         // Access is made up of Read and Write types, so add both breakpoints
1035         type = BreakpointType::Read;
1036         RemoveBreakpoint(type, addr);
1037 
1038         type = BreakpointType::Write;
1039     }
1040 
1041     RemoveBreakpoint(type, addr);
1042     SendReply("OK");
1043 }
1044 
HandlePacket()1045 void HandlePacket() {
1046     if (!IsConnected()) {
1047         if (defer_start) {
1048             ToggleServer(true);
1049         }
1050         return;
1051     }
1052 
1053     if (!IsDataAvailable()) {
1054         return;
1055     }
1056 
1057     ReadCommand();
1058     if (command_length == 0) {
1059         return;
1060     }
1061 
1062     LOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer);
1063 
1064     switch (command_buffer[0]) {
1065     case 'q':
1066         HandleQuery();
1067         break;
1068     case 'H':
1069         HandleSetThread();
1070         break;
1071     case '?':
1072         SendSignal(current_thread, latest_signal);
1073         break;
1074     case 'k':
1075         Shutdown();
1076         LOG_INFO(Debug_GDBStub, "killed by gdb");
1077         return;
1078     case 'g':
1079         ReadRegisters();
1080         break;
1081     case 'G':
1082         WriteRegisters();
1083         break;
1084     case 'p':
1085         ReadRegister();
1086         break;
1087     case 'P':
1088         WriteRegister();
1089         break;
1090     case 'm':
1091         ReadMemory();
1092         break;
1093     case 'M':
1094         WriteMemory();
1095         break;
1096     case 's':
1097         Step();
1098         return;
1099     case 'C':
1100     case 'c':
1101         Continue();
1102         return;
1103     case 'z':
1104         RemoveBreakpoint();
1105         break;
1106     case 'Z':
1107         AddBreakpoint();
1108         break;
1109     case 'T':
1110         HandleThreadAlive();
1111         break;
1112     default:
1113         SendReply("");
1114         break;
1115     }
1116 }
1117 
SetServerPort(u16 port)1118 void SetServerPort(u16 port) {
1119     gdbstub_port = port;
1120 }
1121 
ToggleServer(bool status)1122 void ToggleServer(bool status) {
1123     if (status) {
1124         server_enabled = status;
1125 
1126         // Start server
1127         if (!IsConnected() && Core::System::GetInstance().IsPoweredOn()) {
1128             Init();
1129         }
1130     } else {
1131         // Stop server
1132         if (IsConnected()) {
1133             Shutdown();
1134         }
1135 
1136         server_enabled = status;
1137     }
1138 }
1139 
DeferStart()1140 void DeferStart() {
1141     defer_start = true;
1142 }
1143 
Init(u16 port)1144 static void Init(u16 port) {
1145     if (!server_enabled) {
1146         // Set the halt loop to false in case the user enabled the gdbstub mid-execution.
1147         // This way the CPU can still execute normally.
1148         halt_loop = false;
1149         step_loop = false;
1150         return;
1151     }
1152 
1153     // Setup initial gdbstub status
1154     halt_loop = true;
1155     step_loop = false;
1156 
1157     breakpoints_execute.clear();
1158     breakpoints_read.clear();
1159     breakpoints_write.clear();
1160 
1161     // Start gdb server
1162     LOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port);
1163 
1164     sockaddr_in saddr_server = {};
1165     saddr_server.sin_family = AF_INET;
1166     saddr_server.sin_port = htons(port);
1167     saddr_server.sin_addr.s_addr = INADDR_ANY;
1168 
1169 #ifdef _WIN32
1170     WSAStartup(MAKEWORD(2, 2), &InitData);
1171 #endif
1172 
1173     int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0));
1174     if (tmpsock == -1) {
1175         LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
1176     }
1177 
1178     // Set socket to SO_REUSEADDR so it can always bind on the same port
1179     int reuse_enabled = 1;
1180     if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled,
1181                    sizeof(reuse_enabled)) < 0) {
1182         LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option");
1183     }
1184 
1185     const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server);
1186     socklen_t server_addrlen = sizeof(saddr_server);
1187     if (bind(tmpsock, server_addr, server_addrlen) < 0) {
1188         LOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket");
1189     }
1190 
1191     if (listen(tmpsock, 1) < 0) {
1192         LOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket");
1193     }
1194 
1195     // Wait for gdb to connect
1196     LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...\n");
1197     sockaddr_in saddr_client;
1198     sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client);
1199     socklen_t client_addrlen = sizeof(saddr_client);
1200     gdbserver_socket = static_cast<int>(accept(tmpsock, client_addr, &client_addrlen));
1201     if (gdbserver_socket < 0) {
1202         // In the case that we couldn't start the server for whatever reason, just start CPU
1203         // execution like normal.
1204         halt_loop = false;
1205         step_loop = false;
1206 
1207         LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client");
1208     } else {
1209         LOG_INFO(Debug_GDBStub, "Client connected.\n");
1210         saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr);
1211     }
1212 
1213     // Clean up temporary socket if it's still alive at this point.
1214     if (tmpsock != -1) {
1215         shutdown(tmpsock, SHUT_RDWR);
1216     }
1217 }
1218 
Init()1219 void Init() {
1220     Init(gdbstub_port);
1221 }
1222 
Shutdown()1223 void Shutdown() {
1224     if (!server_enabled) {
1225         return;
1226     }
1227     defer_start = false;
1228 
1229     LOG_INFO(Debug_GDBStub, "Stopping GDB ...");
1230     if (gdbserver_socket != -1) {
1231         shutdown(gdbserver_socket, SHUT_RDWR);
1232         gdbserver_socket = -1;
1233     }
1234 
1235 #ifdef _WIN32
1236     WSACleanup();
1237 #endif
1238 
1239     LOG_INFO(Debug_GDBStub, "GDB stopped.");
1240 }
1241 
IsServerEnabled()1242 bool IsServerEnabled() {
1243     return server_enabled;
1244 }
1245 
IsConnected()1246 bool IsConnected() {
1247     return IsServerEnabled() && gdbserver_socket != -1;
1248 }
1249 
GetCpuHaltFlag()1250 bool GetCpuHaltFlag() {
1251     return halt_loop;
1252 }
1253 
GetCpuStepFlag()1254 bool GetCpuStepFlag() {
1255     return step_loop;
1256 }
1257 
SetCpuStepFlag(bool is_step)1258 void SetCpuStepFlag(bool is_step) {
1259     step_loop = is_step;
1260 }
1261 
SendTrap(Kernel::Thread * thread,int trap)1262 void SendTrap(Kernel::Thread* thread, int trap) {
1263     if (!send_trap) {
1264         return;
1265     }
1266 
1267     current_thread = thread;
1268     SendSignal(thread, trap);
1269 
1270     halt_loop = true;
1271     send_trap = false;
1272 }
1273 }; // namespace GDBStub
1274