PatchworkOS  19e446b
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* data), void* data)
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* symtabShdr = ELF64_GET_SHDR(elf, shdr->sh_link);
15 void* symTableBase = ELF64_AT_OFFSET(elf, symtabShdr->sh_offset);
16 uint64_t symCount = symtabShdr->sh_size / symtabShdr->sh_entsize;
17
18 Elf64_Rela* rela = ELF64_AT_OFFSET(elf, shdr->sh_offset);
19 uint64_t relaCount = shdr->sh_size / sizeof(Elf64_Rela);
20
21 for (uint64_t j = 0; j < relaCount; j++)
22 {
23 Elf64_Addr* patchAddr = (Elf64_Addr*)(base + (rela[j].r_offset - offset));
24 Elf64_Xword type = ELF64_R_TYPE(rela[j].r_info);
25 Elf64_Xword symIndex = ELF64_R_SYM(rela[j].r_info);
26
27 if (symIndex >= symCount)
28 {
29 return ERR;
30 }
31 Elf64_Sym* sym = (Elf64_Sym*)((uintptr_t)symTableBase + (symIndex * symtabShdr->sh_entsize));
32 const char* symName = elf64_get_string(elf, symtabShdr->sh_link, sym->st_name);
33
34 Elf64_Addr value = sym->st_shndx != SHN_UNDEF ? sym->st_value : 0;
35
36 switch (type)
37 {
38 case R_X86_64_64:
39 *patchAddr = base + value + rela[j].r_addend;
40 break;
41 case R_X86_64_PC32:
42 *patchAddr = base + value + rela[j].r_addend - (Elf64_Addr)patchAddr;
43 break;
46 if (sym->st_shndx != SHN_UNDEF)
47 {
48 *patchAddr = base + value + rela[j].r_addend;
49 break;
50 }
51
52 *patchAddr = (uint64_t)resolve_symbol(symName, data);
53 if (*patchAddr == 0)
54 {
55 return ERR;
56 }
57 break;
59 *patchAddr = base + rela[j].r_addend;
60 break;
61 default:
62#ifdef _KERNEL_
63 LOG_ERR("unsupported relocation type %llu for symbol '%s'\n", type, symName);
64#endif
65 return ERR;
66 }
67 }
68 }
69
70 return 0;
71}
static fd_t data
Definition dwm.c:21
#define LOG_ERR(format,...)
Definition log.h:93
const char * elf64_get_string(const Elf64_File *elf, Elf64_Xword strTabIndex, Elf64_Off offset)
Get a string from the string table section at the given offset.
#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_Off
ELF64 Unsigned file offset.
Definition elf.h:36
uint64_t elf64_relocate(const Elf64_File *elf, Elf64_Addr base, Elf64_Off offset, void *(*resolve_symbol)(const char *name, void *data), void *data)
Perform relocations on an ELF file loaded into memory.
#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
static uint64_t offset
Definition screen.c:19
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
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 Section Header.
Definition elf.h:468
Elf64_Word sh_link
Definition elf.h:475
Elf64_Word sh_type
Section type.
Definition elf.h:470
Elf64_Xword sh_entsize
Definition elf.h:479
Elf64_Xword sh_size
Section size in bytes.
Definition elf.h:474
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_Word st_name
Definition elf.h:544
Elf64_Addr st_value
Definition elf.h:548