Last active
May 15, 2021 18:32
-
-
Save JohnnyonFlame/cfc370e744b9f7346327097f8927eaac to your computer and use it in GitHub Desktop.
Human-parseable symbol resolution errors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Iterates each symbol that is either in .rel.dyn or .rel.plt sections | |
#define FOREACH_REL(func) \ | |
for (int i = 0; i < elf_hdr->e_shnum; i++) { \ | |
char *sh_name = shstrtab + sec_hdr[i].sh_name; \ | |
if (strcmp(sh_name, ".rel.dyn") == 0 || strcmp(sh_name, ".rel.plt") == 0) { \ | |
Elf32_Rel *rels = (Elf32_Rel *)((uintptr_t)text_base + sec_hdr[i].sh_addr); \ | |
for (size_t j = 0; j < sec_hdr[i].sh_size / sizeof(Elf32_Rel); j++) { \ | |
uintptr_t *ptr = (uintptr_t *)(text_base + rels[j].r_offset); \ | |
Elf32_Sym *sym = &syms[ELF32_R_SYM(rels[j].r_info)]; \ | |
int type = ELF32_R_TYPE(rels[j].r_info); \ | |
func \ | |
} \ | |
} \ | |
} | |
uintptr_t reloc_err(uintptr_t gotx) | |
{ | |
FOREACH_REL( | |
switch (type) { | |
case R_ARM_GLOB_DAT: | |
case R_ARM_JUMP_SLOT: | |
if (sym->st_shndx == SHN_UNDEF) { | |
if (gotx == ptr) { | |
const char *name = dynstrtab + sym->st_name; | |
fatal_error("Undefined symbol %s.\n", name); | |
exit(-1); | |
} | |
} | |
break; | |
default: | |
break; | |
} | |
) | |
fatal_error("Unable to locate reloc %p???\n", gotx); | |
exit(-1); | |
} | |
__attribute__((naked)) void plt0_stub() | |
{ | |
register uintptr_t got0 asm("r12"); | |
reloc_err(got0); | |
} | |
int so_relocate(void) { | |
FOREACH_REL( | |
const char *name = dynstrtab + sym->st_name; | |
switch (type) { | |
case R_ARM_ABS32: | |
*ptr += (uintptr_t)text_base + sym->st_value; | |
break; | |
case R_ARM_RELATIVE: | |
*ptr += (uintptr_t)text_base; | |
break; | |
case R_ARM_GLOB_DAT: | |
case R_ARM_JUMP_SLOT: | |
{ | |
if (sym->st_shndx != SHN_UNDEF) | |
*ptr = (uintptr_t)text_base + sym->st_value; | |
else { | |
if ((*ptr = so_resolve_symbol(name)) == NULL) { | |
if (type == R_ARM_JUMP_SLOT) | |
*ptr = plt0_stub; | |
else { | |
fatal_error("Undefined symbol %s.\n", name); | |
exit(-1); | |
} | |
} | |
} | |
break; | |
} | |
default: | |
fatal_error("Error unknown relocation type %x\n", type); | |
break; | |
} | |
) | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment