From f609f0351a301d4718a3bda7208d3f190462cce6 Mon Sep 17 00:00:00 2001 From: John Marino Date: Sat, 14 Jan 2012 16:19:06 +0100 Subject: [PATCH] rtld: Reorganize reloc_plt and reloc_jmpslots In the future, more reloc types than just R_$ARCH_JMP_SLOT will be supported. FreeBSD already has them and converted to a switch statement and introduced a new rtld_error message rather than use an ASSERT. Follow suit and fix a mismatching const as well. --- libexec/rtld-elf/i386/reloc.c | 43 ++++++++++++++++++++++----------- libexec/rtld-elf/x86_64/reloc.c | 39 +++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 26 deletions(-) diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c index adf777468e..f1292d3104 100644 --- a/libexec/rtld-elf/i386/reloc.c +++ b/libexec/rtld-elf/i386/reloc.c @@ -317,15 +317,22 @@ reloc_plt(Obj_Entry *obj) const Elf_Rel *rellim; const Elf_Rel *rel; - rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); + rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize); for (rel = obj->pltrel; rel < rellim; rel++) { Elf_Addr *where; - assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT); - - /* Relocate the GOT slot pointing into the PLT. */ - where = (Elf_Addr *)(obj->relocbase + rel->r_offset); - *where += (Elf_Addr)obj->relocbase; + switch (ELF_R_TYPE(rel->r_info)) { + case R_386_JMP_SLOT: + /* Relocate the GOT slot pointing into the PLT. */ + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + *where += (Elf_Addr)obj->relocbase; + break; + + default: + _rtld_error("Unknown relocation type %x in PLT", + ELF_R_TYPE(rel->r_info)); + return (-1); + } } return 0; } @@ -345,14 +352,23 @@ reloc_jmpslots(Obj_Entry *obj) const Elf_Sym *def; const Obj_Entry *defobj; - assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT); - where = (Elf_Addr *)(obj->relocbase + rel->r_offset); - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL); - if (def == NULL) - return -1; - target = (Elf_Addr)(defobj->relocbase + def->st_value); - reloc_jmpslot(where, target, defobj, obj, rel); + switch (ELF_R_TYPE(rel->r_info)) { + case R_386_JMP_SLOT: + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL); + if (def == NULL) + return (-1); + target = (Elf_Addr)(defobj->relocbase + def->st_value); + reloc_jmpslot(where, target, defobj, obj, rel); + break; + + default: + _rtld_error("Unknown relocation type %x in PLT", + ELF_R_TYPE(rel->r_info)); + return (-1); + } } + obj->jmpslots_done = true; return 0; } @@ -384,4 +400,3 @@ __tls_get_addr_tcb(struct tls_tcb *tcb, tls_index *ti) { return tls_get_addr_common((Elf_Addr **)&tcb->tcb_dtv, ti->ti_module, ti->ti_offset); } - diff --git a/libexec/rtld-elf/x86_64/reloc.c b/libexec/rtld-elf/x86_64/reloc.c index ca11a80e21..574cc99725 100644 --- a/libexec/rtld-elf/x86_64/reloc.c +++ b/libexec/rtld-elf/x86_64/reloc.c @@ -342,11 +342,18 @@ reloc_plt(Obj_Entry *obj) for (rela = obj->pltrela; rela < relalim; rela++) { Elf_Addr *where; - assert(ELF_R_TYPE(rela->r_info) == R_X86_64_JMP_SLOT); - - /* Relocate the GOT slot pointing into the PLT. */ - where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - *where += (Elf_Addr)obj->relocbase; + switch(ELF_R_TYPE(rela->r_info)) { + case R_X86_64_JMP_SLOT: + /* Relocate the GOT slot pointing into the PLT. */ + where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + *where += (Elf_Addr)obj->relocbase; + break; + + default: + _rtld_error("Unknown relocation type %x in PLT", + (unsigned int)ELF_R_TYPE(rela->r_info)); + return (-1); + } } return 0; } @@ -366,13 +373,21 @@ reloc_jmpslots(Obj_Entry *obj) const Elf_Sym *def; const Obj_Entry *defobj; - assert(ELF_R_TYPE(rela->r_info) == R_X86_64_JMP_SLOT); - where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true, NULL); - if (def == NULL) - return -1; - target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); - reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela); + switch (ELF_R_TYPE(rela->r_info)) { + case R_X86_64_JMP_SLOT: + where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true, NULL); + if (def == NULL) + return (-1); + target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); + reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela); + break; + + default: + _rtld_error("Unknown relocation type %x in PLT", + (unsigned int)ELF_R_TYPE(rela->r_info)); + return (-1); + } } obj->jmpslots_done = true; return 0; -- 2.41.0