From aec58be40927ec0b2a0e6742396f880d52ce38b5 Mon Sep 17 00:00:00 2001 From: Ada Christine Date: Thu, 22 Feb 2024 20:05:51 +0000 Subject: kjarna runtime --- lib/elf64.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 16 deletions(-) (limited to 'lib/elf64.c') diff --git a/lib/elf64.c b/lib/elf64.c index bae408a..e880179 100644 --- a/lib/elf64.c +++ b/lib/elf64.c @@ -3,15 +3,15 @@ bool elf64_validate(Elf64_Ehdr *ehdr, unsigned type, unsigned machine) { - if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || - ehdr->e_ident[EI_MAG1] != ELFMAG1 || - ehdr->e_ident[EI_MAG2] != ELFMAG2 || - ehdr->e_ident[EI_MAG3] != ELFMAG3 || - ehdr->e_ident[EI_CLASS] != ELFCLASS64 || - ehdr->e_ident[EI_DATA] != ELFDATA2LSB || - ehdr->e_ident[EI_VERSION] != EV_CURRENT || - ehdr->e_machine != machine || - ehdr->e_type != type) + if (ehdr->e_ident[EI_MAG0] != ELFMAG0 + || ehdr->e_ident[EI_MAG1] != ELFMAG1 + || ehdr->e_ident[EI_MAG2] != ELFMAG2 + || ehdr->e_ident[EI_MAG3] != ELFMAG3 + || ehdr->e_ident[EI_CLASS] != ELFCLASS64 + || ehdr->e_ident[EI_DATA] != ELFDATA2LSB + || ehdr->e_ident[EI_VERSION] != EV_CURRENT + || ehdr->e_machine != machine + || ehdr->e_type != type) { return false; } @@ -30,17 +30,52 @@ size_t elf64_size(Elf64_Ehdr *ehdr, Elf64_Phdr *phdrs) continue; } - if (phdrs[i].p_offset + phdrs[i].p_memsz > size) + size = phdrs[i].p_offset + phdrs[i].p_memsz; + if (phdrs[i].p_align > 1) { - size = phdrs[i].p_offset + phdrs[i].p_memsz; - if (phdrs[i].p_align > 1) - { - size = (size + phdrs[i].p_align - 1) & - ~(phdrs[i].p_align - 1); - } + size = (size + phdrs[i].p_align - 1) & ~(phdrs[i].p_align - 1); } } return size; } +static Elf64_Dyn *get_dynent(Elf64_Dyn *dyntab, unsigned long dt_type) +{ + while (dyntab && dyntab->d_tag != DT_NULL) + { + if (dyntab->d_tag == dt_type) + { + return dyntab; + } + + dyntab++; + } + + return nullptr; +} + +void *elf64_dt_ptr(void *base, Elf64_Dyn *dyntab, unsigned long dt_type) +{ + Elf64_Dyn *dynent = get_dynent(dyntab, dt_type); + + if (dynent == nullptr) + { + return nullptr; + } + + return dynent->d_ptr + (char *)base; +} + +uintptr_t elf64_dt_val(Elf64_Dyn *dyntab, unsigned long dt_type) +{ + Elf64_Dyn *dynent = get_dynent(dyntab, dt_type); + + if (dynent == nullptr) + { + return (uintptr_t)-1; + } + + return dynent->d_val; +} + -- cgit v1.3.1-1-g115d