diff options
author | jdp <jdp@FreeBSD.org> | 2000-01-29 01:27:04 +0000 |
---|---|---|
committer | jdp <jdp@FreeBSD.org> | 2000-01-29 01:27:04 +0000 |
commit | 4bff590782e7100c86fb3cb5c40e46fb5c813b42 (patch) | |
tree | 15bb6f7a1a22644cfbb8a3a3b6db5834e253c62b /libexec/rtld-elf/i386/reloc.c | |
parent | a037c1293d958b92212a5b2d4a23307eea11f46d (diff) | |
download | FreeBSD-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/i386/reloc.c')
-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; } |