summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/elf64.c67
-rw-r--r--lib/string.c10
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;