mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Fix bug with reading addresses and lengths
This commit is contained in:
		
							parent
							
								
									b6422038b5
								
							
						
					
					
						commit
						bcea959910
					
				
					 1 changed files with 55 additions and 45 deletions
				
			
		|  | @ -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<char*>(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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue