summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/i386/reloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/rtld-elf/i386/reloc.c')
-rw-r--r--libexec/rtld-elf/i386/reloc.c35
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;
}
OpenPOWER on IntegriCloud