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