summaryrefslogtreecommitdiff
path: root/libexec/rtld-elf/i386
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2011-12-14 16:47:53 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2011-12-14 16:47:53 +0000
commit5734c46c68e4f5b4edfc00921d02d8b8c973e51c (patch)
tree2deca750951347f2dbf7f42e4e15affd3168c2e5 /libexec/rtld-elf/i386
parent7e1f37e14e0cc34adcf134aac671d3ee0900a838 (diff)
downloadsrc-test2-5734c46c68e4f5b4edfc00921d02d8b8c973e51c.tar.gz
src-test2-5734c46c68e4f5b4edfc00921d02d8b8c973e51c.zip
Notes
Diffstat (limited to 'libexec/rtld-elf/i386')
-rw-r--r--libexec/rtld-elf/i386/reloc.c9
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;
}