Эх сурвалжийг харах

feat(elf): set .bss section zero

greatbridf 2 жил өмнө
parent
commit
5e8359fd6b

+ 26 - 0
include/types/elf.hpp

@@ -109,6 +109,32 @@ struct PACKED elf32_program_header_entry {
     uint32_t align;
 };
 
+struct PACKED elf32_section_header_entry {
+    elf32_off_t sh_name;
+    enum : uint32_t {
+        SHT_NULL = 0x00,
+        SHT_PROGBITS = 0x01,
+        SHT_RELA = 0x04,
+        SHT_DYNAMIC = 0x06,
+        SHT_NOTE = 0x07,
+        SHT_NOBITS = 0x08,
+        SHT_REL = 0x09,
+        SHT_DYNSYM = 0x0b,
+        SHT_INIT_ARRAY = 0x0e,
+        SHT_FINI_ARRAY = 0x0f,
+        SHT_PREINIT_ARRAY = 0x0f,
+    } sh_type;
+    enum : uint32_t {
+        SHF_WRITE = 0x01,
+        SHF_ALLOC = 0x02,
+        SHF_EXECINSTR = 0x04,
+    } sh_flags;
+    elf32_addr_t sh_addr;
+    elf32_off_t sh_offset;
+    uint32_t sh_size;
+    char _[16];
+};
+
 struct elf32_load_data {
     const char* exec;
     const char* const* argv;

+ 32 - 3
src/types/elf.cpp

@@ -49,6 +49,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     }
 
     size_t phents_size = hdr.phentsize * hdr.phnum;
+    size_t shents_size = hdr.shentsize * hdr.shnum;
     auto* phents = (types::elf::elf32_program_header_entry*)k_malloc(phents_size);
     n_read = fs::vfs_read(
         ent_exec->ind,
@@ -64,6 +65,22 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
         return GB_FAILED;
     }
 
+    auto* shents = (types::elf::elf32_section_header_entry*)k_malloc(shents_size);
+    n_read = fs::vfs_read(
+        ent_exec->ind,
+        (char*)shents,
+        shents_size,
+        hdr.shoff, shents_size);
+
+    // broken file or I/O error
+    if (n_read != shents_size) {
+        k_free(phents);
+        k_free(shents);
+
+        d->errcode = EINVAL;
+        return GB_FAILED;
+    }
+
     // copy argv and envp
     vector<string<>> argv, envp;
     for (const char* const* p = d->argv; *p; ++p)
@@ -75,6 +92,8 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     // so we can't just simply return to it on error.
     current_process->mms.clear_user();
 
+    auto* null_ind = fs::vfs_open("/dev/null")->ind;
+
     for (int i = 0; i < hdr.phnum; ++i) {
         if (phents[i].type != types::elf::elf32_program_header_entry::PT_LOAD)
             continue;
@@ -94,7 +113,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
             ret = mmap(
                 (char*)phents[i].vaddr + align_up<12>(phents[i].filesz),
                 align_up<12>(phents[i].memsz) - align_up<12>(phents[i].filesz),
-                fs::vfs_open("/dev/null")->ind,
+                null_ind,
                 phents[i].offset + align_up<12>(phents[i].filesz),
                 1,
                 d->system);
@@ -107,12 +126,19 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
 
     error:
         k_free(phents);
+        k_free(shents);
         kill_current(-1);
     }
 
+    for (int i = 0; i < hdr.shnum; ++i) {
+        if (shents[i].sh_type == elf32_section_header_entry::SHT_NOBITS)
+            memset((char*)shents[i].sh_addr, 0x00, shents[i].sh_size);
+    }
+
     // map stack area
-    auto ret = mmap((void*)types::elf::ELF_STACK_TOP, types::elf::ELF_STACK_SIZE,
-        fs::vfs_open("/dev/null")->ind, 0, 1, 0);
+    auto ret = mmap((void*)types::elf::ELF_STACK_TOP,
+        types::elf::ELF_STACK_SIZE,
+        null_ind, 0, 1, 0);
     assert(ret == GB_OK);
 
     d->eip = (void*)hdr.entry;
@@ -152,5 +178,8 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     // push argc
     _user_push(sp, args.size());
 
+    k_free(shents);
+    k_free(phents);
+
     return GB_OK;
 }

+ 1 - 7
user-space-program/sh.c

@@ -52,11 +52,7 @@ int puts(const char* str)
 void* malloc(size_t n)
 {
     static char mems[1024];
-    static int pos = 0;
-    if (n == 0) {
-        pos = 0;
-        return 0;
-    }
+    static int pos;
     int orig_pos = pos;
     pos += n;
     return mems + orig_pos;
@@ -204,8 +200,6 @@ getcmd(char *buf, int nbuf)
 int
 main(void)
 {
-  void* _ = malloc(0);
-  (void)_;
   static char buf[100];
   
 //   // Assumes three file descriptors open.