diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/elf64.c | 67 | ||||
| -rw-r--r-- | lib/string.c | 10 |
2 files changed, 60 insertions, 17 deletions
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; +} + diff --git a/lib/string.c b/lib/string.c index 315fa1e..2da2070 100644 --- a/lib/string.c +++ b/lib/string.c @@ -1,6 +1,14 @@ -#include <libc/string.h> +#include <libc/string.h> #include <stdbool.h> +int strcmp(const char *s1, const char *s2) +{ + size_t s1len = strlen(s1); + size_t s2len = strlen(s2); + + return memcmp(s1, s2, s1len < s2len ? s1len : s2len); +} + size_t strlen(const char *s) { size_t l = 0; |
