summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2002-04-07 04:16:35 +0000
committerpeter <peter@FreeBSD.org>2002-04-07 04:16:35 +0000
commit888c632b353fb248add098435b31a7c5504928f8 (patch)
treeafd56026ad7773fbd891918c00e10ab3948389e8 /libexec
parent4a1195d2b7fd98ce412de02209afcb89723ac260 (diff)
downloadFreeBSD-src-888c632b353fb248add098435b31a7c5504928f8.zip
FreeBSD-src-888c632b353fb248add098435b31a7c5504928f8.tar.gz
Fix a relocation bug in the ia64 ld.so. Weak function pointers in shared
objects were not being correctly set to zero. Instead, the function descriptor pointer was set to the load address of the .so object. This caused gcc generated binaries to segfault on exit when crtbegin.asm's _fini code tested the __cxa_finalize() function pointer for zero. This is a bit of a hack because of a problem nearby workaround for find_symdef and its quirks (failures) for local symbols. This still needs to be fixed.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/ia64/reloc.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/libexec/rtld-elf/ia64/reloc.c b/libexec/rtld-elf/ia64/reloc.c
index 8ec6860..a38d1b0 100644
--- a/libexec/rtld-elf/ia64/reloc.c
+++ b/libexec/rtld-elf/ia64/reloc.c
@@ -136,7 +136,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
* to ensure this within a single object. If the
* caller's alloca failed, we don't even ensure that.
*/
- const Elf_Sym *def;
+ const Elf_Sym *def, *ref;
const Obj_Entry *defobj;
struct fptr *fptr = 0;
Elf_Addr target, gp;
@@ -153,8 +153,21 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
def = &obj->symtab[ELF_R_SYM(rela->r_info)];
defobj = obj;
}
- target = (Elf_Addr) (defobj->relocbase + def->st_value);
- gp = (Elf_Addr) defobj->pltgot;
+ /*
+ * If this is an undefined weak reference, we need to
+ * have a zero target,gp fptr, not pointing to relocbase.
+ * This isn't quite right. Maybe we should check
+ * explicitly for def == &sym_zero.
+ */
+ if (def->st_value == 0 &&
+ (ref = obj->symtab + ELF_R_SYM(rela->r_info)) &&
+ ELF_ST_BIND(ref->st_info) == STB_WEAK) {
+ target = 0;
+ gp = 0;
+ } else {
+ target = (Elf_Addr) (defobj->relocbase + def->st_value);
+ gp = (Elf_Addr) defobj->pltgot;
+ }
/*
* Find the @fptr, using fptrs as a helper.
OpenPOWER on IntegriCloud