Skip to content

Instantly share code, notes, and snippets.

@JohnnyonFlame
Last active May 15, 2021 18:32
Show Gist options
  • Save JohnnyonFlame/cfc370e744b9f7346327097f8927eaac to your computer and use it in GitHub Desktop.
Save JohnnyonFlame/cfc370e744b9f7346327097f8927eaac to your computer and use it in GitHub Desktop.
Human-parseable symbol resolution errors
//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