summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/alpha
diff options
context:
space:
mode:
authorjdp <jdp@FreeBSD.org>2000-01-29 01:27:04 +0000
committerjdp <jdp@FreeBSD.org>2000-01-29 01:27:04 +0000
commit4bff590782e7100c86fb3cb5c40e46fb5c813b42 (patch)
tree15bb6f7a1a22644cfbb8a3a3b6db5834e253c62b /libexec/rtld-elf/alpha
parenta037c1293d958b92212a5b2d4a23307eea11f46d (diff)
downloadFreeBSD-src-4bff590782e7100c86fb3cb5c40e46fb5c813b42.zip
FreeBSD-src-4bff590782e7100c86fb3cb5c40e46fb5c813b42.tar.gz
When a threads package registers locking methods with dllockinit(),
figure out which shared object(s) contain the the locking methods and fully bind those objects as if they had been loaded with LD_BIND_NOW=1. The goal is to keep the locking methods from requiring any lazy binding. Otherwise infinite recursion occurs in _rtld_bind. This fixes the infinite recursion problem in the linuxthreads port.
Diffstat (limited to 'libexec/rtld-elf/alpha')
-rw-r--r--libexec/rtld-elf/alpha/reloc.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/libexec/rtld-elf/alpha/reloc.c b/libexec/rtld-elf/alpha/reloc.c
index 114f3ae..8763be4 100644
--- a/libexec/rtld-elf/alpha/reloc.c
+++ b/libexec/rtld-elf/alpha/reloc.c
@@ -159,7 +159,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)
{
/* All PLT relocations are the same kind: either Elf_Rel or Elf_Rela. */
if (obj->pltrelsize != 0) {
@@ -175,17 +175,6 @@ 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;
-
- if (bind_now) { /* Fully resolve the procedure address. */
- const Elf_Sym *def;
- const Obj_Entry *defobj;
-
- 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));
- }
}
} else {
const Elf_Rela *relalim;
@@ -200,19 +189,56 @@ reloc_plt(Obj_Entry *obj, bool bind_now)
/* Relocate the GOT slot pointing into the PLT. */
where = (Elf_Addr *)(obj->relocbase + rela->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)
+{
+ if (obj->jmpslots_done)
+ return 0;
+ /* All PLT relocations are the same kind: either Elf_Rel or Elf_Rela. */
+ if (obj->pltrelsize != 0) {
+ const Elf_Rel *rellim;
+ const Elf_Rel *rel;
- def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true);
- if (def == NULL)
- return -1;
- reloc_jmpslot(where,
- (Elf_Addr)(defobj->relocbase + def->st_value));
- }
+ 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_ALPHA_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));
+ }
+ } else {
+ const Elf_Rela *relalim;
+ const Elf_Rela *rela;
+
+ relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
+ for (rela = obj->pltrela; rela < relalim; rela++) {
+ Elf_Addr *where;
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
+
+ assert(ELF_R_TYPE(rela->r_info) == R_ALPHA_JMP_SLOT);
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+ def = find_symdef(ELF_R_SYM(rela->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