mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:17: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 };
|
u8* m_data { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
Emulator::Emulator()
|
Emulator::Emulator(NonnullRefPtr<ELF::Loader> elf)
|
||||||
: m_cpu(*this)
|
: m_elf(move(elf))
|
||||||
|
, m_cpu(*this)
|
||||||
{
|
{
|
||||||
setup_stack();
|
setup_stack();
|
||||||
}
|
}
|
||||||
|
@ -110,9 +111,9 @@ void Emulator::setup_stack()
|
||||||
m_cpu.push32(0);
|
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)
|
if (program_header.type() != PT_LOAD)
|
||||||
return;
|
return;
|
||||||
auto region = make<SimpleRegion>(program_header.vaddr().get(), program_header.size_in_memory());
|
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));
|
mmu().add_region(move(region));
|
||||||
});
|
});
|
||||||
|
|
||||||
m_cpu.set_eip(elf.image().entry().get());
|
m_cpu.set_eip(m_elf->image().entry().get());
|
||||||
return true;
|
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()
|
int Emulator::exec()
|
||||||
{
|
{
|
||||||
|
ELFSymbolProvider symbol_provider(*m_elf);
|
||||||
|
|
||||||
while (!m_shutdown) {
|
while (!m_shutdown) {
|
||||||
auto base_eip = m_cpu.eip();
|
auto base_eip = m_cpu.eip();
|
||||||
auto insn = X86::Instruction::from_stream(m_cpu, true, true);
|
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.*insn.handler())(insn);
|
||||||
m_cpu.dump();
|
m_cpu.dump();
|
||||||
|
|
|
@ -37,9 +37,9 @@ namespace UserspaceEmulator {
|
||||||
|
|
||||||
class Emulator {
|
class Emulator {
|
||||||
public:
|
public:
|
||||||
Emulator();
|
explicit Emulator(NonnullRefPtr<ELF::Loader>);
|
||||||
|
|
||||||
bool load_elf(const ELF::Loader&);
|
bool load_elf();
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
u32 virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3);
|
u32 virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3);
|
||||||
|
@ -47,6 +47,8 @@ public:
|
||||||
SoftMMU& mmu() { return m_mmu; }
|
SoftMMU& mmu() { return m_mmu; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
NonnullRefPtr<ELF::Loader> m_elf;
|
||||||
|
|
||||||
SoftMMU m_mmu;
|
SoftMMU m_mmu;
|
||||||
SoftCPU m_cpu;
|
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());
|
auto elf = ELF::Loader::create((const u8*)mapped_file.data(), mapped_file.size());
|
||||||
|
|
||||||
UserspaceEmulator::Emulator emulator;
|
UserspaceEmulator::Emulator emulator(move(elf));
|
||||||
if (!emulator.load_elf(*elf))
|
if (!emulator.load_elf())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return emulator.exec();
|
return emulator.exec();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue