#define elf_backend_special_sections ppc64_elf_special_sections
#define elf_backend_merge_symbol_attribute ppc64_elf_merge_symbol_attribute
#define elf_backend_merge_symbol ppc64_elf_merge_symbol
+#define elf_backend_get_reloc_section bfd_get_section_by_name
/* The name of the dynamic interpreter. This is put in the .interp
section. */
}
}
+/* Whether an undefined weak symbol should resolve to its link-time
+ value, even in PIC or PIE objects. */
+#define UNDEFWEAK_NO_DYNAMIC_RELOC(INFO, H) \
+ ((H)->root.type == bfd_link_hash_undefweak \
+ && (ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \
+ || (INFO)->dynamic_undefined_weak == 0))
+
/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
copying dynamic variables from a shared lib into an app's dynbss
section, and instead use a dynamic relocation to point into the
/* Propagate reference flags from entry symbol to function
descriptor symbol. */
- fdh->elf.root.non_ir_ref |= eh->elf.root.non_ir_ref;
+ fdh->elf.root.non_ir_ref_regular |= eh->elf.root.non_ir_ref_regular;
+ fdh->elf.root.non_ir_ref_dynamic |= eh->elf.root.non_ir_ref_dynamic;
fdh->elf.ref_regular |= eh->elf.ref_regular;
fdh->elf.ref_regular_nonweak |= eh->elf.ref_regular_nonweak;
/* PR15323, ref flags aren't set for references in the same
object. */
- h->root.non_ir_ref = 1;
+ h->root.non_ir_ref_regular = 1;
if (eh->is_func && eh->oh != NULL)
- eh->oh->elf.root.non_ir_ref = 1;
+ eh->oh->elf.root.non_ir_ref_regular = 1;
if (h == htab->elf.hgot)
sec->has_toc_reloc = 1;
unsigned long r_symndx;
enum elf_ppc64_reloc_type r_type;
struct elf_link_hash_entry *h = NULL;
- struct plt_entry **plt_list;
+ struct plt_entry **plt_list = NULL;
unsigned char tls_type = 0;
r_symndx = ELF64_R_SYM (rel->r_info);
if (ent->got.refcount > 0)
ent->got.refcount -= 1;
}
+ if (h != NULL && !bfd_link_pic (info) && abiversion (abfd) != 1)
+ plt_list = &h->plt.plist;
break;
case R_PPC64_PLT16_HA:
case R_PPC64_REL14_BRNTAKEN:
case R_PPC64_REL14_BRTAKEN:
case R_PPC64_REL24:
- plt_list = NULL;
if (h != NULL)
plt_list = &h->plt.plist;
else if (local_got_ents != NULL)
if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
plt_list = local_plt + r_symndx;
}
- if (plt_list)
- {
- struct plt_entry *ent;
+ break;
- for (ent = *plt_list; ent != NULL; ent = ent->next)
- if (ent->addend == rel->r_addend)
- break;
- if (ent != NULL && ent->plt.refcount > 0)
- ent->plt.refcount -= 1;
- }
+ case R_PPC64_ADDR64:
+ case R_PPC64_ADDR16:
+ case R_PPC64_ADDR16_DS:
+ case R_PPC64_ADDR16_HA:
+ case R_PPC64_ADDR16_HI:
+ case R_PPC64_ADDR16_HIGH:
+ case R_PPC64_ADDR16_HIGHA:
+ case R_PPC64_ADDR16_HIGHER:
+ case R_PPC64_ADDR16_HIGHERA:
+ case R_PPC64_ADDR16_HIGHEST:
+ case R_PPC64_ADDR16_HIGHESTA:
+ case R_PPC64_ADDR16_LO:
+ case R_PPC64_ADDR16_LO_DS:
+ if (h != NULL && !bfd_link_pic (info) && abiversion (abfd) != 1
+ && rel->r_addend == 0)
+ plt_list = &h->plt.plist;
break;
default:
break;
}
+ if (plt_list != NULL)
+ {
+ struct plt_entry *ent;
+
+ for (ent = *plt_list; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend)
+ break;
+ if (ent != NULL && ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+ }
}
return TRUE;
}
if (ent == NULL
|| (h->type != STT_GNU_IFUNC
&& (SYMBOL_CALLS_LOCAL (info, h)
- || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
- && h->root.type == bfd_link_hash_undefweak)))
+ || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)))
|| ((struct ppc_link_hash_entry *) h)->save_res)
{
h->plt.plist = NULL;
if (ent.sec == NULL || ent.sec->output_section == NULL)
{
_bfd_error_handler
- (_("%B: undefined symbol on R_PPC64_TOCSAVE relocation"));
+ (_("%B: undefined symbol on R_PPC64_TOCSAVE relocation"), ibfd);
return NULL;
}
&& (tga_fd->type == STT_FUNC
|| tga_fd->needs_plt)
&& !(SYMBOL_CALLS_LOCAL (info, tga_fd)
- || (ELF_ST_VISIBILITY (tga_fd->other) != STV_DEFAULT
- && tga_fd->root.type == bfd_link_hash_undefweak)))
+ || UNDEFWEAK_NO_DYNAMIC_RELOC (info, tga_fd)))
{
struct plt_entry *ent;
|| (htab->elf.dynamic_sections_created
&& h->dynindx != -1
&& !SYMBOL_REFERENCES_LOCAL (info, h)))
- && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- || h->root.type != bfd_link_hash_undefweak))
+ && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
{
asection *relgot = ppc64_elf_tdata (gent->owner)->relgot;
relgot->size += rentsize;
struct elf_link_hash_table *htab = elf_hash_table (info);
if (htab->dynamic_sections_created
+ && info->dynamic_undefined_weak != 0
&& h->root.type == bfd_link_hash_undefweak
&& h->dynindx == -1
&& !h->forced_local
allocate_got (h, info, gent);
}
+ /* If no dynamic sections we can't have dynamic relocs, except for
+ IFUNCs which are handled even in static executables. */
if (!htab->elf.dynamic_sections_created
&& h->type != STT_GNU_IFUNC)
eh->dyn_relocs = NULL;
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility, or when dynamic_undefined_weak says so. */
+ else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+ eh->dyn_relocs = NULL;
+
if (eh->dyn_relocs != NULL)
{
struct elf_dyn_relocs *p, **pp;
}
}
- /* Also discard relocs on undefined weak syms with
- non-default visibility. */
- if (eh->dyn_relocs != NULL
- && h->root.type == bfd_link_hash_undefweak)
+ if (eh->dyn_relocs != NULL)
{
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
- eh->dyn_relocs = NULL;
-
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
- else if (!ensure_undefweak_dynamic (info, h))
+ if (!ensure_undefweak_dynamic (info, h))
return FALSE;
}
}
addend = 0;
reloc_dest = DEST_STUB;
- if ((stub_entry->stub_type == ppc_stub_plt_call
+ if ((stub_entry->stub_type == ppc_stub_plt_call
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
&& (ALWAYS_EMIT_R2SAVE
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
if (!htab->elf.dynamic_sections_created
|| h->elf.dynindx == -1
|| SYMBOL_REFERENCES_LOCAL (info, &h->elf)
- || (ELF_ST_VISIBILITY (h->elf.other) != STV_DEFAULT
- && h->elf.root.type == bfd_link_hash_undefweak))
+ || UNDEFWEAK_NO_DYNAMIC_RELOC (info, &h->elf))
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
else if (indx != 0
|| (bfd_link_pic (info)
&& (h == NULL
- || (ELF_ST_VISIBILITY (h->elf.other)
- == STV_DEFAULT)
- || h->elf.root.type != bfd_link_hash_undefweak
+ || !UNDEFWEAK_NO_DYNAMIC_RELOC (info, &h->elf)
|| (tls_type == (TLS_TLS | TLS_LD)
&& !h->elf.def_dynamic))))
relgot = ppc64_elf_tdata (ent->owner)->relgot;