Browse Source

UserspaceEmulator: Put the executable name in argv[0] :^)

The emulated program can now find its own name in argv[0]. Very cool!
Andreas Kling 5 years ago
parent
commit
079021a607

+ 9 - 4
DevTools/UserspaceEmulator/Emulator.cpp

@@ -26,6 +26,7 @@
 
 #include "Emulator.h"
 #include "SoftCPU.h"
+#include <AK/LexicalPath.h>
 #include <AK/LogStream.h>
 #include <Kernel/API/Syscall.h>
 #include <stdio.h>
@@ -92,9 +93,10 @@ private:
     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_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);

+ 3 - 1
DevTools/UserspaceEmulator/Emulator.h

@@ -37,7 +37,7 @@ namespace UserspaceEmulator {
 
 class Emulator {
 public:
-    explicit Emulator(NonnullRefPtr<ELF::Loader>);
+    Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader>);
 
     bool load_elf();
     void dump_backtrace();
@@ -63,6 +63,8 @@ private:
 
     bool m_shutdown { false };
     int m_exit_status { 0 };
+
+    String m_executable_path;
 };
 
 }

+ 8 - 0
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));

+ 2 - 0
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]; }
 

+ 1 - 1
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;