diff options
| author | Freya Murphy <freya@freyacat.org> | 2025-04-17 13:44:55 -0400 | 
|---|---|---|
| committer | Freya Murphy <freya@freyacat.org> | 2025-04-17 14:10:42 -0400 | 
| commit | f8529d09bf1555c2dda61f5841b7ad4f42ce9715 (patch) | |
| tree | 16e0cdede45741e945e663f72697665074b2b077 /kernel/mboot | |
| parent | fmt (diff) | |
| download | comus-f8529d09bf1555c2dda61f5841b7ad4f42ce9715.tar.gz comus-f8529d09bf1555c2dda61f5841b7ad4f42ce9715.tar.bz2 comus-f8529d09bf1555c2dda61f5841b7ad4f42ce9715.zip | |
elf sym loading
Diffstat (limited to '')
| -rw-r--r-- | kernel/mboot/elf.c | 77 | ||||
| -rw-r--r-- | kernel/mboot/mboot.c | 7 | ||||
| -rw-r--r-- | kernel/mboot/mmap.c | 2 | 
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; | 
