summaryrefslogtreecommitdiff
path: root/lib/elf64.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/elf64.c')
-rw-r--r--lib/elf64.c67
1 files changed, 51 insertions, 16 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;
+}
+