diff options
Diffstat (limited to 'libexec/rtld-elf/i386')
-rw-r--r-- | libexec/rtld-elf/i386/reloc.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c index 217d88e..360733a 100644 --- a/libexec/rtld-elf/i386/reloc.c +++ b/libexec/rtld-elf/i386/reloc.c @@ -203,7 +203,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) /* Process the PLT relocations. */ int -reloc_plt(Obj_Entry *obj, bool bind_now) +reloc_plt(Obj_Entry *obj) { const Elf_Rel *rellim; const Elf_Rel *rel; @@ -217,17 +217,32 @@ reloc_plt(Obj_Entry *obj, bool bind_now) /* Relocate the GOT slot pointing into the PLT. */ where = (Elf_Addr *)(obj->relocbase + rel->r_offset); *where += (Elf_Addr)obj->relocbase; + } + return 0; +} - if (bind_now) { /* Fully resolve the procedure address. */ - const Elf_Sym *def; - const Obj_Entry *defobj; +/* Relocate the jump slots in an object. */ +int +reloc_jmpslots(Obj_Entry *obj) +{ + const Elf_Rel *rellim; + const Elf_Rel *rel; - def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true); - if (def == NULL) - return -1; - reloc_jmpslot(where, - (Elf_Addr)(defobj->relocbase + def->st_value)); - } + if (obj->jmpslots_done) + return 0; + rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize); + for (rel = obj->pltrel; rel < rellim; rel++) { + Elf_Addr *where; + 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); + if (def == NULL) + return -1; + reloc_jmpslot(where, (Elf_Addr)(defobj->relocbase + def->st_value)); } + obj->jmpslots_done = true; return 0; } |