summaryrefslogtreecommitdiff
path: root/kernel/mboot
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-17 13:44:55 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-17 14:10:42 -0400
commitf8529d09bf1555c2dda61f5841b7ad4f42ce9715 (patch)
tree16e0cdede45741e945e663f72697665074b2b077 /kernel/mboot
parentfmt (diff)
downloadcomus-f8529d09bf1555c2dda61f5841b7ad4f42ce9715.tar.gz
comus-f8529d09bf1555c2dda61f5841b7ad4f42ce9715.tar.bz2
comus-f8529d09bf1555c2dda61f5841b7ad4f42ce9715.zip
elf sym loading
Diffstat (limited to 'kernel/mboot')
-rw-r--r--kernel/mboot/elf.c77
-rw-r--r--kernel/mboot/mboot.c7
-rw-r--r--kernel/mboot/mmap.c2
3 files changed, 82 insertions, 4 deletions
diff --git a/kernel/mboot/elf.c b/kernel/mboot/elf.c
new file mode 100644
index 0000000..88b61a7
--- /dev/null
+++ b/kernel/mboot/elf.c
@@ -0,0 +1,77 @@
+#include "lib/kio.h"
+#include <lib.h>
+#include <elf.h>
+#include <comus/mboot.h>
+
+#include "mboot.h"
+
+#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
+
+struct multiboot_tag_elf_sections {
+ uint32_t type;
+ uint32_t size;
+ uint32_t num;
+ uint32_t entsize;
+ uint32_t shndx;
+ Elf64_Shdr sections[];
+};
+
+static struct multiboot_tag_elf_sections *elf = NULL;
+static Elf64_Shdr *symtab = NULL;
+static Elf64_Shdr *symstrtab = NULL;
+
+static Elf64_Shdr *mboot_get_elf_sec(uint32_t sh_type)
+{
+ for (uint32_t i = 0; i < elf->num; i++) {
+ Elf64_Shdr *ent = &elf->sections[i];
+ if (ent->sh_type == sh_type)
+ return ent;
+ }
+
+ return NULL;
+}
+
+static int mboot_load_elf(void)
+{
+ void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_ELF_SECTIONS);
+ if (tag == NULL)
+ return 1;
+
+ // found elf sections
+ elf = (struct multiboot_tag_elf_sections *)tag;
+
+ // load symtab
+ if ((symtab = mboot_get_elf_sec(SHT_SYMTAB)) == NULL)
+ return 1;
+
+ // load strsymtab
+ if ((symstrtab = mboot_get_elf_sec(symtab->sh_link)) == NULL)
+ return 1;
+
+ return 0;
+}
+
+const char *mboot_get_elf_sym(uint64_t addr)
+{
+ if (symstrtab == NULL)
+ if (mboot_load_elf())
+ return NULL;
+
+ // walk symbol table
+ Elf64_Sym *syms = (Elf64_Sym *)symtab->sh_addr;
+ Elf64_Sym *best = NULL;
+ for (uint32_t i = 0; i < symtab->sh_size / symtab->sh_entsize; i++) {
+ Elf64_Sym *sym = &syms[i];
+ if (sym->st_value < addr)
+ continue;
+ if (best == NULL || (best->st_value < sym->st_value))
+ best = sym;
+ }
+
+ if (best != NULL) {
+ char *buf = (char *)symstrtab->sh_addr;
+ return &buf[best->st_name];
+ }
+
+ return "???";
+}
diff --git a/kernel/mboot/mboot.c b/kernel/mboot/mboot.c
index e10f33c..949337d 100644
--- a/kernel/mboot/mboot.c
+++ b/kernel/mboot/mboot.c
@@ -3,7 +3,7 @@
#include "mboot.h"
-static volatile void *mboot;
+static volatile void *mboot = NULL;
void mboot_init(long magic, volatile void *ptr)
{
@@ -14,9 +14,12 @@ void mboot_init(long magic, volatile void *ptr)
void *locate_mboot_table(uint32_t type)
{
+ if (mboot == NULL)
+ return NULL;
+
struct multiboot *info = (struct multiboot *)mboot;
- const char *mboot_end = ((char *)info) + info->total_size;
+ const char *mboot_end = ((char *)info) + info->total_size;
char *tag_ptr = info->tags;
while (tag_ptr < mboot_end) {
diff --git a/kernel/mboot/mmap.c b/kernel/mboot/mmap.c
index 8959c49..e0963ca 100644
--- a/kernel/mboot/mmap.c
+++ b/kernel/mboot/mmap.c
@@ -30,11 +30,9 @@ int mboot_get_mmap(struct memory_map *res)
int idx = 0;
uintptr_t i = (uintptr_t)mmap->entries;
- char buf[20];
for (; i < (uintptr_t)mmap->entries + mmap->size;
i += mmap->entry_size, idx++) {
struct multiboot_mmap_entry *seg = (struct multiboot_mmap_entry *)i;
- const char *type = NULL;
res->entries[idx].addr = seg->addr;
res->entries[idx].len = seg->len;
res->entries[idx].type = seg->type;