mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:27:42 +00:00
UserspaceEmulator: Symbolicate disassembly output :^)
Since we have the ELF executable handy, we can actually symbolicate the disassembly trace output really easily. Very cool! :^)
This commit is contained in:
parent
dc66d70369
commit
0f63d8c9b4
3 changed files with 31 additions and 10 deletions
|
@ -92,8 +92,9 @@ private:
|
|||
u8* m_data { nullptr };
|
||||
};
|
||||
|
||||
Emulator::Emulator()
|
||||
: m_cpu(*this)
|
||||
Emulator::Emulator(NonnullRefPtr<ELF::Loader> elf)
|
||||
: m_elf(move(elf))
|
||||
, m_cpu(*this)
|
||||
{
|
||||
setup_stack();
|
||||
}
|
||||
|
@ -110,9 +111,9 @@ void Emulator::setup_stack()
|
|||
m_cpu.push32(0);
|
||||
}
|
||||
|
||||
bool Emulator::load_elf(const ELF::Loader& elf)
|
||||
bool Emulator::load_elf()
|
||||
{
|
||||
elf.image().for_each_program_header([&](const ELF::Image::ProgramHeader& program_header) {
|
||||
m_elf->image().for_each_program_header([&](const ELF::Image::ProgramHeader& program_header) {
|
||||
if (program_header.type() != PT_LOAD)
|
||||
return;
|
||||
auto region = make<SimpleRegion>(program_header.vaddr().get(), program_header.size_in_memory());
|
||||
|
@ -120,16 +121,34 @@ bool Emulator::load_elf(const ELF::Loader& elf)
|
|||
mmu().add_region(move(region));
|
||||
});
|
||||
|
||||
m_cpu.set_eip(elf.image().entry().get());
|
||||
m_cpu.set_eip(m_elf->image().entry().get());
|
||||
return true;
|
||||
}
|
||||
|
||||
class ELFSymbolProvider final : public X86::SymbolProvider {
|
||||
public:
|
||||
ELFSymbolProvider(ELF::Loader& loader)
|
||||
: m_loader(loader)
|
||||
{
|
||||
}
|
||||
|
||||
virtual String symbolicate(FlatPtr address, u32* offset = nullptr) const
|
||||
{
|
||||
return m_loader.symbolicate(address, offset);
|
||||
}
|
||||
|
||||
private:
|
||||
ELF::Loader& m_loader;
|
||||
};
|
||||
|
||||
int Emulator::exec()
|
||||
{
|
||||
ELFSymbolProvider symbol_provider(*m_elf);
|
||||
|
||||
while (!m_shutdown) {
|
||||
auto base_eip = m_cpu.eip();
|
||||
auto insn = X86::Instruction::from_stream(m_cpu, true, true);
|
||||
out() << (const void*)base_eip << " \033[33;1m" << insn.to_string(base_eip) << "\033[0m";
|
||||
out() << (const void*)base_eip << " \033[33;1m" << insn.to_string(base_eip, &symbol_provider) << "\033[0m";
|
||||
|
||||
(m_cpu.*insn.handler())(insn);
|
||||
m_cpu.dump();
|
||||
|
|
|
@ -37,9 +37,9 @@ namespace UserspaceEmulator {
|
|||
|
||||
class Emulator {
|
||||
public:
|
||||
Emulator();
|
||||
explicit Emulator(NonnullRefPtr<ELF::Loader>);
|
||||
|
||||
bool load_elf(const ELF::Loader&);
|
||||
bool load_elf();
|
||||
|
||||
int exec();
|
||||
u32 virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3);
|
||||
|
@ -47,6 +47,8 @@ public:
|
|||
SoftMMU& mmu() { return m_mmu; }
|
||||
|
||||
private:
|
||||
NonnullRefPtr<ELF::Loader> m_elf;
|
||||
|
||||
SoftMMU m_mmu;
|
||||
SoftCPU m_cpu;
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ int main(int argc, char** argv)
|
|||
|
||||
auto elf = ELF::Loader::create((const u8*)mapped_file.data(), mapped_file.size());
|
||||
|
||||
UserspaceEmulator::Emulator emulator;
|
||||
if (!emulator.load_elf(*elf))
|
||||
UserspaceEmulator::Emulator emulator(move(elf));
|
||||
if (!emulator.load_elf())
|
||||
return 1;
|
||||
|
||||
return emulator.exec();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue