From bcea9599100a0df945629cd50be066ae9dabf89f Mon Sep 17 00:00:00 2001 From: polaris- Date: Tue, 3 Nov 2015 21:50:53 -0500 Subject: Fix bug with reading addresses and lengths --- src/core/gdbstub/gdbstub.cpp | 100 ++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index e37a2efd7..003ce4167 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -126,6 +126,22 @@ static u8 NibbleToHex(u8 n) { } } +/** +* Converts input hex string characters into an array of equivalent of u8 bytes. +* +* @param dest Pointer to buffer to store u8 bytes. +* @param src Pointer to array of output hex string characters. +* @param len Length of src array. +*/ +static u32 HexToInt(u8* src, u32 len) { + u32 output = 0; + while (len-- > 0) { + output = (output << 4) | HexCharToValue(src[0]); + src++; + } + return output; +} + /** * Converts input array of u8 bytes into their equivalent hex string characters. * @@ -133,7 +149,7 @@ static u8 NibbleToHex(u8 n) { * @param src Pointer to array of u8 bytes. * @param len Length of src array. */ -static void MemToHex(u8* dest, u8* src, u32 len) { +static void MemToGdbHex(u8* dest, u8* src, u32 len) { while (len-- > 0) { u8 tmp = *src++; *dest++ = NibbleToHex(tmp >> 4); @@ -142,13 +158,13 @@ static void MemToHex(u8* dest, u8* src, u32 len) { } /** - * Converts input hex string characters into an array of equivalent of u8 bytes. + * Converts input gdb-formatted hex string characters into an array of equivalent of u8 bytes. * * @param dest Pointer to buffer to store u8 bytes. * @param src Pointer to array of output hex string characters. * @param len Length of src array. */ -static void HexToMem(u8* dest, u8* src, u32 len) { +static void GdbHexToMem(u8* dest, u8* src, u32 len) { while (len-- > 0) { *dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]); src += 2; @@ -156,11 +172,11 @@ static void HexToMem(u8* dest, u8* src, u32 len) { } /** - * Convert a u32 into a hex string. + * Convert a u32 into a gdb-formatted hex string. * * @param dest Pointer to buffer to store output hex string characters. */ -static void IntToHex(u8* dest, u32 v) { +static void IntToGdbHex(u8* dest, u32 v) { for (int i = 0; i < 8; i += 2) { dest[i + 1] = NibbleToHex(v >> (4 * i)); dest[i] = NibbleToHex(v >> (4 * (i + 1))); @@ -168,11 +184,11 @@ static void IntToHex(u8* dest, u32 v) { } /** - * Convert a hex string into a u32. + * Convert a gdb-formatted hex string into a u32. * * @param src Pointer to hex string. */ -static u32 HexToInt(u8* src) { +static u32 GdbHexToInt(u8* src) { u32 output = 0; for (int i = 0; i < 8; i += 2) { @@ -455,14 +471,14 @@ static void ReadRegister() { } if (id >= R0_REGISTER && id <= R15_REGISTER) { - IntToHex(reply, Core::g_app_core->GetReg(id)); + IntToGdbHex(reply, Core::g_app_core->GetReg(id)); } else if (id == CSPR_REGISTER) { - IntToHex(reply, Core::g_app_core->GetCPSR()); + IntToGdbHex(reply, Core::g_app_core->GetCPSR()); } else if (id > CSPR_REGISTER && id < FPSCR_REGISTER) { - IntToHex(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 - CSPR_REGISTER - 1)); // VFP registers should start at 26, so one after CSPR_REGISTER } else if (id == FPSCR_REGISTER) { - IntToHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR - IntToHex(reply + 8, 0); + IntToGdbHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR + IntToGdbHex(reply + 8, 0); } else { return SendReply("E01"); } @@ -478,20 +494,20 @@ static void ReadRegisters() { u8* bufptr = buffer; for (int i = 0, reg = 0; i <= MAX_REGISTERS; i++, reg++) { if (i <= R15_REGISTER) { - IntToHex(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) { - IntToHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetCPSR()); + IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetCPSR()); } else if (i < CSPR_REGISTER) { - IntToHex(bufptr + i * CHAR_BIT, 0); - IntToHex(bufptr + (i + 1) * CHAR_BIT, 0); + IntToGdbHex(bufptr + i * 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 reg++; } else if (i > CSPR_REGISTER && i < MAX_REGISTERS) { - IntToHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPReg(reg - CSPR_REGISTER - 1)); - IntToHex(bufptr + (i + 1) * CHAR_BIT, 0); + IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPReg(reg - CSPR_REGISTER - 1)); + IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0); i++; } else if (i == MAX_REGISTERS) { - IntToHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); + IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); } } @@ -510,13 +526,13 @@ static void WriteRegister() { } if (id >= R0_REGISTER && id <= R15_REGISTER) { - Core::g_app_core->SetReg(id, HexToInt(buffer_ptr)); + Core::g_app_core->SetReg(id, GdbHexToInt(buffer_ptr)); } else if (id == CSPR_REGISTER) { - Core::g_app_core->SetCPSR(HexToInt(buffer_ptr)); + Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr)); } else if (id > CSPR_REGISTER && id < FPSCR_REGISTER) { - Core::g_app_core->SetVFPReg(id - CSPR_REGISTER - 1, HexToInt(buffer_ptr)); + Core::g_app_core->SetVFPReg(id - CSPR_REGISTER - 1, GdbHexToInt(buffer_ptr)); } else if (id == FPSCR_REGISTER) { - Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, HexToInt(buffer_ptr)); + Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr)); } else { return SendReply("E01"); } @@ -533,17 +549,17 @@ static void WriteRegisters() { for (int i = 0, reg = 0; i <= MAX_REGISTERS; i++, reg++) { if (i <= R15_REGISTER) { - Core::g_app_core->SetReg(reg, HexToInt(buffer_ptr + i * CHAR_BIT)); + Core::g_app_core->SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); } else if (i == CSPR_REGISTER) { - Core::g_app_core->SetCPSR(HexToInt(buffer_ptr + i * CHAR_BIT)); + Core::g_app_core->SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT)); } else if (i < CSPR_REGISTER) { i++; // These registers seem to be all 64bit instead of 32bit, so skip two instead of one reg++; } else if (i > CSPR_REGISTER && i < MAX_REGISTERS) { - Core::g_app_core->SetVFPReg(reg - CSPR_REGISTER - 1, HexToInt(buffer_ptr + i * CHAR_BIT)); + Core::g_app_core->SetVFPReg(reg - CSPR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); i++; // Skip padding } else if (i == MAX_REGISTERS) { - Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, HexToInt(buffer_ptr + i * CHAR_BIT)); + Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); } } @@ -556,12 +572,12 @@ static void ReadMemory() { auto start_offset = command_buffer+1; auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); - PAddr addr = 0; - HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + PAddr addr = HexToInt(start_offset, addr_pos - start_offset); start_offset = addr_pos+1; - u32 len = 0; - HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); + u32 len = HexToInt(start_offset, (command_buffer + command_length) - start_offset); + + LOG_DEBUG(Debug_GDBStub, "gdb: addr: %08x len: %08x\n", addr, len); if (len * 2 > sizeof(reply)) { SendReply("E01"); @@ -572,7 +588,7 @@ static void ReadMemory() { return SendReply("E0"); } - MemToHex(reply, data, len); + MemToGdbHex(reply, data, len); reply[len * 2] = '\0'; SendReply(reinterpret_cast(reply)); } @@ -581,20 +597,18 @@ static void ReadMemory() { static void WriteMemory() { auto start_offset = command_buffer+1; auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); - PAddr addr = 0; - HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + PAddr addr = HexToInt(start_offset, addr_pos - start_offset); start_offset = addr_pos+1; auto len_pos = std::find(start_offset, command_buffer+command_length, ':'); - u32 len = 0; - HexToMem((u8*)&len, start_offset, (len_pos - start_offset) / 2); + u32 len = HexToInt(start_offset, len_pos - start_offset); u8* dst = Memory::GetPointer(addr); if (!dst) { return SendReply("E00"); } - HexToMem(dst, len_pos + 1, len); + GdbHexToMem(dst, len_pos + 1, len); SendReply("OK"); } @@ -677,12 +691,10 @@ static void AddBreakpoint() { auto start_offset = command_buffer+3; auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); - PAddr addr = 0; - HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + PAddr addr = HexToInt(start_offset, addr_pos - start_offset); start_offset = addr_pos+1; - u32 len = 0; - HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); + u32 len = HexToInt(start_offset, (command_buffer + command_length) - start_offset); if (type == BreakpointType::Access) { // Access is made up of Read and Write types, so add both breakpoints @@ -727,12 +739,10 @@ static void RemoveBreakpoint() { auto start_offset = command_buffer+3; auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); - PAddr addr = 0; - HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + PAddr addr = HexToInt(start_offset, addr_pos - start_offset); start_offset = addr_pos+1; - u32 len = 0; - HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); + u32 len = HexToInt(start_offset, (command_buffer + command_length) - start_offset); if (type == BreakpointType::Access) { // Access is made up of Read and Write types, so add both breakpoints -- cgit v1.2.3