mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-05 10:42:51 +00:00
UserspaceEmulator: Put the executable name in argv[0] :^)
The emulated program can now find its own name in argv[0]. Very cool!
This commit is contained in:
parent
ddf7b817df
commit
079021a607
Notes:
sideshowbarker
2024-07-19 04:53:22 +09:00
Author: https://github.com/awesomekling
Commit: 079021a607
5 changed files with 23 additions and 6 deletions
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "Emulator.h"
|
#include "Emulator.h"
|
||||||
#include "SoftCPU.h"
|
#include "SoftCPU.h"
|
||||||
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/LogStream.h>
|
#include <AK/LogStream.h>
|
||||||
#include <Kernel/API/Syscall.h>
|
#include <Kernel/API/Syscall.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -92,9 +93,10 @@ private:
|
||||||
u8* m_data { nullptr };
|
u8* m_data { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
Emulator::Emulator(NonnullRefPtr<ELF::Loader> elf)
|
Emulator::Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader> elf)
|
||||||
: m_elf(move(elf))
|
: m_elf(move(elf))
|
||||||
, m_cpu(*this)
|
, m_cpu(*this)
|
||||||
|
, m_executable_path(executable_path)
|
||||||
{
|
{
|
||||||
setup_stack();
|
setup_stack();
|
||||||
}
|
}
|
||||||
|
@ -105,16 +107,19 @@ void Emulator::setup_stack()
|
||||||
m_mmu.add_region(move(stack_region));
|
m_mmu.add_region(move(stack_region));
|
||||||
m_cpu.set_esp(stack_location + stack_size);
|
m_cpu.set_esp(stack_location + stack_size);
|
||||||
|
|
||||||
|
m_cpu.push_string(LexicalPath(m_executable_path).basename());
|
||||||
|
u32 argv0 = m_cpu.esp();
|
||||||
|
|
||||||
m_cpu.push32(0); // char** envp = { nullptr }
|
m_cpu.push32(0); // char** envp = { nullptr }
|
||||||
u32 envp = m_cpu.esp();
|
u32 envp = m_cpu.esp();
|
||||||
|
|
||||||
m_cpu.push32(0); // char** argv = { nullptr }
|
m_cpu.push32(0); // char** argv = { argv0, nullptr }
|
||||||
|
m_cpu.push32(argv0);
|
||||||
u32 argv = m_cpu.esp();
|
u32 argv = m_cpu.esp();
|
||||||
|
|
||||||
m_cpu.push32(0); // (alignment)
|
|
||||||
m_cpu.push32(0); // (alignment)
|
m_cpu.push32(0); // (alignment)
|
||||||
|
|
||||||
u32 argc = 0;
|
u32 argc = 1;
|
||||||
m_cpu.push32(envp);
|
m_cpu.push32(envp);
|
||||||
m_cpu.push32(argv);
|
m_cpu.push32(argv);
|
||||||
m_cpu.push32(argc);
|
m_cpu.push32(argc);
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace UserspaceEmulator {
|
||||||
|
|
||||||
class Emulator {
|
class Emulator {
|
||||||
public:
|
public:
|
||||||
explicit Emulator(NonnullRefPtr<ELF::Loader>);
|
Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader>);
|
||||||
|
|
||||||
bool load_elf();
|
bool load_elf();
|
||||||
void dump_backtrace();
|
void dump_backtrace();
|
||||||
|
@ -63,6 +63,8 @@ private:
|
||||||
|
|
||||||
bool m_shutdown { false };
|
bool m_shutdown { false };
|
||||||
int m_exit_status { 0 };
|
int m_exit_status { 0 };
|
||||||
|
|
||||||
|
String m_executable_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,14 @@ void SoftCPU::write_memory32(X86::LogicalAddress address, u32 value)
|
||||||
m_emulator.mmu().write32(address, value);
|
m_emulator.mmu().write32(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftCPU::push_string(const StringView& string)
|
||||||
|
{
|
||||||
|
size_t space_to_allocate = round_up_to_power_of_two(string.length() + 1, 16);
|
||||||
|
set_esp(esp() - space_to_allocate);
|
||||||
|
m_emulator.mmu().copy_to_vm(esp(), string.characters_without_null_termination(), string.length());
|
||||||
|
m_emulator.mmu().write8({ 0x20, esp() + string.length() }, '\0');
|
||||||
|
}
|
||||||
|
|
||||||
void SoftCPU::push32(u32 value)
|
void SoftCPU::push32(u32 value)
|
||||||
{
|
{
|
||||||
set_esp(esp() - sizeof(value));
|
set_esp(esp() - sizeof(value));
|
||||||
|
|
|
@ -75,6 +75,8 @@ public:
|
||||||
void push32(u32);
|
void push32(u32);
|
||||||
u32 pop32();
|
u32 pop32();
|
||||||
|
|
||||||
|
void push_string(const StringView&);
|
||||||
|
|
||||||
u16 segment(X86::SegmentRegister seg) const { return m_segment[(int)seg]; }
|
u16 segment(X86::SegmentRegister seg) const { return m_segment[(int)seg]; }
|
||||||
u16& segment(X86::SegmentRegister seg) { return m_segment[(int)seg]; }
|
u16& segment(X86::SegmentRegister seg) { return m_segment[(int)seg]; }
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ 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(move(elf));
|
UserspaceEmulator::Emulator emulator(executable_path, move(elf));
|
||||||
if (!emulator.load_elf())
|
if (!emulator.load_elf())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue