:: commit 95c6a2dd633747908ec345a47cfe34639b067719

mintsuki <mintsuki@protonmail.com> — 2023-07-08 21:44

parents: 507688261f

limine/elf: Optimise not to scan .bss for requests

diff --git a/common/lib/elf.c b/common/lib/elf.c
index 23132fc1..3b1328cc 100644
--- a/common/lib/elf.c
+++ b/common/lib/elf.c
@@ -396,7 +396,7 @@ static void elf64_get_ranges(uint8_t *elf, uint64_t slide, struct elf_range **_r
     *_ranges = ranges;
 }
 
-bool elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *_slide, uint32_t alloc_type, bool kaslr, struct elf_range **ranges, uint64_t *ranges_count, uint64_t *physical_base, uint64_t *virtual_base, uint64_t *_image_size, bool *is_reloc) {
+bool elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *_slide, uint32_t alloc_type, bool kaslr, struct elf_range **ranges, uint64_t *ranges_count, uint64_t *physical_base, uint64_t *virtual_base, uint64_t *_image_size, uint64_t *_image_size_before_bss, bool *is_reloc) {
     struct elf64_hdr *hdr = (void *)elf;
 
     if (strncmp((char *)hdr->ident, "\177ELF", 4)) {
@@ -518,6 +518,8 @@ again:
         }
     }
 
+    uint64_t bss_size;
+
     for (uint16_t i = 0; i < hdr->ph_num; i++) {
         struct elf64_phdr *phdr = (void *)elf + (hdr->phoff + i * hdr->phdr_size);
 
@@ -548,6 +550,10 @@ again:
 
         memcpy((void *)(uintptr_t)load_addr, elf + (phdr->p_offset), phdr->p_filesz);
 
+        if (i == hdr->ph_num - 1) {
+            bss_size = phdr->p_memsz - phdr->p_filesz;
+        }
+
         if (!elf64_apply_relocations(elf, hdr, (void *)(uintptr_t)load_addr, phdr->p_vaddr, phdr->p_memsz, slide)) {
             panic(true, "elf: Failed to apply relocations");
         }
@@ -558,6 +564,10 @@ again:
 #endif
     }
 
+    if (_image_size_before_bss != NULL) {
+        *_image_size_before_bss = image_size - bss_size;
+    }
+
     *virtual_base += slide;
     *entry_point = entry + slide;
     if (_slide) {
diff --git a/common/lib/elf.h b/common/lib/elf.h
index e7df68c0..8f1e0f13 100644
--- a/common/lib/elf.h
+++ b/common/lib/elf.h
@@ -30,7 +30,7 @@ struct elf_section_hdr_info elf64_section_hdr_info(uint8_t *elf);
 struct elf_section_hdr_info elf32_section_hdr_info(uint8_t *elf);
 
 bool elf64_load_section(uint8_t *elf, void *buffer, const char *name, size_t limit, uint64_t slide);
-bool elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *_slide, uint32_t alloc_type, bool kaslr, struct elf_range **ranges, uint64_t *ranges_count, uint64_t *physical_base, uint64_t *virtual_base, uint64_t *image_size, bool *is_reloc);
+bool elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *_slide, uint32_t alloc_type, bool kaslr, struct elf_range **ranges, uint64_t *ranges_count, uint64_t *physical_base, uint64_t *virtual_base, uint64_t *image_size, uint64_t *image_size_before_bss, bool *is_reloc);
 
 bool elf32_load_elsewhere(uint8_t *elf, uint64_t *entry_point,
                           struct elsewhere_range **ranges,
diff --git a/common/protos/limine.c b/common/protos/limine.c
index e451a5a3..92a9e789 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -353,13 +353,14 @@ noreturn void limine_load(char *config, char *cmdline) {
     struct elf_range *ranges;
     uint64_t ranges_count;
 
-    uint64_t image_size;
+    uint64_t image_size_before_bss;
     bool is_reloc;
 
     if (!elf64_load(kernel, &entry_point, &slide,
                    MEMMAP_KERNEL_AND_MODULES, kaslr,
                    &ranges, &ranges_count,
-                   &physical_base, &virtual_base, &image_size,
+                   &physical_base, &virtual_base, NULL,
+                   &image_size_before_bss,
                    &is_reloc)) {
         panic(true, "limine: ELF64 load failure");
     }
@@ -380,7 +381,7 @@ noreturn void limine_load(char *config, char *cmdline) {
         requests = ext_mem_alloc(MAX_REQUESTS * sizeof(void *));
         requests_count = 0;
         uint64_t common_magic[2] = { LIMINE_COMMON_MAGIC };
-        for (size_t i = 0; i < ALIGN_DOWN(image_size, 8); i += 8) {
+        for (size_t i = 0; i < ALIGN_DOWN(image_size_before_bss, 8); i += 8) {
             uint64_t *p = (void *)(uintptr_t)physical_base + i;
 
             if (p[0] != common_magic[0]) {
tab: 248 wrap: offon