diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index e9502db49f..3180dc5ee5 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -26,6 +26,7 @@ #include "Emulator.h" #include "SoftCPU.h" +#include #include #include #include @@ -92,9 +93,10 @@ private: u8* m_data { nullptr }; }; -Emulator::Emulator(NonnullRefPtr elf) +Emulator::Emulator(const String& executable_path, NonnullRefPtr elf) : m_elf(move(elf)) , m_cpu(*this) + , m_executable_path(executable_path) { setup_stack(); } @@ -105,16 +107,19 @@ void Emulator::setup_stack() m_mmu.add_region(move(stack_region)); 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 } 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(); - m_cpu.push32(0); // (alignment) m_cpu.push32(0); // (alignment) - u32 argc = 0; + u32 argc = 1; m_cpu.push32(envp); m_cpu.push32(argv); m_cpu.push32(argc); diff --git a/DevTools/UserspaceEmulator/Emulator.h b/DevTools/UserspaceEmulator/Emulator.h index c8c9c6ba1c..cfc461164d 100644 --- a/DevTools/UserspaceEmulator/Emulator.h +++ b/DevTools/UserspaceEmulator/Emulator.h @@ -37,7 +37,7 @@ namespace UserspaceEmulator { class Emulator { public: - explicit Emulator(NonnullRefPtr); + Emulator(const String& executable_path, NonnullRefPtr); bool load_elf(); void dump_backtrace(); @@ -63,6 +63,8 @@ private: bool m_shutdown { false }; int m_exit_status { 0 }; + + String m_executable_path; }; } diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index aaacd9e95d..b56fb4f2d1 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -139,6 +139,14 @@ void SoftCPU::write_memory32(X86::LogicalAddress address, u32 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) { set_esp(esp() - sizeof(value)); diff --git a/DevTools/UserspaceEmulator/SoftCPU.h b/DevTools/UserspaceEmulator/SoftCPU.h index a812395f1b..6d8670e74f 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.h +++ b/DevTools/UserspaceEmulator/SoftCPU.h @@ -75,6 +75,8 @@ public: void push32(u32); u32 pop32(); + void push_string(const StringView&); + u16 segment(X86::SegmentRegister seg) const { return m_segment[(int)seg]; } u16& segment(X86::SegmentRegister seg) { return m_segment[(int)seg]; } diff --git a/DevTools/UserspaceEmulator/main.cpp b/DevTools/UserspaceEmulator/main.cpp index fdeb061b40..cb272c6d0b 100644 --- a/DevTools/UserspaceEmulator/main.cpp +++ b/DevTools/UserspaceEmulator/main.cpp @@ -47,7 +47,7 @@ int main(int argc, char** argv) 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()) return 1;