Selaa lähdekoodia

feat(elf): pass program arguments to elf loader

greatbridf 2 vuotta sitten
vanhempi
commit
9ddd370740
4 muutettua tiedostoa jossa 37 lisäystä ja 9 poistoa
  1. 2 1
      include/types/elf.hpp
  2. 2 1
      src/kernel/process.cpp
  3. 1 4
      src/kernel/syscall.cpp
  4. 32 3
      src/types/elf.cpp

+ 2 - 1
include/types/elf.hpp

@@ -109,6 +109,7 @@ struct PACKED elf32_program_header_entry {
     uint32_t align;
 };
 
-int elf32_load(const char* exec, interrupt_stack* intrpt_stack, bool system);
+// TODO: environment variables
+int elf32_load(const char* exec, const char** argv, interrupt_stack* intrpt_stack, bool system);
 
 } // namespace types::elf

+ 2 - 1
src/kernel/process.cpp

@@ -135,7 +135,8 @@ void NORETURN _kernel_init(void)
 
     interrupt_stack intrpt_stack {};
     intrpt_stack.eflags = 0x200; // STI
-    types::elf::elf32_load("/mnt/INIT.ELF", &intrpt_stack, 0);
+    const char* argv[] = { "/mnt/INIT.ELF", nullptr };
+    types::elf::elf32_load("/mnt/INIT.ELF", argv, &intrpt_stack, 0);
 
     asm_cli();
     current_process->attr.system = 0;

+ 1 - 4
src/kernel/syscall.cpp

@@ -67,14 +67,11 @@ void _syscall_crash(interrupt_stack*)
 void _syscall_exec(interrupt_stack* data)
 {
     const char* exec = reinterpret_cast<const char*>(data->s_regs.edi);
-
-    // TODO: load argv
     const char** argv = reinterpret_cast<const char**>(data->s_regs.esi);
-    (void)argv;
 
     unmap_user_space_memory(current_process->mms);
 
-    types::elf::elf32_load(exec, data, current_process->attr.system);
+    types::elf::elf32_load(exec, argv, data, current_process->attr.system);
 }
 
 // @param exit_code

+ 32 - 3
src/types/elf.cpp

@@ -1,7 +1,16 @@
+#include <kernel/stdio.h>
 #include <kernel/syscall.hpp>
 #include <types/elf.hpp>
+#include <types/stdint.h>
 
-int types::elf::elf32_load(const char* exec, interrupt_stack* intrpt_stack, bool system)
+template <typename T>
+constexpr void _user_push(uint32_t& sp, T d)
+{
+    sp -= sizeof(T);
+    *(T*)sp = d;
+}
+
+int types::elf::elf32_load(const char* exec, const char** argv, interrupt_stack* intrpt_stack, bool system)
 {
     auto* ent_exec = fs::vfs_open(exec);
     if (!ent_exec) {
@@ -60,7 +69,27 @@ int types::elf::elf32_load(const char* exec, interrupt_stack* intrpt_stack, bool
 
     intrpt_stack->v_eip = (void*)hdr.entry;
     memset((void*)&intrpt_stack->s_regs, 0x00, sizeof(regs_32));
-    intrpt_stack->s_regs.esp = types::elf::ELF_STACK_BOTTOM;
-    intrpt_stack->s_regs.ebp = types::elf::ELF_STACK_BOTTOM;
+
+    auto* sp = &intrpt_stack->s_regs.esp;
+    *sp = types::elf::ELF_STACK_BOTTOM;
+
+    types::vector<const char*> arr;
+    for (const char** ptr = argv; *ptr != nullptr; ++ptr) {
+        auto len = strlen(*ptr);
+        *sp -= (len + 1);
+        *sp = ((*sp >> 4) << 4);
+        memcpy((char*)*sp, *ptr, len + 1);
+        arr.push_back((const char*)*sp);
+    }
+
+    *sp -= sizeof(const char*) * arr.size();
+    *sp = ((*sp >> 4) << 4);
+    memcpy((char*)*sp, arr.data(), sizeof(const char*) * arr.size());
+
+    _user_push(*sp, 0);
+    _user_push(*sp, 0);
+    _user_push(*sp, *sp + 8);
+    _user_push(*sp, arr.size());
+
     return GB_OK;
 }