summaryrefslogtreecommitdiff
path: root/src/core/gdbstub/gdbstub.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2016-04-08 16:03:40 -0400
committerGravatar bunnei2016-04-08 16:03:40 -0400
commita4c5d8fd50e32545494a4ac158892310dfe98489 (patch)
tree7d7ac94d1f93e6664c28e078fae6f321d1e3f83b /src/core/gdbstub/gdbstub.cpp
parentupdate the code of AM service! (#1623) (diff)
parentDefault to settings from ini for gdbstub (diff)
downloadyuzu-a4c5d8fd50e32545494a4ac158892310dfe98489.tar.gz
yuzu-a4c5d8fd50e32545494a4ac158892310dfe98489.tar.xz
yuzu-a4c5d8fd50e32545494a4ac158892310dfe98489.zip
Merge pull request #1644 from polaris-/gdb-fixes
Adopted WinterMute's gdbstub changes
Diffstat (limited to 'src/core/gdbstub/gdbstub.cpp')
-rw-r--r--src/core/gdbstub/gdbstub.cpp108
1 files changed, 85 insertions, 23 deletions
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 3a2445241..c1a7ec5bf 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -60,6 +60,59 @@ const u32 R15_REGISTER = 15;
60const u32 CPSR_REGISTER = 25; 60const u32 CPSR_REGISTER = 25;
61const u32 FPSCR_REGISTER = 58; 61const u32 FPSCR_REGISTER = 58;
62 62
63// For sample XML files see the GDB source /gdb/features
64// GDB also wants the l character at the start
65// This XML defines what the registers are for this specific ARM device
66static const char* target_xml =
67R"(l<?xml version="1.0"?>
68<!DOCTYPE target SYSTEM "gdb-target.dtd">
69<target version="1.0">
70 <feature name="org.gnu.gdb.arm.core">
71 <reg name="r0" bitsize="32"/>
72 <reg name="r1" bitsize="32"/>
73 <reg name="r2" bitsize="32"/>
74 <reg name="r3" bitsize="32"/>
75 <reg name="r4" bitsize="32"/>
76 <reg name="r5" bitsize="32"/>
77 <reg name="r6" bitsize="32"/>
78 <reg name="r7" bitsize="32"/>
79 <reg name="r8" bitsize="32"/>
80 <reg name="r9" bitsize="32"/>
81 <reg name="r10" bitsize="32"/>
82 <reg name="r11" bitsize="32"/>
83 <reg name="r12" bitsize="32"/>
84 <reg name="sp" bitsize="32" type="data_ptr"/>
85 <reg name="lr" bitsize="32"/>
86 <reg name="pc" bitsize="32" type="code_ptr"/>
87
88 <!-- The CPSR is register 25, rather than register 16, because
89 the FPA registers historically were placed between the PC
90 and the CPSR in the "g" packet. -->
91
92 <reg name="cpsr" bitsize="32" regnum="25"/>
93 </feature>
94 <feature name="org.gnu.gdb.arm.vfp">
95 <reg name="d0" bitsize="64" type="float"/>
96 <reg name="d1" bitsize="64" type="float"/>
97 <reg name="d2" bitsize="64" type="float"/>
98 <reg name="d3" bitsize="64" type="float"/>
99 <reg name="d4" bitsize="64" type="float"/>
100 <reg name="d5" bitsize="64" type="float"/>
101 <reg name="d6" bitsize="64" type="float"/>
102 <reg name="d7" bitsize="64" type="float"/>
103 <reg name="d8" bitsize="64" type="float"/>
104 <reg name="d9" bitsize="64" type="float"/>
105 <reg name="d10" bitsize="64" type="float"/>
106 <reg name="d11" bitsize="64" type="float"/>
107 <reg name="d12" bitsize="64" type="float"/>
108 <reg name="d13" bitsize="64" type="float"/>
109 <reg name="d14" bitsize="64" type="float"/>
110 <reg name="d15" bitsize="64" type="float"/>
111 <reg name="fpscr" bitsize="32" type="int" group="float"/>
112 </feature>
113</target>
114)";
115
63namespace GDBStub { 116namespace GDBStub {
64 117
65static int gdbserver_socket = -1; 118static int gdbserver_socket = -1;
@@ -211,7 +264,7 @@ static u8 ReadByte() {
211} 264}
212 265
213/// Calculate the checksum of the current command buffer. 266/// Calculate the checksum of the current command buffer.
214static u8 CalculateChecksum(u8 *buffer, u32 length) { 267static u8 CalculateChecksum(u8* buffer, u32 length) {
215 return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>())); 268 return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>()));
216} 269}
217 270
@@ -353,8 +406,15 @@ static void SendReply(const char* reply) {
353static void HandleQuery() { 406static void HandleQuery() {
354 LOG_DEBUG(Debug_GDBStub, "gdb: query '%s'\n", command_buffer + 1); 407 LOG_DEBUG(Debug_GDBStub, "gdb: query '%s'\n", command_buffer + 1);
355 408
356 if (!strcmp(reinterpret_cast<const char*>(command_buffer + 1), "TStatus")) { 409 const char* query = reinterpret_cast<const char*>(command_buffer + 1);
410
411 if (strcmp(query, "TStatus") == 0 ) {
357 SendReply("T0"); 412 SendReply("T0");
413 } else if (strncmp(query, "Supported:", strlen("Supported:")) == 0) {
414 // PacketSize needs to be large enough for target xml
415 SendReply("PacketSize=800;qXfer:features:read+");
416 } else if (strncmp(query, "Xfer:features:read:target.xml:", strlen("Xfer:features:read:target.xml:")) == 0) {
417 SendReply(target_xml);
358 } else { 418 } else {
359 SendReply(""); 419 SendReply("");
360 } 420 }
@@ -491,29 +551,25 @@ static void ReadRegisters() {
491 memset(buffer, 0, sizeof(buffer)); 551 memset(buffer, 0, sizeof(buffer));
492 552
493 u8* bufptr = buffer; 553 u8* bufptr = buffer;
494 for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) { 554
495 if (reg <= R15_REGISTER) { 555 for (int reg = 0; reg <= R15_REGISTER; reg++) {
496 IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetReg(reg)); 556 IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetReg(reg));
497 } else if (reg == CPSR_REGISTER) {
498 IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetCPSR());
499 } else if (reg == CPSR_REGISTER - 1) {
500 // Dummy FPA register, ignore
501 IntToGdbHex(bufptr + i * CHAR_BIT, 0);
502 } else if (reg < CPSR_REGISTER) {
503 // Dummy FPA registers, ignore
504 IntToGdbHex(bufptr + i * CHAR_BIT, 0);
505 IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0);
506 IntToGdbHex(bufptr + (i + 2) * CHAR_BIT, 0);
507 i += 2;
508 } else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
509 IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPReg(reg - CPSR_REGISTER - 1));
510 IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0);
511 i++;
512 } else if (reg == FPSCR_REGISTER) {
513 IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR));
514 }
515 } 557 }
516 558
559 bufptr += (16 * CHAR_BIT);
560
561 IntToGdbHex(bufptr, Core::g_app_core->GetCPSR());
562
563 bufptr += CHAR_BIT;
564
565 for (int reg = 0; reg <= 31; reg++) {
566 IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetVFPReg(reg));
567 }
568
569 bufptr += (32 * CHAR_BIT);
570
571 IntToGdbHex(bufptr, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR));
572
517 SendReply(reinterpret_cast<char*>(buffer)); 573 SendReply(reinterpret_cast<char*>(buffer));
518} 574}
519 575
@@ -885,6 +941,12 @@ void Init(u16 port) {
885 LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); 941 LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
886 } 942 }
887 943
944 // Set socket to SO_REUSEADDR so it can always bind on the same port
945 int reuse_enabled = 1;
946 if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, sizeof(reuse_enabled)) < 0) {
947 LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option");
948 }
949
888 const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server); 950 const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server);
889 socklen_t server_addrlen = sizeof(saddr_server); 951 socklen_t server_addrlen = sizeof(saddr_server);
890 if (bind(tmpsock, server_addr, server_addrlen) < 0) { 952 if (bind(tmpsock, server_addr, server_addrlen) < 0) {