diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2011-12-14 16:47:53 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2011-12-14 16:47:53 +0000 |
commit | 5734c46c68e4f5b4edfc00921d02d8b8c973e51c (patch) | |
tree | 2deca750951347f2dbf7f42e4e15affd3168c2e5 /libexec/rtld-elf/i386 | |
parent | 7e1f37e14e0cc34adcf134aac671d3ee0900a838 (diff) | |
download | src-test2-5734c46c68e4f5b4edfc00921d02d8b8c973e51c.tar.gz src-test2-5734c46c68e4f5b4edfc00921d02d8b8c973e51c.zip |
Notes
Diffstat (limited to 'libexec/rtld-elf/i386')
-rw-r--r-- | libexec/rtld-elf/i386/reloc.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c index 5f11106ab14c..68a5331064bf 100644 --- a/libexec/rtld-elf/i386/reloc.c +++ b/libexec/rtld-elf/i386/reloc.c @@ -371,16 +371,21 @@ reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate) const Elf_Rel *rel; Elf_Addr *where, target; + if (!obj->irelative) + return (0); rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize); for (rel = obj->pltrel; rel < rellim; rel++) { switch (ELF_R_TYPE(rel->r_info)) { case R_386_IRELATIVE: where = (Elf_Addr *)(obj->relocbase + rel->r_offset); - target = ((Elf_Addr (*)(void))(*where))(); + lock_release(rtld_bind_lock, lockstate); + target = ((Elf_Addr (*)(void))(obj->relocbase + *where))(); + wlock_acquire(rtld_bind_lock, lockstate); *where = target; break; } } + obj->irelative = false; return (0); } @@ -407,7 +412,9 @@ reloc_gnu_ifunc(Obj_Entry *obj, RtldLockState *lockstate) return (-1); if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC) continue; + lock_release(rtld_bind_lock, lockstate); target = (Elf_Addr)rtld_resolve_ifunc(defobj, def); + wlock_acquire(rtld_bind_lock, lockstate); reloc_jmpslot(where, target, defobj, obj, rel); break; } |