From 888c632b353fb248add098435b31a7c5504928f8 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 7 Apr 2002 04:16:35 +0000 Subject: [PATCH] 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. --- libexec/rtld-elf/ia64/reloc.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libexec/rtld-elf/ia64/reloc.c b/libexec/rtld-elf/ia64/reloc.c index 8ec68608f8a0..a38d1b0ef510 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.