PatchworkOS  966e257
A non-POSIX operating system.
Loading...
Searching...
No Matches
elf64_relocate.c
Go to the documentation of this file.
1#include "common/elf.h"
2
4 void* (*resolve_symbol)(const char* name, void* private), void* private)
5{
6 for (uint64_t i = 0; i < elf->header->e_shnum; i++)
7 {
8 Elf64_Shdr* shdr = ELF64_GET_SHDR(elf, i);
9 if (shdr->sh_type != SHT_RELA)
10 {
11 continue;
12 }
13
14 Elf64_Shdr* targetShdr = ELF64_GET_SHDR(elf, shdr->sh_info);
15
16 Elf64_Rela* rela = ELF64_AT_OFFSET(elf, shdr->sh_offset);
17 uint64_t relaCount = shdr->sh_size / sizeof(Elf64_Rela);
18
19 for (uint64_t j = 0; j < relaCount; j++)
20 {
21 Elf64_Addr* patchAddr = (Elf64_Addr*)(base + (targetShdr->sh_addr + rela[j].r_offset - offset));
22 Elf64_Xword type = ELF64_R_TYPE(rela[j].r_info);
23 Elf64_Xword symIndex = ELF64_R_SYM(rela[j].r_info);
24
25 Elf64_Sym* sym = elf64_get_dynamic_symbol_by_index(elf, symIndex);
26 const char* symName = elf64_get_dynamic_symbol_name(elf, sym);
27
28 Elf64_Addr value = sym->st_shndx != SHN_UNDEF ? sym->st_value : 0;
29
30 switch (type)
31 {
32 case R_X86_64_64:
33 *patchAddr = base + value + rela[j].r_addend;
34 break;
35 case R_X86_64_PC32:
36 *patchAddr = base + value + rela[j].r_addend - (Elf64_Addr)patchAddr;
37 break;
40 *patchAddr = (uint64_t)resolve_symbol(symName, private);
41 if (*patchAddr == 0)
42 {
43 return ERR;
44 }
45 break;
47 *patchAddr = base + rela[j].r_addend;
48 break;
49 default:
50#ifdef _KERNEL_
51 LOG_ERR("unsupported relocation type %llu for symbol '%s'\n", type, symName);
52#endif
53 return ERR;
54 }
55 }
56 }
57
58 return 0;
59}
#define LOG_ERR(format,...)
Definition log.h:108
Elf64_Sym * elf64_get_dynamic_symbol_by_index(const Elf64_File *elf, Elf64_Xword symbolIndex)
Get a dynamic symbol by its index from the dynamic symbol table.
#define ELF64_AT_OFFSET(elf, offset)
Get a pointer to a location in the ELF file at the given offset.
Definition elf.h:814
#define ELF64_R_TYPE(i)
Extract the type from r_info.
Definition elf.h:650
uint64_t Elf64_Xword
ELF64 Unsigned long integer.
Definition elf.h:60
uint64_t elf64_relocate(const Elf64_File *elf, Elf64_Addr base, Elf64_Off offset, void *(*resolve_symbol)(const char *name, void *private), void *private)
Perform relocations on an ELF file loaded into memory.
uint64_t Elf64_Off
ELF64 Unsigned file offset.
Definition elf.h:36
const char * elf64_get_dynamic_symbol_name(const Elf64_File *elf, const Elf64_Sym *symbol)
Get the name of a dynamic symbol.
#define ELF64_R_SYM(i)
Extract the symbol index from r_info.
Definition elf.h:640
#define ELF64_GET_SHDR(elf, index)
Get the section header at the given index from an ELF file.
Definition elf.h:805
uint64_t Elf64_Addr
ELF64 Unsigned program address.
Definition elf.h:30
@ SHN_UNDEF
Undefined section.
Definition elf.h:446
@ R_X86_64_RELATIVE
word64 B + A
Definition elf.h:681
@ R_X86_64_GLOB_DAT
word64 S
Definition elf.h:679
@ R_X86_64_64
word64 S + A
Definition elf.h:674
@ R_X86_64_JUMP_SLOT
word64 S
Definition elf.h:680
@ R_X86_64_PC32
word32 S + A - P
Definition elf.h:675
@ SHT_RELA
Contains relocation entries with explicit addends.
Definition elf.h:493
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
Elf64_Half e_shnum
Definition elf.h:114
ELF File Helper structure.
Definition elf.h:781
Elf64_Ehdr * header
The data in the file, pointed to the start of the ELF header.
Definition elf.h:782
ELF64 Rela Entry with addend.
Definition elf.h:626
Elf64_Sxword r_addend
Definition elf.h:629
Elf64_Addr r_offset
Definition elf.h:627
ELF64 Section Header.
Definition elf.h:468
Elf64_Word sh_type
Section type.
Definition elf.h:470
Elf64_Word sh_info
Depends on section type.
Definition elf.h:477
Elf64_Xword sh_size
Section size in bytes.
Definition elf.h:474
Elf64_Addr sh_addr
If the section will appear in memory, this will be its virtual address, otherwise 0
Definition elf.h:472
Elf64_Off sh_offset
Section's file offset in bytes.
Definition elf.h:473
ELF64 Symbol Table Entry.
Definition elf.h:543
Elf64_Half st_shndx
Definition elf.h:547
Elf64_Addr st_value
Definition elf.h:548