diff options
| author | Peter Wemm <peter@FreeBSD.org> | 2002-04-07 04:16:35 +0000 |
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 2002-04-07 04:16:35 +0000 |
| commit | 968253905ebf5b0999c56877772c4858730bf4c2 (patch) | |
| tree | afd56026ad7773fbd891918c00e10ab3948389e8 /libexec | |
| parent | 94f11749cdb983eb1bf9784691fe7a716c7a3319 (diff) | |
Notes
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/rtld-elf/ia64/reloc.c | 19 |
1 files 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. |
