34 for (
int i = 0; i < ehdr->
e_phnum; i++) {
41 LOG2_WARN(
"ELF",
"vaddr 0x%x not found in any PT_LOAD segment", vaddr);
69 switch (dyn[i].d_tag) {
76 "strtab at file offset 0x%x (vaddr 0x%x)",
77 off, dyn[i].d_un.
d_ptr);
92 "symtab at file offset 0x%x (vaddr 0x%x)",
93 off, dyn[i].d_un.
d_ptr);
100 for (
int j = 0; j < ehdr->
e_phnum; j++) {
103 vaddr < p->p_vaddr + p->
p_memsz) {
129 "jmprel at file offset 0x%x (vaddr 0x%x)",
130 off, dyn[i].d_un.
d_ptr);
139 "rela at file offset 0x%x (vaddr 0x%x)", off,
165 const char* sh_names = (
const char*)
data + sh_strtab->
sh_offset;
169 const char* sec_name = sh_names + s->
sh_name;
182 if (
strncmp(sec_name,
".strtab", 7) == 0)
187 if (
strncmp(sec_name,
".got.plt", 8) == 0) {
189 "found .got.plt at 0x%x, size %d",
192 }
else if (
strncmp(sec_name,
".got", 4) == 0) {
193 LOG2_INFO(
"ELF",
"found .got at 0x%x, size %d",
241 uintptr_t offset_aligned = start - aligned_start;
245 LOG2_INFO(
"VOXMO",
"gotplt found at 0x%x (0x%x), size %d",
246 base + aligned_start, offset_aligned, total_aligned);
264 (void)temporary_base;
293 auto temporary_addr =
base + aligned_vaddr;
295 if (kernel_page !=
page) {
307 LOG2_INFO(
"ELF",
"vaddr 0x%x, type %d %x %x, flags %b",
309 base + aligned_vaddr, mmap_flags);
313 t->paddr = phys_alloc;
314 t->vaddr = temporary_addr;
315 t->alligned = aligned_vaddr;
320 memset((
void*)(temporary_addr + vaddr_offset), 0, p->
p_memsz);
322 memcopy((
void*)(temporary_addr + vaddr_offset),
338 for (
size_t j = 0; j < external_syms->
size; j++) {
340 for (
size_t k = 0; k < item->size; k++) {
343 return item->data[k].value;
354 return (
uint64_t*)(fallback_base + r_offset);
356 for (
int i = 0; i < table_count; i++) {
357 if (!
table[i].mapped)
362 if (r_offset >= seg_vaddr_start && r_offset < seg_vaddr_end) {
364 return (
uint64_t*)(kernel_segment_base +
365 (r_offset - seg_vaddr_start));
369 return (
uint64_t*)(fallback_base + r_offset);
378 for (
uint64_t i = 0; i < rela_count; i++) {
382 const char*
name = (
const char*)(strtab + symbol->
st_name);
385 (
const char*)strtab);
390 rel[i].r_offset,
table, table_count, kernel_base);
402 LOG2_WARN(
"ELF",
"TLS relocation not implemented");
407 (
uintptr_t)((intptr_t)user_base + rel[i].r_addend);
416 if (!resolver_kptr) {
418 "IRELATIVE: resolver not found for "
435 "IRELATIVE r_offset=0x%x resolver_addr=0x%x",
436 rel[i].r_offset, *target);
441 *target = (
uintptr_t)((intptr_t)user_base +
478 memcopy((
void*)target, (
void*)src,
491 external_syms,
name);
495 "GLOB_DAT: symbol %s not found",
512 external_syms,
name);
516 "JUMP_SLOT: symbol %s not found",
525 *target = user_base + symbol->
st_value;
527 "unhandled reloc type %d at 0x%x -> 0x%x",
528 type, rel[i].r_offset, *target);
541 serial2_printf(
"relocating with kernel_base = 0x%x, user_base = 0x%x\n",
542 kernel_base, user_base);
544 if (
map->rel &&
map->relasz &&
map->relaent) {
549 map->strtab,
map->symbols, gnu_hash,
550 external_syms,
table, table_count);
553 if (
map->jmprel &&
map->pltrelsz &&
map->relaent) {
554 LOG2_INFO(
"VOXMO",
"jmprel found at 0x%x",
map->jmprel);
558 map->strtab,
map->symbols, gnu_hash,
559 external_syms,
table, table_count);
565 for (
unsigned char c = (
unsigned char)*s; c !=
'\0';
566 c = (
unsigned char)*++s)
567 h = (
h << 5) +
h + c;
575 return (word & mask) == mask;
592 const char* sym_name = strtab + symtab[i].
st_name;
645 max_end =
max(max_end, seg_end);
648 LOG2_INFO(
"ELF",
"module load size: %d bytes (%d kb)", max_end,
656 if (!
map->symtab || !
map->strtab)
661 const char* strtab_data = (
const char*)(
data +
map->strtab->sh_offset);
668 for (
uint64_t i = 0; i < sym_count; i++) {
669 if (skip_empty_val && symtab[i].st_value == 0)
681 if (!
map->init_aray) {
691 for (
size_t i = 0; i <
count; i++) {
693 LOG2_DEBUG(
"ELF",
"load .init array %x", arr[i]);
710 size_t count =
map->init_aray->sh_size /
sizeof(
void*);
712 for (
size_t i = 0; i <
count; i++) {
714 map->init_aray->sh_addr + i *
sizeof(
void*),
table,
721 if (fn_ptr && *fn_ptr) {
732 if (!
map->symtab || !
map->strtab)
735 const char* strtab_data =
742 LOG2_INFO(
"ELF",
"sym found %s by gnu hash 0x%x",
748 size_t sym_count =
map->symtab->sh_size /
sizeof(
Elf64_Sym);
749 for (
size_t i = 0; i < sym_count; i++) {
750 const char* sname = strtab_data + symtab[i].
st_name;
753 LOG2_INFO(
"ELF",
"sym found %s 0x%x", sname,
madt_record_table_entry_t table[]
uintptr_t elf_find_base_addr(uint8_t *data)
void elf_section_map_all(uint8_t *data, elf_section_map *map)
size_t elf_load(volatile uintptr_t *page, uint8_t *data, uintptr_t temporary_base, uintptr_t base, struct elf_load_mmap_table *table)
static uint64_t vaddr_to_file_offset(Elf64_Ehdr *ehdr, Elf64_Phdr *phdr, uint64_t vaddr)
uintptr_t elf_find_symbol(const char *name, GnuHashHeader *gnuhash, uintptr_t base, elf_section_map *map, uint8_t *data)
void elf_gnu_hash_parse(GnuHashHeader *gnu_hash, Elf64_Shdr *gnu_hash_sym, uint8_t *data)
void elf_call_init_array(elf_section_map *map, uintptr_t base)
void elf_dyn_map_all(Elf64_Dyn *dyn, uint8_t *data, elf_dynamic_map *map)
uintptr_t elf_get_entry(uint8_t *data, uintptr_t base)
static uintptr_t elf_resolve_external_symbol(symbols_ptr_vector_t *external_syms, const char *name)
Elf64_Sym * elf_gnu_lookup(const char *name, GnuHashHeader *gh, Elf64_Sym *symtab, const char *strtab)
Elf64_Dyn * elf_get_phdr_dynamic(uint8_t *data)
void elf_call_init_array_with_table(elf_section_map *map, struct elf_load_mmap_table *table, int table_count)
void elf_relocate_dyn(elf_dynamic_map *map, uintptr_t kernel_base, uintptr_t user_base, GnuHashHeader *gnu_hash, symbols_ptr_vector_t *external_syms, struct elf_load_mmap_table *table, int table_count)
void elf_mmap_got(volatile uintptr_t *page, elf_section_map *map, uintptr_t base)
uint64_t elf_pflags_to_page_flags(uint64_t p_flags)
static uint64_t * elf_roffset_to_kernel_ptr(uintptr_t r_offset, struct elf_load_mmap_table *table, int table_count, uintptr_t fallback_base)
void elf_get_symbol(const char *sym_name, uintptr_t base, elf_section_map *map, uint8_t *data, symbols_ptr_vector_t *syms, boolean_t skip_empty_val)
static void elf_relocate_rel(Elf64_Rela *rel, uintptr_t kernel_base, uintptr_t user_base, uint64_t rela_count, uint8_t *strtab, Elf64_Sym *symbols, GnuHashHeader *gnu_hash, symbols_ptr_vector_t *external_syms, struct elf_load_mmap_table *table, int table_count)
void module_loader(uintptr_t addr, uintptr_t stack)
static int elf_gnu_maybe_present(GnuHashHeader *gh, uint32_t hash)
static uint32_t elf_gnu_hash(const char *s)
uintptr_t elf_count_load_size(uint8_t *data)
#define ELF_PTR(type, base, off)
elf_section_map uintptr_t base
uintptr_t rip_before_run_elf
boolean_t elf_has_running
void serial2_printf(const char *fmt,...)
void * kalloc(size_t size)
uint64_t max(uint64_t a, uint64_t b)
#define ALIGN_DOWN(x, align)
#define PTR_ADD(ptr, off)
#define ASSUME_ALIGNED(ptr, align)
#define ALIGN_UP(x, align)
page_t paging_get_highest_page_map(void)
void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags)
void * phys_base_alloc(uint64_t block)
#define LOG2_WARN(mod, fmt,...)
#define LOG2_DEBUG(mod, fmt,...)
#define LOG2_INFO(mod, fmt,...)
int strncmp(const char *s1, const char *s2, size_t n)
size_t strlen(const char *s)
void memset(void *ptr, int value, size_t num)
void memcopy(void *dest, void *src, size_t size)
union Elf64_Dyn::@220367214354326365050217232242036207207371044375 d_un
struct vector_symbols_item items
struct vector_symbols_ptr symbols_ptr_vector_t
#define vector_push_back(v, val)
uintptr_t vma_lookup_free_vaddr(struct virtual_memory_page *page, mem_vma_region region, size_t size)
struct virtual_memory_page * get_kernel_vmm_page()