forked from eden-emu/eden
		
	gdbstub: Update registers and sizes for aarch64
This gets gdbstub working at least to the point where clients can communicate with it. What works: - Reading/writing GPRegs - Reading/writing memory - Interrupting the emulated program and continuing What does NOT work: - Breakpoints. Sizes have been updated to u64, but support will need to be added in the interpreter for them to work. - VRegs. Mostly because my gdb was having issues with 128-bit regs for some reason. However, the current u128 representation is a bit awkward to use and should probably be updated first.
This commit is contained in:
		
							parent
							
								
									4f20190c95
								
							
						
					
					
						commit
						939be88b01
					
				
					 1 changed files with 154 additions and 112 deletions
				
			
		|  | @ -57,9 +57,10 @@ const u32 SIGTERM = 15; | ||||||
| const u32 MSG_WAITALL = 8; | const u32 MSG_WAITALL = 8; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| const u32 R15_REGISTER = 15; | const u32 X30_REGISTER = 30; | ||||||
| const u32 CPSR_REGISTER = 25; | const u32 SP_REGISTER = 31; | ||||||
| const u32 FPSCR_REGISTER = 58; | const u32 PC_REGISTER = 32; | ||||||
|  | const u32 CPSR_REGISTER = 33; | ||||||
| 
 | 
 | ||||||
| // For sample XML files see the GDB source /gdb/features
 | // For sample XML files see the GDB source /gdb/features
 | ||||||
| // GDB also wants the l character at the start
 | // GDB also wants the l character at the start
 | ||||||
|  | @ -68,48 +69,62 @@ static const char* target_xml = | ||||||
|     R"(l<?xml version="1.0"?> |     R"(l<?xml version="1.0"?> | ||||||
| <!DOCTYPE target SYSTEM "gdb-target.dtd"> | <!DOCTYPE target SYSTEM "gdb-target.dtd"> | ||||||
| <target version="1.0"> | <target version="1.0"> | ||||||
|   <feature name="org.gnu.gdb.arm.core"> |   <feature name="org.gnu.gdb.aarch64.core"> | ||||||
|     <reg name="r0" bitsize="32"/> |     <reg name="x0" bitsize="64"/> | ||||||
|     <reg name="r1" bitsize="32"/> |     <reg name="x1" bitsize="64"/> | ||||||
|     <reg name="r2" bitsize="32"/> |     <reg name="x2" bitsize="64"/> | ||||||
|     <reg name="r3" bitsize="32"/> |     <reg name="x3" bitsize="64"/> | ||||||
|     <reg name="r4" bitsize="32"/> |     <reg name="x4" bitsize="64"/> | ||||||
|     <reg name="r5" bitsize="32"/> |     <reg name="x5" bitsize="64"/> | ||||||
|     <reg name="r6" bitsize="32"/> |     <reg name="x6" bitsize="64"/> | ||||||
|     <reg name="r7" bitsize="32"/> |     <reg name="x7" bitsize="64"/> | ||||||
|     <reg name="r8" bitsize="32"/> |     <reg name="x8" bitsize="64"/> | ||||||
|     <reg name="r9" bitsize="32"/> |     <reg name="x9" bitsize="64"/> | ||||||
|     <reg name="r10" bitsize="32"/> |     <reg name="x10" bitsize="64"/> | ||||||
|     <reg name="r11" bitsize="32"/> |     <reg name="x11" bitsize="64"/> | ||||||
|     <reg name="r12" bitsize="32"/> |     <reg name="x12" bitsize="64"/> | ||||||
|     <reg name="sp" bitsize="32" type="data_ptr"/> |     <reg name="x13" bitsize="64"/> | ||||||
|     <reg name="lr" bitsize="32"/> |     <reg name="x14" bitsize="64"/> | ||||||
|     <reg name="pc" bitsize="32" type="code_ptr"/> |     <reg name="x15" bitsize="64"/> | ||||||
|  |     <reg name="x16" bitsize="64"/> | ||||||
|  |     <reg name="x17" bitsize="64"/> | ||||||
|  |     <reg name="x18" bitsize="64"/> | ||||||
|  |     <reg name="x19" bitsize="64"/> | ||||||
|  |     <reg name="x20" bitsize="64"/> | ||||||
|  |     <reg name="x21" bitsize="64"/> | ||||||
|  |     <reg name="x22" bitsize="64"/> | ||||||
|  |     <reg name="x23" bitsize="64"/> | ||||||
|  |     <reg name="x24" bitsize="64"/> | ||||||
|  |     <reg name="x25" bitsize="64"/> | ||||||
|  |     <reg name="x26" bitsize="64"/> | ||||||
|  |     <reg name="x27" bitsize="64"/> | ||||||
|  |     <reg name="x28" bitsize="64"/> | ||||||
|  |     <reg name="x29" bitsize="64"/> | ||||||
|  |     <reg name="x30" bitsize="64"/> | ||||||
|  |     <reg name="sp" bitsize="64" type="data_ptr"/> | ||||||
| 
 | 
 | ||||||
|     <!-- The CPSR is register 25, rather than register 16, because |     <reg name="pc" bitsize="64" type="code_ptr"/> | ||||||
|          the FPA registers historically were placed between the PC |  | ||||||
|          and the CPSR in the "g" packet.  --> |  | ||||||
| 
 | 
 | ||||||
|     <reg name="cpsr" bitsize="32" regnum="25"/> |     <flags id="cpsr_flags" size="4"> | ||||||
|   </feature> |       <field name="SP" start="0" end="0"/> | ||||||
|   <feature name="org.gnu.gdb.arm.vfp"> |       <field name="" start="1" end="1"/> | ||||||
|     <reg name="d0" bitsize="64" type="float"/> |       <field name="EL" start="2" end="3"/> | ||||||
|     <reg name="d1" bitsize="64" type="float"/> |       <field name="nRW" start="4" end="4"/> | ||||||
|     <reg name="d2" bitsize="64" type="float"/> |       <field name="" start="5" end="5"/> | ||||||
|     <reg name="d3" bitsize="64" type="float"/> |       <field name="F" start="6" end="6"/> | ||||||
|     <reg name="d4" bitsize="64" type="float"/> |       <field name="I" start="7" end="7"/> | ||||||
|     <reg name="d5" bitsize="64" type="float"/> |       <field name="A" start="8" end="8"/> | ||||||
|     <reg name="d6" bitsize="64" type="float"/> |       <field name="D" start="9" end="9"/> | ||||||
|     <reg name="d7" bitsize="64" type="float"/> | 
 | ||||||
|     <reg name="d8" bitsize="64" type="float"/> |       <field name="IL" start="20" end="20"/> | ||||||
|     <reg name="d9" bitsize="64" type="float"/> |       <field name="SS" start="21" end="21"/> | ||||||
|     <reg name="d10" bitsize="64" type="float"/> | 
 | ||||||
|     <reg name="d11" bitsize="64" type="float"/> |       <field name="V" start="28" end="28"/> | ||||||
|     <reg name="d12" bitsize="64" type="float"/> |       <field name="C" start="29" end="29"/> | ||||||
|     <reg name="d13" bitsize="64" type="float"/> |       <field name="Z" start="30" end="30"/> | ||||||
|     <reg name="d14" bitsize="64" type="float"/> |       <field name="N" start="31" end="31"/> | ||||||
|     <reg name="d15" bitsize="64" type="float"/> |     </flags> | ||||||
|     <reg name="fpscr" bitsize="32" type="int" group="float"/> |     <reg name="cpsr" bitsize="32" type="cpsr_flags"/> | ||||||
|   </feature> |   </feature> | ||||||
| </target> | </target> | ||||||
| )"; | )"; | ||||||
|  | @ -143,12 +158,12 @@ WSADATA InitData; | ||||||
| struct Breakpoint { | struct Breakpoint { | ||||||
|     bool active; |     bool active; | ||||||
|     PAddr addr; |     PAddr addr; | ||||||
|     u32 len; |     u64 len; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static std::map<u32, Breakpoint> breakpoints_execute; | static std::map<u64, Breakpoint> breakpoints_execute; | ||||||
| static std::map<u32, Breakpoint> breakpoints_read; | static std::map<u64, Breakpoint> breakpoints_read; | ||||||
| static std::map<u32, Breakpoint> breakpoints_write; | static std::map<u64, Breakpoint> breakpoints_write; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Turns hex string character into the equivalent byte. |  * Turns hex string character into the equivalent byte. | ||||||
|  | @ -197,6 +212,21 @@ static u32 HexToInt(const u8* src, size_t len) { | ||||||
|     return output; |     return output; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Converts input hex string characters into an array of equivalent of u8 bytes. | ||||||
|  |  * | ||||||
|  |  * @param src Pointer to array of output hex string characters. | ||||||
|  |  * @param len Length of src array. | ||||||
|  |  */ | ||||||
|  | static u64 HexToLong(const u8* src, size_t len) { | ||||||
|  |     u64 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. |  * Converts input array of u8 bytes into their equivalent hex string characters. | ||||||
|  * |  * | ||||||
|  | @ -234,8 +264,21 @@ static void GdbHexToMem(u8* dest, const u8* src, size_t len) { | ||||||
|  */ |  */ | ||||||
| static void IntToGdbHex(u8* dest, u32 v) { | static void IntToGdbHex(u8* dest, u32 v) { | ||||||
|     for (int i = 0; i < 8; i += 2) { |     for (int i = 0; i < 8; i += 2) { | ||||||
|         dest[i + 1] = NibbleToHex(v >> (4 * i)); |         dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i))); | ||||||
|         dest[i] = NibbleToHex(v >> (4 * (i + 1))); |         dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1)))); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Convert a u64 into a gdb-formatted hex string. | ||||||
|  |  * | ||||||
|  |  * @param dest Pointer to buffer to store output hex string characters. | ||||||
|  |  * @param v    Value to convert. | ||||||
|  |  */ | ||||||
|  | static void LongToGdbHex(u8* dest, u64 v) { | ||||||
|  |     for (int i = 0; i < 16; i += 2) { | ||||||
|  |         dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i))); | ||||||
|  |         dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1)))); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -255,6 +298,22 @@ static u32 GdbHexToInt(const u8* src) { | ||||||
|     return output; |     return output; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Convert a gdb-formatted hex string into a u64. | ||||||
|  |  * | ||||||
|  |  * @param src Pointer to hex string. | ||||||
|  |  */ | ||||||
|  | static u64 GdbHexToLong(const u8* src) { | ||||||
|  |     u64 output = 0; | ||||||
|  | 
 | ||||||
|  |     for (int i = 0; i < 16; i += 2) { | ||||||
|  |         output = (output << 4) | HexCharToValue(src[15 - i - 1]); | ||||||
|  |         output = (output << 4) | HexCharToValue(src[15 - i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return output; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// Read a byte from the gdb client.
 | /// Read a byte from the gdb client.
 | ||||||
| static u8 ReadByte() { | static u8 ReadByte() { | ||||||
|     u8 c; |     u8 c; | ||||||
|  | @ -277,7 +336,7 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) { | ||||||
|  * |  * | ||||||
|  * @param type Type of breakpoint list. |  * @param type Type of breakpoint list. | ||||||
|  */ |  */ | ||||||
| static std::map<u32, Breakpoint>& GetBreakpointList(BreakpointType type) { | static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) { | ||||||
|     switch (type) { |     switch (type) { | ||||||
|     case BreakpointType::Execute: |     case BreakpointType::Execute: | ||||||
|         return breakpoints_execute; |         return breakpoints_execute; | ||||||
|  | @ -297,19 +356,19 @@ static std::map<u32, Breakpoint>& GetBreakpointList(BreakpointType type) { | ||||||
|  * @param addr Address of breakpoint. |  * @param addr Address of breakpoint. | ||||||
|  */ |  */ | ||||||
| static void RemoveBreakpoint(BreakpointType type, PAddr addr) { | static void RemoveBreakpoint(BreakpointType type, PAddr addr) { | ||||||
|     std::map<u32, Breakpoint>& p = GetBreakpointList(type); |     std::map<u64, Breakpoint>& p = GetBreakpointList(type); | ||||||
| 
 | 
 | ||||||
|     auto bp = p.find(static_cast<u32>(addr)); |     auto bp = p.find(static_cast<u64>(addr)); | ||||||
|     if (bp != p.end()) { |     if (bp != p.end()) { | ||||||
|         LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n", |         LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n", | ||||||
|                   bp->second.len, bp->second.addr, type); |                   bp->second.len, bp->second.addr, type); | ||||||
|         p.erase(static_cast<u32>(addr)); |         p.erase(static_cast<u64>(addr)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) { | BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) { | ||||||
|     std::map<u32, Breakpoint>& p = GetBreakpointList(type); |     std::map<u64, Breakpoint>& p = GetBreakpointList(type); | ||||||
|     auto next_breakpoint = p.lower_bound(static_cast<u32>(addr)); |     auto next_breakpoint = p.lower_bound(static_cast<u64>(addr)); | ||||||
|     BreakpointAddress breakpoint; |     BreakpointAddress breakpoint; | ||||||
| 
 | 
 | ||||||
|     if (next_breakpoint != p.end()) { |     if (next_breakpoint != p.end()) { | ||||||
|  | @ -328,11 +387,11 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::map<u32, Breakpoint>& p = GetBreakpointList(type); |     std::map<u64, Breakpoint>& p = GetBreakpointList(type); | ||||||
| 
 | 
 | ||||||
|     auto bp = p.find(static_cast<u32>(addr)); |     auto bp = p.find(static_cast<u64>(addr)); | ||||||
|     if (bp != p.end()) { |     if (bp != p.end()) { | ||||||
|         u32 len = bp->second.len; |         u64 len = bp->second.len; | ||||||
| 
 | 
 | ||||||
|         // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
 |         // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
 | ||||||
|         // no matter if it's a 4-byte or 2-byte instruction. When you execute a
 |         // no matter if it's a 4-byte or 2-byte instruction. When you execute a
 | ||||||
|  | @ -419,7 +478,7 @@ static void HandleQuery() { | ||||||
|         SendReply("T0"); |         SendReply("T0"); | ||||||
|     } else if (strncmp(query, "Supported", strlen("Supported")) == 0) { |     } else if (strncmp(query, "Supported", strlen("Supported")) == 0) { | ||||||
|         // PacketSize needs to be large enough for target xml
 |         // PacketSize needs to be large enough for target xml
 | ||||||
|         SendReply("PacketSize=800;qXfer:features:read+"); |         SendReply("PacketSize=2000;qXfer:features:read+"); | ||||||
|     } else if (strncmp(query, "Xfer:features:read:target.xml:", |     } else if (strncmp(query, "Xfer:features:read:target.xml:", | ||||||
|                        strlen("Xfer:features:read:target.xml:")) == 0) { |                        strlen("Xfer:features:read:target.xml:")) == 0) { | ||||||
|         SendReply(target_xml); |         SendReply(target_xml); | ||||||
|  | @ -450,10 +509,7 @@ static void SendSignal(u32 signal) { | ||||||
| 
 | 
 | ||||||
|     latest_signal = signal; |     latest_signal = signal; | ||||||
| 
 | 
 | ||||||
|     std::string buffer = |     std::string buffer = Common::StringFromFormat("T%02x", latest_signal); | ||||||
|         Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15, |  | ||||||
|                                  htonl(static_cast<u_long>(Core::CPU().GetPC())), 13, |  | ||||||
|                                  htonl(static_cast<u_long>(Core::CPU().GetReg(13)))); |  | ||||||
|     LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str()); |     LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str()); | ||||||
|     SendReply(buffer.c_str()); |     SendReply(buffer.c_str()); | ||||||
| } | } | ||||||
|  | @ -539,16 +595,12 @@ static void ReadRegister() { | ||||||
|         id |= HexCharToValue(command_buffer[2]); |         id |= HexCharToValue(command_buffer[2]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (id <= R15_REGISTER) { |     if (id <= SP_REGISTER) { | ||||||
|         IntToGdbHex(reply, static_cast<u32>(Core::CPU().GetReg(static_cast<u64>(id)))); |         LongToGdbHex(reply, Core::CPU().GetReg(static_cast<int>(id))); | ||||||
|  |     } else if (id == PC_REGISTER) { | ||||||
|  |         LongToGdbHex(reply, Core::CPU().GetPC()); | ||||||
|     } else if (id == CPSR_REGISTER) { |     } else if (id == CPSR_REGISTER) { | ||||||
|         IntToGdbHex(reply, Core::CPU().GetCPSR()); |         IntToGdbHex(reply, Core::CPU().GetCPSR()); | ||||||
|     } else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) { |  | ||||||
|         IntToGdbHex(reply, Core::CPU().GetVFPReg( |  | ||||||
|                                id - CPSR_REGISTER - |  | ||||||
|                                1)); // VFP registers should start at 26, so one after CSPR_REGISTER
 |  | ||||||
|     } else if (id == FPSCR_REGISTER) { |  | ||||||
|         UNIMPLEMENTED(); |  | ||||||
|     } else { |     } else { | ||||||
|         return SendReply("E01"); |         return SendReply("E01"); | ||||||
|     } |     } | ||||||
|  | @ -563,21 +615,19 @@ static void ReadRegisters() { | ||||||
| 
 | 
 | ||||||
|     u8* bufptr = buffer; |     u8* bufptr = buffer; | ||||||
| 
 | 
 | ||||||
|     for (int reg = 0; reg <= R15_REGISTER; reg++) { |     for (int reg = 0; reg <= SP_REGISTER; reg++) { | ||||||
|         IntToGdbHex(bufptr + reg * CHAR_BIT, static_cast<u32>(Core::CPU().GetReg(reg))); |         LongToGdbHex(bufptr + reg * 16, Core::CPU().GetReg(reg)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bufptr += (16 * CHAR_BIT); |     bufptr += (32 * 16); | ||||||
|  | 
 | ||||||
|  |     LongToGdbHex(bufptr, Core::CPU().GetPC()); | ||||||
|  | 
 | ||||||
|  |     bufptr += 16; | ||||||
| 
 | 
 | ||||||
|     IntToGdbHex(bufptr, Core::CPU().GetCPSR()); |     IntToGdbHex(bufptr, Core::CPU().GetCPSR()); | ||||||
| 
 | 
 | ||||||
|     bufptr += CHAR_BIT; |     bufptr += 8; | ||||||
| 
 |  | ||||||
|     for (int reg = 0; reg <= 31; reg++) { |  | ||||||
|         IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetVFPReg(reg)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     bufptr += (32 * CHAR_BIT); |  | ||||||
| 
 | 
 | ||||||
|     SendReply(reinterpret_cast<char*>(buffer)); |     SendReply(reinterpret_cast<char*>(buffer)); | ||||||
| } | } | ||||||
|  | @ -593,14 +643,12 @@ static void WriteRegister() { | ||||||
|         id |= HexCharToValue(command_buffer[2]); |         id |= HexCharToValue(command_buffer[2]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (id <= R15_REGISTER) { |     if (id <= SP_REGISTER) { | ||||||
|         Core::CPU().SetReg(id, GdbHexToInt(buffer_ptr)); |         Core::CPU().SetReg(id, GdbHexToLong(buffer_ptr)); | ||||||
|  |     } else if (id == PC_REGISTER) { | ||||||
|  |         Core::CPU().SetPC(GdbHexToLong(buffer_ptr)); | ||||||
|     } else if (id == CPSR_REGISTER) { |     } else if (id == CPSR_REGISTER) { | ||||||
|         Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr)); |         Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr)); | ||||||
|     } else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) { |  | ||||||
|         Core::CPU().SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr)); |  | ||||||
|     } else if (id == FPSCR_REGISTER) { |  | ||||||
|         UNIMPLEMENTED(); |  | ||||||
|     } else { |     } else { | ||||||
|         return SendReply("E01"); |         return SendReply("E01"); | ||||||
|     } |     } | ||||||
|  | @ -615,20 +663,14 @@ 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; reg <= FPSCR_REGISTER; i++, reg++) { |     for (int i = 0, reg = 0; reg <= CPSR_REGISTER; i++, reg++) { | ||||||
|         if (reg <= R15_REGISTER) { |         if (reg <= SP_REGISTER) { | ||||||
|             Core::CPU().SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); |             Core::CPU().SetReg(reg, GdbHexToLong(buffer_ptr + i * 16)); | ||||||
|  |         } else if (reg == PC_REGISTER) { | ||||||
|  |             Core::CPU().SetPC(GdbHexToLong(buffer_ptr + i * 16)); | ||||||
|         } else if (reg == CPSR_REGISTER) { |         } else if (reg == CPSR_REGISTER) { | ||||||
|             Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT)); |             Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr + i * 16)); | ||||||
|         } else if (reg == CPSR_REGISTER - 1) { |         } else { | ||||||
|             // Dummy FPA register, ignore
 |  | ||||||
|         } else if (reg < CPSR_REGISTER) { |  | ||||||
|             // Dummy FPA registers, ignore
 |  | ||||||
|             i += 2; |  | ||||||
|         } else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) { |  | ||||||
|             Core::CPU().SetVFPReg(reg - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); |  | ||||||
|             i++; // Skip padding
 |  | ||||||
|         } else if (reg == FPSCR_REGISTER) { |  | ||||||
|             UNIMPLEMENTED(); |             UNIMPLEMENTED(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -642,13 +684,13 @@ static void ReadMemory() { | ||||||
| 
 | 
 | ||||||
|     auto start_offset = command_buffer + 1; |     auto start_offset = command_buffer + 1; | ||||||
|     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); |     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); | ||||||
|     VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); |     VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); | ||||||
| 
 | 
 | ||||||
|     start_offset = addr_pos + 1; |     start_offset = addr_pos + 1; | ||||||
|     u32 len = |     u64 len = | ||||||
|         HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); |         HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset)); | ||||||
| 
 | 
 | ||||||
|     LOG_DEBUG(Debug_GDBStub, "gdb: addr: %08x len: %08x\n", addr, len); |     LOG_DEBUG(Debug_GDBStub, "gdb: addr: %016llx len: %016llx\n", addr, len); | ||||||
| 
 | 
 | ||||||
|     if (len * 2 > sizeof(reply)) { |     if (len * 2 > sizeof(reply)) { | ||||||
|         SendReply("E01"); |         SendReply("E01"); | ||||||
|  | @ -670,11 +712,11 @@ static void ReadMemory() { | ||||||
| static void WriteMemory() { | static void WriteMemory() { | ||||||
|     auto start_offset = command_buffer + 1; |     auto start_offset = command_buffer + 1; | ||||||
|     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); |     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); | ||||||
|     VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); |     VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); | ||||||
| 
 | 
 | ||||||
|     start_offset = addr_pos + 1; |     start_offset = addr_pos + 1; | ||||||
|     auto len_pos = std::find(start_offset, command_buffer + command_length, ':'); |     auto len_pos = std::find(start_offset, command_buffer + command_length, ':'); | ||||||
|     u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset)); |     u64 len = HexToLong(start_offset, static_cast<u64>(len_pos - start_offset)); | ||||||
| 
 | 
 | ||||||
|     if (!Memory::IsValidVirtualAddress(addr)) { |     if (!Memory::IsValidVirtualAddress(addr)) { | ||||||
|         return SendReply("E00"); |         return SendReply("E00"); | ||||||
|  | @ -727,8 +769,8 @@ static void Continue() { | ||||||
|  * @param addr Address of breakpoint. |  * @param addr Address of breakpoint. | ||||||
|  * @param len Length of breakpoint. |  * @param len Length of breakpoint. | ||||||
|  */ |  */ | ||||||
| static bool CommitBreakpoint(BreakpointType type, PAddr addr, u32 len) { | static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) { | ||||||
|     std::map<u32, Breakpoint>& p = GetBreakpointList(type); |     std::map<u64, Breakpoint>& p = GetBreakpointList(type); | ||||||
| 
 | 
 | ||||||
|     Breakpoint breakpoint; |     Breakpoint breakpoint; | ||||||
|     breakpoint.active = true; |     breakpoint.active = true; | ||||||
|  | @ -767,11 +809,11 @@ static void AddBreakpoint() { | ||||||
| 
 | 
 | ||||||
|     auto start_offset = command_buffer + 3; |     auto start_offset = command_buffer + 3; | ||||||
|     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); |     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); | ||||||
|     PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); |     PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); | ||||||
| 
 | 
 | ||||||
|     start_offset = addr_pos + 1; |     start_offset = addr_pos + 1; | ||||||
|     u32 len = |     u64 len = | ||||||
|         HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); |         HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset)); | ||||||
| 
 | 
 | ||||||
|     if (type == BreakpointType::Access) { |     if (type == BreakpointType::Access) { | ||||||
|         // Access is made up of Read and Write types, so add both breakpoints
 |         // Access is made up of Read and Write types, so add both breakpoints
 | ||||||
|  | @ -816,7 +858,7 @@ static void RemoveBreakpoint() { | ||||||
| 
 | 
 | ||||||
|     auto start_offset = command_buffer + 3; |     auto start_offset = command_buffer + 3; | ||||||
|     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); |     auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); | ||||||
|     PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); |     PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); | ||||||
| 
 | 
 | ||||||
|     if (type == BreakpointType::Access) { |     if (type == BreakpointType::Access) { | ||||||
|         // Access is made up of Read and Write types, so add both breakpoints
 |         // Access is made up of Read and Write types, so add both breakpoints
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rozlette
						Rozlette