Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
elf.c
Go to the documentation of this file.
1#include "hal/cpu/paging.h"
2#include "libk/math.h"
3#include "libk/serial.h"
4#include "libk/symbols.h"
7#include "memory/vm_manager.h"
9#include <str.h>
10#include <type.h>
11#include <vector.h>
12
16
18 Elf64_Ehdr* ehdr =
21 PTR_ADD(data, ehdr->e_phoff), alignof(Elf64_Phdr));
22
23 for (uint64_t i = 0; i < ehdr->e_phnum; i++) {
24 Elf64_Phdr* p =
25 (Elf64_Phdr*)((uint64_t)phdr + i * ehdr->e_phentsize);
26 if (p->p_type == PT_LOAD)
27 return p->p_vaddr - p->p_offset;
28 }
29 return 0;
30}
31
33 uint64_t vaddr) {
34 for (int i = 0; i < ehdr->e_phnum; i++) {
35 Elf64_Phdr* p = &phdr[i];
36 if (p->p_type == PT_LOAD && vaddr >= p->p_vaddr &&
37 vaddr < p->p_vaddr + p->p_filesz) {
38 return p->p_offset + (vaddr - p->p_vaddr);
39 }
40 }
41 LOG2_WARN("ELF", "vaddr 0x%x not found in any PT_LOAD segment", vaddr);
42 return vaddr;
43}
44
46 Elf64_Ehdr* ehdr =
49 PTR_ADD(data, ehdr->e_phoff), alignof(Elf64_Phdr));
50
51 for (uint64_t i = 0; i < ehdr->e_phnum; i++) {
52 Elf64_Phdr* p =
53 (Elf64_Phdr*)((uint64_t)phdr + i * ehdr->e_phentsize);
54 if (p->p_type == PT_DYNAMIC)
55 return (Elf64_Dyn*)((uint64_t)data + p->p_offset);
56 }
57 return NULL;
58}
59
61 Elf64_Ehdr* ehdr =
64 PTR_ADD(data, ehdr->e_phoff), alignof(Elf64_Phdr));
65
66 vector_init(&map->needed);
67
68 for (int i = 0; dyn[i].d_tag != DT_NULL; i++) {
69 switch (dyn[i].d_tag) {
70
71 case DT_STRTAB: {
72 uint64_t off =
73 vaddr_to_file_offset(ehdr, phdr, dyn[i].d_un.d_ptr);
74 map->strtab = data + off;
75 LOG2_INFO("ELF",
76 "strtab at file offset 0x%x (vaddr 0x%x)",
77 off, dyn[i].d_un.d_ptr);
78 break;
79 }
80
81 case DT_NEEDED: {
82 uint64_t needed = dyn[i].d_un.d_val;
83 vector_push_back(&map->needed, needed);
84 break;
85 }
86
87 case DT_SYMTAB: {
88 uint64_t off =
89 vaddr_to_file_offset(ehdr, phdr, dyn[i].d_un.d_ptr);
90 map->symbols = (Elf64_Sym*)(void*)(data + off);
91 LOG2_INFO("ELF",
92 "symtab at file offset 0x%x (vaddr 0x%x)",
93 off, dyn[i].d_un.d_ptr);
94 break;
95 }
96
97 case DT_HASH: {
98 uint64_t vaddr = dyn[i].d_un.d_ptr;
99 uint64_t offset = 0;
100 for (int j = 0; j < ehdr->e_phnum; j++) {
101 Elf64_Phdr* p = &phdr[j];
102 if (vaddr >= p->p_vaddr &&
103 vaddr < p->p_vaddr + p->p_memsz) {
104 offset =
105 (vaddr - p->p_vaddr) + p->p_offset;
106 break;
107 }
108 }
110 map->symcount = hash[1];
111 break;
112 }
113
114 case DT_PLTRELSZ:
115 map->pltrelsz = dyn[i].d_un.d_val;
116 LOG2_INFO("ELF", "pltrel size : %x", map->pltrelsz);
117 break;
118
119 case DT_PLTGOT:
120 LOG2_INFO("ELF", "pltgot : 0x%x", dyn[i].d_un.d_ptr);
121 map->pltgot = (uint64_t)dyn[i].d_un.d_ptr;
122 break;
123
124 case DT_JMPREL: {
125 uint64_t off =
126 vaddr_to_file_offset(ehdr, phdr, dyn[i].d_un.d_ptr);
127 map->jmprel = ELF_PTR(Elf64_Rela, data, off);
128 LOG2_INFO("ELF",
129 "jmprel at file offset 0x%x (vaddr 0x%x)",
130 off, dyn[i].d_un.d_ptr);
131 break;
132 }
133
134 case DT_RELA: {
135 uint64_t off =
136 vaddr_to_file_offset(ehdr, phdr, dyn[i].d_un.d_ptr);
137 map->rel = ELF_PTR(Elf64_Rela, data, off);
138 LOG2_INFO("ELF",
139 "rela at file offset 0x%x (vaddr 0x%x)", off,
140 dyn[i].d_un.d_ptr);
141 break;
142 }
143
144 case DT_RELASZ:
145 map->relasz = dyn[i].d_un.d_val;
146 LOG2_INFO("ELF", "relasz : %x", map->relasz);
147 break;
148
149 case DT_RELAENT:
150 map->relaent = dyn[i].d_un.d_val;
151 LOG2_INFO("ELF", "relaent : %x", map->relaent);
152 break;
153
154 default:
155 break;
156 }
157 }
158}
159
161 Elf64_Ehdr* ehdr =
163 Elf64_Shdr* shdr = (Elf64_Shdr*)((uint64_t)data + ehdr->e_shoff);
164 Elf64_Shdr* sh_strtab = &shdr[ehdr->e_shstrndx];
165 const char* sh_names = (const char*)data + sh_strtab->sh_offset;
166
167 for (uint64_t i = 0; i < ehdr->e_shnum; i++) {
168 Elf64_Shdr* s = &shdr[i];
169 const char* sec_name = sh_names + s->sh_name;
170
171 switch (s->sh_type) {
172
173 case SHT_SYMTAB:
174 map->symtab = s;
175 break;
176
177 case SHT_GNU_HASH:
178 map->gnuhash = s;
179 break;
180
181 case SHT_STRTAB:
182 if (strncmp(sec_name, ".strtab", 7) == 0)
183 map->strtab = s;
184 break;
185
186 case SHT_PROGBITS:
187 if (strncmp(sec_name, ".got.plt", 8) == 0) {
188 LOG2_INFO("ELF",
189 "found .got.plt at 0x%x, size %d",
190 s->sh_addr, s->sh_size);
191 map->gotplt = s;
192 } else if (strncmp(sec_name, ".got", 4) == 0) {
193 LOG2_INFO("ELF", "found .got at 0x%x, size %d",
194 s->sh_addr, s->sh_size);
195 map->got = s;
196 }
197 break;
198
199 case SHT_RELA:
200 break;
201
202 case SHT_INIT_ARRAY:
203 map->init_aray = s;
204 break;
205
206 case SHT_FINI_ARRAY:
207 map->fini_aray = s;
208 break;
209
210 default:
211 break;
212 }
213 }
214}
215
217 uint64_t flags = PAGE_USER; // selalu user-accessible
218
219 if (p_flags & PF_R)
221 if (p_flags & PF_W)
223 if (p_flags & PF_X)
225 else
226 flags |= PAGE_NO_EXECUTE; // NX jika bukan executable segment
227
228 return flags;
229}
230
232 uintptr_t base) {
233 if (!map->gotplt)
234 return;
235
236 uint64_t start = map->got ? map->got->sh_addr : map->gotplt->sh_addr;
237 uint64_t end = map->gotplt->sh_addr + map->gotplt->sh_size;
238 uint64_t total = end - start;
239
240 uint64_t aligned_start = ALIGN_DOWN(start, PAGE_SIZE);
241 uintptr_t offset_aligned = start - aligned_start;
242 uint64_t total_aligned =
243 ALIGN_UP(total + offset_aligned, PAGE_SIZE) / PAGE_SIZE;
244
245 LOG2_INFO("VOXMO", "gotplt found at 0x%x (0x%x), size %d",
246 base + aligned_start, offset_aligned, total_aligned);
247
249 uint64_t got_flags =
251 vxMultipleMmap(page, base + aligned_start, phys_addr, total_aligned,
252 got_flags);
253}
254
256 Elf64_Ehdr* ehdr =
258 return base + ehdr->e_entry;
259}
260
261size_t elf_load(volatile uintptr_t* page, uint8_t* data,
262 uintptr_t temporary_base, uintptr_t base,
263 struct elf_load_mmap_table* table) {
264 (void)temporary_base;
265
266 Elf64_Ehdr* ehdr =
268 LOG2_INFO("ELF", "version : %d, ph num : %d", ehdr->e_version,
269 ehdr->e_phnum);
270 LOG2_INFO("ELF", "entry : 0x%x", ehdr->e_entry);
271
272 Elf64_Phdr* phdr = ELF_PTR(Elf64_Phdr, data, ehdr->e_phoff);
273
274 size_t max_end = 0;
275
276 for (uint64_t i = 0; i < ehdr->e_phnum; i++) {
277 Elf64_Phdr* p =
278 ELF_PTR(Elf64_Phdr, phdr, i * ehdr->e_phentsize);
279
280 uintptr_t aligned_vaddr = ALIGN_DOWN(p->p_vaddr, BLOCK_SIZE);
281 uintptr_t vaddr_offset = p->p_vaddr - aligned_vaddr;
282 size_t sz =
283 (vaddr_offset + p->p_memsz + BLOCK_SIZE - 1) / BLOCK_SIZE;
284
285 max_end = max(max_end, p->p_vaddr + sz * BLOCK_SIZE);
286
287 if (p->p_type != PT_LOAD)
288 continue;
289
290 uintptr_t phys_alloc = (uintptr_t)phys_base_alloc(sz);
291 auto kernel_page = paging_get_highest_page_map();
292
293 auto temporary_addr = base + aligned_vaddr;
294 auto mmap_flags = elf_pflags_to_page_flags(p->p_flags);
295 if (kernel_page != page) {
296 temporary_addr = vma_lookup_free_vaddr(
298
299 vxMultipleMmap(kernel_page, temporary_addr, phys_alloc,
300 sz, 0b11);
301 }
302 vxMultipleMmap(page, base + aligned_vaddr, phys_alloc, sz,
303 mmap_flags);
304 // vxMultipleMmap(page, base + aligned_vaddr, phys_alloc, sz,
305 // mmap_flags);
306
307 LOG2_INFO("ELF", "vaddr 0x%x, type %d %x %x, flags %b",
308 p->p_vaddr, p->p_type, temporary_addr,
309 base + aligned_vaddr, mmap_flags);
310
311 if (table) {
312 auto t = &table[i];
313 t->paddr = phys_alloc;
314 t->vaddr = temporary_addr;
315 t->alligned = aligned_vaddr;
316 t->size = sz;
317 t->mapped = true;
318 }
319
320 memset((void*)(temporary_addr + vaddr_offset), 0, p->p_memsz);
321 if (p->p_filesz > 0)
322 memcopy((void*)(temporary_addr + vaddr_offset),
323 (void*)((uint8_t*)data + p->p_offset),
324 p->p_filesz);
325 }
326
327 LOG2_INFO("ELF", "module loaded");
328 return max_end;
329}
330
331static uintptr_t
333 const char* name) {
334 if (!external_syms)
335 return 0;
336
337 size_t name_len = strlen(name);
338 for (size_t j = 0; j < external_syms->size; j++) {
339 vector(symbols_item)* item = &external_syms->data[j]->items;
340 for (size_t k = 0; k < item->size; k++) {
341 if (strlen(item->data[k].name) == name_len &&
342 strncmp(item->data[k].name, name, name_len) == 0)
343 return item->data[k].value;
344 }
345 }
346 return 0;
347}
348
351 int table_count,
352 uintptr_t fallback_base) {
353 if (!table)
354 return (uint64_t*)(fallback_base + r_offset);
355
356 for (int i = 0; i < table_count; i++) {
357 if (!table[i].mapped)
358 continue;
359 uintptr_t seg_vaddr_start = table[i].alligned;
360 uintptr_t seg_vaddr_end =
361 seg_vaddr_start + table[i].size * BLOCK_SIZE;
362 if (r_offset >= seg_vaddr_start && r_offset < seg_vaddr_end) {
363 uintptr_t kernel_segment_base = table[i].vaddr;
364 return (uint64_t*)(kernel_segment_base +
365 (r_offset - seg_vaddr_start));
366 }
367 }
368
369 return (uint64_t*)(fallback_base + r_offset);
370}
371
372static void
373elf_relocate_rel(Elf64_Rela* rel, uintptr_t kernel_base, uintptr_t user_base,
374 uint64_t rela_count, uint8_t* strtab, Elf64_Sym* symbols,
375 GnuHashHeader* gnu_hash, symbols_ptr_vector_t* external_syms,
376 struct elf_load_mmap_table* table, int table_count) {
377
378 for (uint64_t i = 0; i < rela_count; i++) {
379 uint64_t sym_idx = ELF64_R_SYM(rel[i].r_info);
380 uint64_t type = ELF64_R_TYPE(rel[i].r_info);
381 Elf64_Sym* symbol = &symbols[sym_idx];
382 const char* name = (const char*)(strtab + symbol->st_name);
383
384 Elf64_Sym* lookup = elf_gnu_lookup(name, gnu_hash, symbols,
385 (const char*)strtab);
386 if (lookup)
387 symbol = lookup;
388
390 rel[i].r_offset, table, table_count, kernel_base);
391
392 switch (type) {
393
396 case R_X86_64_TPOFF64:
397 case R_X86_64_TLSGD:
398 case R_X86_64_TLSLD:
401 case R_X86_64_TPOFF32:
402 LOG2_WARN("ELF", "TLS relocation not implemented");
403 break;
404
406 *target =
407 (uintptr_t)((intptr_t)user_base + rel[i].r_addend);
408 break;
409
410 case R_X86_64_IRELATIVE: {
411 uintptr_t resolver_kptr =
413 (uintptr_t)rel[i].r_addend, table, table_count,
414 kernel_base);
415
416 if (!resolver_kptr) {
417 LOG2_WARN("ELF",
418 "IRELATIVE: resolver not found for "
419 "r_addend=0x%x",
420 rel[i].r_addend);
421 break;
422 }
423
424 uintptr_t (*resolver)(void) =
425 (uintptr_t(*)(void))resolver_kptr;
426 uintptr_t result = resolver();
427
428 if (user_base) {
429 result += user_base;
430 }
431
432 *target = result;
433
434 LOG2_DEBUG("ELF",
435 "IRELATIVE r_offset=0x%x resolver_addr=0x%x",
436 rel[i].r_offset, *target);
437 break;
438 }
439
440 case R_X86_64_64:
441 *target = (uintptr_t)((intptr_t)user_base +
442 (intptr_t)symbol->st_value +
443 rel[i].r_addend);
444 break;
445
446 case R_X86_64_32: {
447 uint32_t value = (uint32_t)((intptr_t)user_base +
448 (intptr_t)symbol->st_value +
449 rel[i].r_addend);
450 *(uint32_t*)target = value;
451 break;
452 }
453
454 case R_X86_64_32S: {
455 int32_t value = (int32_t)((intptr_t)user_base +
456 (intptr_t)symbol->st_value +
457 rel[i].r_addend);
458 *(int32_t*)target = value;
459 break;
460 }
461
462 case R_X86_64_PC32: {
463 uintptr_t symbol_addr =
464 (uintptr_t)((intptr_t)user_base +
465 (intptr_t)symbol->st_value +
466 rel[i].r_addend);
467 *(uint32_t*)target =
468 (uint32_t)(symbol_addr -
469 (user_base + rel[i].r_offset));
470 break;
471 }
472
473 case R_X86_64_COPY:
474 if (symbol->st_size) {
476 symbol->st_value, table, table_count,
477 kernel_base);
478 memcopy((void*)target, (void*)src,
479 symbol->st_size);
480 }
481 break;
482
483 case R_X86_64_GLOB_DAT: {
484 // GLOB_DAT: addend selalu 0 per ABI, ignore r_addend
485 uintptr_t value = 0;
486 if (symbol->st_value) {
487 value = (uintptr_t)((intptr_t)user_base +
488 (intptr_t)symbol->st_value);
489 } else {
491 external_syms, name);
492 if (!value)
493 LOG2_WARN(
494 "ELF",
495 "GLOB_DAT: symbol %s not found",
496 name);
497 }
498 if (value)
499 *target = value;
500 break;
501 }
502
503 case R_X86_64_JUMP_SLOT: {
504 // JUMP_SLOT: lazy binding — set ke alamat PLT stub jika
505 // ada, atau langsung resolve
506 uintptr_t value = 0;
507 if (symbol->st_value) {
508 value = (uintptr_t)((intptr_t)user_base +
509 (intptr_t)symbol->st_value);
510 } else {
512 external_syms, name);
513 if (!value)
514 LOG2_WARN(
515 "ELF",
516 "JUMP_SLOT: symbol %s not found",
517 name);
518 }
519 if (value)
520 *target = value;
521 break;
522 }
523
524 default:
525 *target = user_base + symbol->st_value;
526 LOG2_DEBUG("ELF",
527 "unhandled reloc type %d at 0x%x -> 0x%x",
528 type, rel[i].r_offset, *target);
529 break;
530 }
531 }
532}
533
535 uintptr_t user_base, GnuHashHeader* gnu_hash,
536 symbols_ptr_vector_t* external_syms,
537 struct elf_load_mmap_table* table, int table_count) {
538 if (!map)
539 return;
540
541 serial2_printf("relocating with kernel_base = 0x%x, user_base = 0x%x\n",
542 kernel_base, user_base);
543
544 if (map->rel && map->relasz && map->relaent) {
545 LOG2_INFO("VOXMO", "rela found at 0x%x", map->rel);
546 uint64_t count = map->relasz / map->relaent;
547 LOG2_INFO("VOXMO", "rela count %d", count);
548 elf_relocate_rel(map->rel, kernel_base, user_base, count,
549 map->strtab, map->symbols, gnu_hash,
550 external_syms, table, table_count);
551 }
552
553 if (map->jmprel && map->pltrelsz && map->relaent) {
554 LOG2_INFO("VOXMO", "jmprel found at 0x%x", map->jmprel);
555 uint64_t count = map->pltrelsz / map->relaent;
556 LOG2_INFO("VOXMO", "rela count %d", count);
557 elf_relocate_rel(map->jmprel, kernel_base, user_base, count,
558 map->strtab, map->symbols, gnu_hash,
559 external_syms, table, table_count);
560 }
561}
562
563static uint32_t elf_gnu_hash(const char* s) {
564 uint32_t h = 5381;
565 for (unsigned char c = (unsigned char)*s; c != '\0';
566 c = (unsigned char)*++s)
567 h = (h << 5) + h + c;
568 return h;
569}
570
572 uint64_t word = gh->bloom[(hash / 64) % gh->bloom_size];
573 uint64_t mask =
574 (1ULL << (hash % 64)) | (1ULL << ((hash >> gh->bloom_shift) % 64));
575 return (word & mask) == mask;
576}
577
579 Elf64_Sym* symtab, const char* strtab) {
581
582 if (!elf_gnu_maybe_present(gh, hash))
583 return NULL;
584
585 uint32_t idx = gh->buckets[hash % gh->nbuckets];
586 if (idx < gh->symoffset || idx == 0)
587 return NULL;
588
589 size_t name_len = strlen(name);
590 for (uint32_t i = idx;; i++) {
591 uint32_t h2 = gh->chains[i - gh->symoffset];
592 const char* sym_name = strtab + symtab[i].st_name;
593
594 if ((h2 | 1) == (hash | 1) && strlen(sym_name) == name_len &&
595 strncmp(sym_name, name, name_len) == 0)
596 return &symtab[i];
597
598 if (h2 & 1)
599 break;
600 }
601 return NULL;
602}
603
604void elf_gnu_hash_parse(GnuHashHeader* gnu_hash, Elf64_Shdr* gnu_hash_sym,
605 uint8_t* data) {
606 memset(gnu_hash, 0, sizeof(GnuHashHeader));
607 if (!gnu_hash_sym)
608 return;
609
610 uint8_t* ptr = (uint8_t*)(data + gnu_hash_sym->sh_offset);
611
612 memcopy(&gnu_hash->nbuckets, ptr + 0, sizeof(uint32_t));
613 memcopy(&gnu_hash->symoffset, ptr + 4, sizeof(uint32_t));
614 memcopy(&gnu_hash->bloom_size, ptr + 8, sizeof(uint32_t));
615 memcopy(&gnu_hash->bloom_shift, ptr + 12, sizeof(uint32_t));
616 ptr += 16;
617
618 gnu_hash->bloom = (uintptr_t*)ASSUME_ALIGNED(ptr, alignof(uintptr_t));
619
620 ptr += gnu_hash->bloom_size * sizeof(uintptr_t);
621
622 gnu_hash->buckets = (uint32_t*)ASSUME_ALIGNED(ptr, alignof(uint32_t));
623
624 ptr += gnu_hash->nbuckets * sizeof(uint32_t);
625
626 gnu_hash->chains = (uint32_t*)ASSUME_ALIGNED(ptr, alignof(uint32_t));
627}
628
630 Elf64_Ehdr* ehdr =
632 Elf64_Phdr* phdr = ELF_PTR(Elf64_Phdr, data, ehdr->e_phoff);
633
634 LOG2_INFO("ELF", "version : %d, ph num : %d", ehdr->e_version,
635 ehdr->e_phnum);
636 size_t max_end = 0;
637
638 for (uint64_t i = 0; i < ehdr->e_phnum; i++) {
639 Elf64_Phdr* p =
640 ELF_PTR(Elf64_Phdr, phdr, i * ehdr->e_phentsize);
641 if (p->p_type != PT_LOAD)
642 continue;
643 uintptr_t seg_end =
645 max_end = max(max_end, seg_end);
646 }
647
648 LOG2_INFO("ELF", "module load size: %d bytes (%d kb)", max_end,
649 max_end / 1024);
650 return max_end;
651}
652
653void elf_get_symbol(const char* sym_name, uintptr_t base, elf_section_map* map,
655 boolean_t skip_empty_val) {
656 if (!map->symtab || !map->strtab)
657 return;
658
659 Elf64_Sym* symtab =
660 (Elf64_Sym*)((uint64_t)data + map->symtab->sh_offset);
661 const char* strtab_data = (const char*)(data + map->strtab->sh_offset);
662 uint64_t sym_count = map->symtab->sh_size / sizeof(Elf64_Sym);
663
664 symbols* s = (symbols*)kalloc(sizeof(symbols));
665 vector_init(&s->items);
666 s->name = sym_name;
667
668 for (uint64_t i = 0; i < sym_count; i++) {
669 if (skip_empty_val && symtab[i].st_value == 0)
670 continue;
671
672 symbols_item item;
673 item.name = strtab_data + symtab[i].st_name;
674 item.value = base + symtab[i].st_value;
675 vector_push_back(&s->items, item);
676 }
677 vector_push_back(syms, s);
678}
679
681 if (!map->init_aray) {
682 return;
683 }
684
685 Elf64_Shdr* init_aray = map->init_aray;
686
687 ctor_t* arr = (ctor_t*)(base + init_aray->sh_addr);
688 size_t count = init_aray->sh_size / sizeof(void*);
689
690 LOG2_INFO("ELF", "lib init array count %d", count);
691 for (size_t i = 0; i < count; i++) {
692 if (arr[i]) {
693 LOG2_DEBUG("ELF", "load .init array %x", arr[i]);
694 arr[i]();
695 }
696 }
697}
698
701 int table_count) {
702
703 (void)map;
704 (void)table;
705 (void)table_count;
706
707 if (!map->init_aray)
708 return;
709
710 size_t count = map->init_aray->sh_size / sizeof(void*);
711 serial2_printf("init array count %d\n", count);
712 for (size_t i = 0; i < count; i++) {
714 map->init_aray->sh_addr + i * sizeof(void*), table,
715 table_count, 0);
716
717 serial2_printf("sh_addr 0x%x\n", map->init_aray->sh_addr);
718 serial2_printf("fn_ptr: 0x%x\n", fn_ptr);
719 serial2_printf("fn_ptr contain 0x%x\n", *fn_ptr);
720
721 if (fn_ptr && *fn_ptr) {
722 auto fn = (void*)elf_roffset_to_kernel_ptr(
723 (uintptr_t)*fn_ptr, table, table_count, 0);
724 serial2_printf("mapped fn at 0x%x\n", fn);
725 ((void(*)())fn)();
726 }
727 }
728}
729
732 if (!map->symtab || !map->strtab)
733 return 0;
734
735 const char* strtab_data =
736 (const char*)((uint64_t)data + map->strtab->sh_offset);
737 Elf64_Sym* symtab =
738 (Elf64_Sym*)((uint64_t)data + map->symtab->sh_offset);
739
740 Elf64_Sym* sym = elf_gnu_lookup(name, gnuhash, symtab, strtab_data);
741 if (sym && sym->st_value) {
742 LOG2_INFO("ELF", "sym found %s by gnu hash 0x%x",
743 strtab_data + sym->st_name, base + sym->st_value);
744 return base + sym->st_value;
745 }
746
747 size_t name_len = strlen(name);
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;
751 if (strlen(sname) == name_len &&
752 strncmp(sname, name, name_len) == 0) {
753 LOG2_INFO("ELF", "sym found %s 0x%x", sname,
754 symtab[i].st_value);
755 return base + symtab[i].st_value;
756 }
757 }
758
759 LOG2_WARN("ELF", "sym %s not found", name);
760 return 0;
761}
madt_record_table_entry_t table[]
Definition acpi.h:3
struct SDT h
Definition acpi.h:0
int count
Definition cache.h:2
kstring name
Definition dentry.h:5
uint32_t hash
Definition dentry.h:3
volatile uint64_t addr
Definition e1000.hpp:0
uintptr_t elf_find_base_addr(uint8_t *data)
Definition elf.c:17
void elf_section_map_all(uint8_t *data, elf_section_map *map)
Definition elf.c:160
size_t elf_load(volatile uintptr_t *page, uint8_t *data, uintptr_t temporary_base, uintptr_t base, struct elf_load_mmap_table *table)
Definition elf.c:261
static uint64_t vaddr_to_file_offset(Elf64_Ehdr *ehdr, Elf64_Phdr *phdr, uint64_t vaddr)
Definition elf.c:32
uintptr_t elf_find_symbol(const char *name, GnuHashHeader *gnuhash, uintptr_t base, elf_section_map *map, uint8_t *data)
Definition elf.c:730
void elf_gnu_hash_parse(GnuHashHeader *gnu_hash, Elf64_Shdr *gnu_hash_sym, uint8_t *data)
Definition elf.c:604
void elf_call_init_array(elf_section_map *map, uintptr_t base)
Definition elf.c:680
void elf_dyn_map_all(Elf64_Dyn *dyn, uint8_t *data, elf_dynamic_map *map)
Definition elf.c:60
uintptr_t elf_get_entry(uint8_t *data, uintptr_t base)
Definition elf.c:255
static uintptr_t elf_resolve_external_symbol(symbols_ptr_vector_t *external_syms, const char *name)
Definition elf.c:332
Elf64_Sym * elf_gnu_lookup(const char *name, GnuHashHeader *gh, Elf64_Sym *symtab, const char *strtab)
Definition elf.c:578
Elf64_Dyn * elf_get_phdr_dynamic(uint8_t *data)
Definition elf.c:45
void elf_call_init_array_with_table(elf_section_map *map, struct elf_load_mmap_table *table, int table_count)
Definition elf.c:699
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)
Definition elf.c:534
void elf_mmap_got(volatile uintptr_t *page, elf_section_map *map, uintptr_t base)
Definition elf.c:231
uint64_t elf_pflags_to_page_flags(uint64_t p_flags)
Definition elf.c:216
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)
Definition elf.c:349
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)
Definition elf.c:653
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)
Definition elf.c:373
void module_loader(uintptr_t addr, uintptr_t stack)
static int elf_gnu_maybe_present(GnuHashHeader *gh, uint32_t hash)
Definition elf.c:571
static uint32_t elf_gnu_hash(const char *s)
Definition elf.c:563
uintptr_t elf_count_load_size(uint8_t *data)
Definition elf.c:629
void(* ctor_t)(void)
Definition elf.h:337
#define PF_X
Definition elf.h:258
#define PF_W
Definition elf.h:259
elf_section_map * map
Definition elf.h:295
@ SHT_RELA
Definition elf.h:162
@ SHT_PROGBITS
Definition elf.h:159
@ SHT_STRTAB
Definition elf.h:161
@ SHT_FINI_ARRAY
Definition elf.h:171
@ SHT_INIT_ARRAY
Definition elf.h:170
@ SHT_GNU_HASH
Definition elf.h:178
@ SHT_SYMTAB
Definition elf.h:160
#define ELF64_R_TYPE(i)
Definition elf.h:344
@ PT_DYNAMIC
Definition elf.h:86
@ PT_LOAD
Definition elf.h:85
#define ELF_PTR(type, base, off)
Definition elf.h:346
#define ELF64_R_SYM(i)
Definition elf.h:343
@ DT_PLTRELSZ
Definition elf.h:117
@ DT_RELASZ
Definition elf.h:123
@ DT_STRTAB
Definition elf.h:120
@ DT_RELAENT
Definition elf.h:124
@ DT_RELA
Definition elf.h:122
@ DT_NEEDED
Definition elf.h:116
@ DT_NULL
Definition elf.h:115
@ DT_JMPREL
Definition elf.h:138
@ DT_PLTGOT
Definition elf.h:118
@ DT_HASH
Definition elf.h:119
@ DT_SYMTAB
Definition elf.h:121
@ R_X86_64_RELATIVE
Definition elf.h:221
@ R_X86_64_GLOB_DAT
Definition elf.h:219
@ R_X86_64_COPY
Definition elf.h:218
@ R_X86_64_GOTTPOFF
Definition elf.h:236
@ R_X86_64_32
Definition elf.h:223
@ R_X86_64_TPOFF32
Definition elf.h:237
@ R_X86_64_IRELATIVE
Definition elf.h:253
@ R_X86_64_TLSGD
Definition elf.h:233
@ R_X86_64_64
Definition elf.h:214
@ R_X86_64_DTPOFF64
Definition elf.h:231
@ R_X86_64_32S
Definition elf.h:224
@ R_X86_64_TPOFF64
Definition elf.h:232
@ R_X86_64_TLSLD
Definition elf.h:234
@ R_X86_64_JUMP_SLOT
Definition elf.h:220
@ R_X86_64_PC32
Definition elf.h:215
@ R_X86_64_DTPOFF32
Definition elf.h:235
@ R_X86_64_DTPMOD64
Definition elf.h:230
#define PF_R
Definition elf.h:260
elf_section_map uintptr_t base
Definition elf.h:296
struct fs_data data
Definition filesystem.h:1
uint64_t stack
Definition thread.h:13
uint16_t flags
Definition thread.h:5
uintptr_t rip_before_run_elf
Definition elf.c:15
boolean_t elf_has_running
Definition elf.c:14
void serial2_printf(const char *fmt,...)
uint8_t name_len
Definition iso9660.h:19
void * kalloc(size_t size)
uint64_t max(uint64_t a, uint64_t b)
Definition math.c:24
#define ALIGN_DOWN(x, align)
Definition memory_utils.h:9
#define PTR_ADD(ptr, off)
#define ASSUME_ALIGNED(ptr, align)
#define ALIGN_UP(x, align)
Definition memory_utils.h:6
return value
Definition oct2bin.h:22
uintptr_t page
Definition paging.c:0
page_t paging_get_highest_page_map(void)
Definition paging.c:463
void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags)
Definition paging.c:340
#define PAGE_PRESENT
Definition paging.h:34
#define PAGE_NO_EXECUTE
Definition paging.h:43
#define PAGE_USER
Definition paging.h:36
#define PAGE_SIZE
Definition paging.h:6
#define PAGE_WRITABLE
Definition paging.h:35
void * phys_base_alloc(uint64_t block)
#define BLOCK_SIZE
#define LOG2_WARN(mod, fmt,...)
Definition serial.h:40
#define LOG2_DEBUG(mod, fmt,...)
Definition serial.h:35
#define LOG2_INFO(mod, fmt,...)
Definition serial.h:33
uintptr_t phys_addr
Definition slab.h:6
int strncmp(const char *s1, const char *s2, size_t n)
size_t strlen(const char *s)
Definition str.c:105
void memset(void *ptr, int value, size_t num)
void memcopy(void *dest, void *src, size_t size)
union Elf64_Dyn::@220367214354326365050217232242036207207371044375 d_un
uint64_t d_tag
Definition elf.h:197
uint64_t d_ptr
Definition elf.h:200
uint64_t d_val
Definition elf.h:199
uint64_t e_shoff
Definition elf.h:29
uint32_t e_version
Definition elf.h:26
uint16_t e_shnum
Definition elf.h:35
uint16_t e_phentsize
Definition elf.h:32
uint16_t e_phnum
Definition elf.h:33
uint64_t e_phoff
Definition elf.h:28
uint64_t e_entry
Definition elf.h:27
uint16_t e_shstrndx
Definition elf.h:36
uint64_t p_offset
Definition elf.h:42
uint64_t p_memsz
Definition elf.h:46
uint32_t p_type
Definition elf.h:40
uint32_t p_flags
Definition elf.h:41
uint64_t p_filesz
Definition elf.h:45
uint64_t p_vaddr
Definition elf.h:43
uint64_t r_offset
Definition elf.h:78
int64_t r_addend
Definition elf.h:80
uint32_t sh_type
Definition elf.h:52
uint64_t sh_offset
Definition elf.h:55
uint64_t sh_addr
Definition elf.h:54
uint32_t sh_name
Definition elf.h:51
uint64_t sh_size
Definition elf.h:56
uint64_t st_value
Definition elf.h:68
uint64_t st_size
Definition elf.h:69
uint32_t st_name
Definition elf.h:64
uint32_t bloom_size
Definition elf.h:303
uint32_t nbuckets
Definition elf.h:301
uint32_t * chains
Definition elf.h:308
uint32_t bloom_shift
Definition elf.h:304
uint32_t * buckets
Definition elf.h:307
uint32_t symoffset
Definition elf.h:302
uintptr_t * bloom
Definition elf.h:306
uintptr_t value
Definition symbols.h:9
const char * name
Definition symbols.h:8
struct vector_symbols_item items
Definition symbols.h:16
const char * name
Definition symbols.h:15
symbols_ptr * data
Definition symbols.h:19
struct vector_symbols_ptr symbols_ptr_vector_t
Definition symbols.h:20
#define NULL
Definition type.h:76
unsigned int uint32_t
Definition type.h:19
uint8_t boolean_t
Definition type.h:89
unsigned long uintptr_t
Definition type.h:73
unsigned long uint64_t
Definition type.h:25
signed int int32_t
Definition type.h:43
unsigned char uint8_t
Definition type.h:7
#define vector_push_back(v, val)
Definition vector.h:45
#define vector(T)
Definition vector.h:11
#define vector_init(v)
Definition vector.h:20
uint16_t idx
Definition virtio-gpu.hpp:1
uint32_t offset
Definition virtio.h:6
uintptr_t vma_lookup_free_vaddr(struct virtual_memory_page *page, mem_vma_region region, size_t size)
Definition vm_manager.c:156
struct virtual_memory_page * get_kernel_vmm_page()
@ VMA_REGION_B
Definition vm_manager.h:14
uint8_t type
Definition vnode.h:2
uint64_t ptr
Definition xhci.hpp:0