1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:47:44 +00:00

UserspaceEmulator+LibX86: Add support for 64-bit memory reads and writes (#3584)

This is useful for reading and writing doubles for #3329.
It is also useful for emulating 64-bit binaries.

MemoryOrRegisterReference assumes that 64-bit values are always
memory references since that's enough for fpu support. If we
ever want to emulate 64-bit binaries, that part will need minor
updating.
This commit is contained in:
Nico Weber 2020-09-23 14:45:43 -04:00 committed by GitHub
parent 1fa5a526e8
commit f1c0f661f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 156 additions and 0 deletions

View file

@ -315,6 +315,7 @@ public:
virtual u8 read8() = 0;
virtual u16 read16() = 0;
virtual u32 read32() = 0;
virtual u64 read64() = 0;
};
class SimpleInstructionStream final : public InstructionStream {
@ -347,6 +348,12 @@ public:
return ((u32)msw << 16) | (u32)lsw;
}
virtual u64 read64() override
{
u32 lsw = read32();
u32 msw = read32();
return ((u64)msw << 32) | (u64)lsw;
}
size_t offset() const { return m_offset; }
private:
@ -385,6 +392,8 @@ public:
void write16(CPU&, const Instruction&, T);
template<typename CPU, typename T>
void write32(CPU&, const Instruction&, T);
template<typename CPU, typename T>
void write64(CPU&, const Instruction&, T);
template<typename T, typename CPU>
T read8(CPU&, const Instruction&);
@ -392,6 +401,8 @@ public:
T read16(CPU&, const Instruction&);
template<typename T, typename CPU>
T read32(CPU&, const Instruction&);
template<typename T, typename CPU>
T read64(CPU&, const Instruction&);
template<typename CPU>
LogicalAddress resolve(const CPU&, const Instruction&);
@ -752,6 +763,14 @@ ALWAYS_INLINE void MemoryOrRegisterReference::write32(CPU& cpu, const Instructio
cpu.write_memory32(address, value);
}
template<typename CPU, typename T>
ALWAYS_INLINE void MemoryOrRegisterReference::write64(CPU& cpu, const Instruction& insn, T value)
{
ASSERT(!is_register());
auto address = resolve(cpu, insn);
cpu.write_memory64(address, value);
}
template<typename T, typename CPU>
ALWAYS_INLINE T MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& insn)
{
@ -782,6 +801,14 @@ ALWAYS_INLINE T MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& i
return cpu.read_memory32(address);
}
template<typename T, typename CPU>
ALWAYS_INLINE T MemoryOrRegisterReference::read64(CPU& cpu, const Instruction& insn)
{
ASSERT(!is_register());
auto address = resolve(cpu, insn);
return cpu.read_memory64(address);
}
template<typename InstructionStreamType>
ALWAYS_INLINE Instruction Instruction::from_stream(InstructionStreamType& stream, bool o32, bool a32)
{