citra-emu
/
citra
Archived
1
0
Fork 0

Fix read and write register blocks in gdbstub

Previously, the padding wasn't correctly accounted for which caused the gdbstub to read and write everything after R15 (starting with the dummy FPA registers) incorrectly, which caused CPSR to not be handled correctly. Everything appears to be working as expected with this change.
This commit is contained in:
polaris- 2015-11-21 10:31:02 -05:00 committed by polaris-
parent ac829f87e0
commit 2732ec758d
1 changed files with 31 additions and 26 deletions

View File

@ -57,9 +57,8 @@ const u32 MSG_WAITALL = 8;
const u32 R0_REGISTER = 0; const u32 R0_REGISTER = 0;
const u32 R15_REGISTER = 15; const u32 R15_REGISTER = 15;
const u32 CSPR_REGISTER = 25; const u32 CPSR_REGISTER = 25;
const u32 FPSCR_REGISTER = 58; const u32 FPSCR_REGISTER = 58;
const u32 MAX_REGISTERS = 90;
namespace GDBStub { namespace GDBStub {
@ -472,10 +471,10 @@ static void ReadRegister() {
if (id >= R0_REGISTER && id <= R15_REGISTER) { if (id >= R0_REGISTER && id <= R15_REGISTER) {
IntToGdbHex(reply, Core::g_app_core->GetReg(id)); IntToGdbHex(reply, Core::g_app_core->GetReg(id));
} else if (id == CSPR_REGISTER) { } else if (id == CPSR_REGISTER) {
IntToGdbHex(reply, Core::g_app_core->GetCPSR()); IntToGdbHex(reply, Core::g_app_core->GetCPSR());
} else if (id > CSPR_REGISTER && id < FPSCR_REGISTER) { } else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
IntToGdbHex(reply, Core::g_app_core->GetVFPReg(id - CSPR_REGISTER - 1)); // VFP registers should start at 26, so one after CSPR_REGISTER IntToGdbHex(reply, Core::g_app_core->GetVFPReg(id - CPSR_REGISTER - 1)); // VFP registers should start at 26, so one after CSPR_REGISTER
} else if (id == FPSCR_REGISTER) { } else if (id == FPSCR_REGISTER) {
IntToGdbHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR IntToGdbHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR
IntToGdbHex(reply + 8, 0); IntToGdbHex(reply + 8, 0);
@ -492,21 +491,25 @@ static void ReadRegisters() {
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
u8* bufptr = buffer; u8* bufptr = buffer;
for (int i = 0, reg = 0; i <= MAX_REGISTERS; i++, reg++) { for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
if (i <= R15_REGISTER) { if (reg <= R15_REGISTER) {
IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetReg(reg)); IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetReg(reg));
} else if (i == CSPR_REGISTER) { } else if (reg == CPSR_REGISTER) {
IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetCPSR()); IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetCPSR());
} else if (i < CSPR_REGISTER) { } else if (reg == CPSR_REGISTER - 1) {
// Dummy FPA register, ignore
IntToGdbHex(bufptr + i * CHAR_BIT, 0);
} else if (reg < CPSR_REGISTER) {
// Dummy FPA registers, ignore
IntToGdbHex(bufptr + i * CHAR_BIT, 0); IntToGdbHex(bufptr + i * CHAR_BIT, 0);
IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0); IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0);
i++; // These registers seem to be all 64bit instead of 32bit, so skip two instead of one IntToGdbHex(bufptr + (i + 2) * CHAR_BIT, 0);
reg++; i += 2;
} else if (i > CSPR_REGISTER && i < MAX_REGISTERS) { } else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPReg(reg - CSPR_REGISTER - 1)); IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPReg(reg - CPSR_REGISTER - 1));
IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0); IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0);
i++; i++;
} else if (i == MAX_REGISTERS) { } else if (reg == FPSCR_REGISTER) {
IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR));
} }
} }
@ -527,10 +530,10 @@ static void WriteRegister() {
if (id >= R0_REGISTER && id <= R15_REGISTER) { if (id >= R0_REGISTER && id <= R15_REGISTER) {
Core::g_app_core->SetReg(id, GdbHexToInt(buffer_ptr)); Core::g_app_core->SetReg(id, GdbHexToInt(buffer_ptr));
} else if (id == CSPR_REGISTER) { } else if (id == CPSR_REGISTER) {
Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr)); Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr));
} else if (id > CSPR_REGISTER && id < FPSCR_REGISTER) { } else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
Core::g_app_core->SetVFPReg(id - CSPR_REGISTER - 1, GdbHexToInt(buffer_ptr)); Core::g_app_core->SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr));
} else if (id == FPSCR_REGISTER) { } else if (id == FPSCR_REGISTER) {
Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr)); Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr));
} else { } else {
@ -547,18 +550,20 @@ static void WriteRegisters() {
if (command_buffer[0] != 'G') if (command_buffer[0] != 'G')
return SendReply("E01"); return SendReply("E01");
for (int i = 0, reg = 0; i <= MAX_REGISTERS; i++, reg++) { for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
if (i <= R15_REGISTER) { if (reg <= R15_REGISTER) {
Core::g_app_core->SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); Core::g_app_core->SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
} else if (i == CSPR_REGISTER) { } else if (reg == CPSR_REGISTER) {
Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT)); Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT));
} else if (i < CSPR_REGISTER) { } else if (reg == CPSR_REGISTER - 1) {
i++; // These registers seem to be all 64bit instead of 32bit, so skip two instead of one // Dummy FPA register, ignore
reg++; } else if (reg < CPSR_REGISTER) {
} else if (i > CSPR_REGISTER && i < MAX_REGISTERS) { // Dummy FPA registers, ignore
Core::g_app_core->SetVFPReg(reg - CSPR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); i += 2;
} else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
Core::g_app_core->SetVFPReg(reg - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
i++; // Skip padding i++; // Skip padding
} else if (i == MAX_REGISTERS) { } else if (reg == FPSCR_REGISTER) {
Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
} }
} }