/* PowerPC64-specific support for 64-bit ELF.
- Copyright (C) 1999-2020 Free Software Foundation, Inc.
+ Copyright (C) 1999-2021 Free Software Foundation, Inc.
Written by Linus Nordberg, Swox AB <info@swox.com>,
based on elf32-ppc.c by Ian Lance Taylor.
Largely rewritten by Alan Modra.
if (error_message != NULL)
{
- static char buf[60];
- sprintf (buf, "generic linker can't handle %s",
- reloc_entry->howto->name);
- *error_message = buf;
+ static char *message;
+ free (message);
+ if (asprintf (&message, _("generic linker can't handle %s"),
+ reloc_entry->howto->name) < 0)
+ message = NULL;
+ *error_message = message;
}
return bfd_reloc_dangerous;
}
\f
/* Parameters for the qsort hook. */
static bfd_boolean synthetic_relocatable;
-static asection *synthetic_opd;
+static const asection *synthetic_opd;
/* qsort comparison function for ppc64_elf_get_synthetic_symtab. */
static void
ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
- const Elf_Internal_Sym *isym,
+ unsigned int st_other,
bfd_boolean definition,
bfd_boolean dynamic)
{
if (definition && (!dynamic || !h->def_regular))
- h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
+ h->other = ((st_other & ~ELF_ST_VISIBILITY (-1))
| ELF_ST_VISIBILITY (h->other));
}
obfd = htab->params->stub_bfd;
is_tga = ((stub_entry->stub_type == ppc_stub_plt_call_notoc
|| stub_entry->stub_type == ppc_stub_plt_call_both)
+ && stub_entry->h != NULL
&& is_tls_get_addr (&stub_entry->h->elf, htab)
&& htab->params->tls_get_addr_opt);
if (is_tga)
case ppc_stub_plt_call_notoc:
case ppc_stub_plt_call_both:
lr_used = 0;
- if (is_tls_get_addr (&stub_entry->h->elf, htab)
+ if (stub_entry->h != NULL
+ && is_tls_get_addr (&stub_entry->h->elf, htab)
&& htab->params->tls_get_addr_opt)
{
lr_used += 7 * 4;
}
if ((stub_entry->stub_type == ppc_stub_plt_call_notoc
|| stub_entry->stub_type == ppc_stub_plt_call_both)
+ && stub_entry->h != NULL
&& is_tls_get_addr (&stub_entry->h->elf, htab)
&& htab->params->tls_get_addr_opt)
{
}
val = sym->st_value + ent->addend;
- if (ELF_ST_TYPE (sym->st_info) != STT_GNU_IFUNC)
- val += PPC64_LOCAL_ENTRY_OFFSET (sym->st_other);
if (sym_sec != NULL && sym_sec->output_section != NULL)
val += sym_sec->output_offset + sym_sec->output_section->vma;
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
{
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
- if ((insn & (0x3fu << 26 | 0x3)) == 58u << 26 /* ld */)
+ if (r_type == R_PPC64_GOT16_LO_DS
+ && (insn & (0x3fu << 26 | 0x3)) == 58u << 26 /* ld */)
{
insn += (14u << 26) - (58u << 26);
bfd_put_32 (input_bfd, insn, contents + (rel->r_offset & ~3));
r_type = R_PPC64_TOC16_LO;
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
}
- else if ((insn & (0x3fu << 26)) == 15u << 26 /* addis */)
+ else if (r_type == R_PPC64_GOT16_HA
+ && (insn & (0x3fu << 26)) == 15u << 26 /* addis */)
{
r_type = R_PPC64_TOC16_HA;
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
/* FreeBSD support */
#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM powerpc_elf64_fbsd_le_vec
#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-powerpcle-freebsd"
#undef TARGET_BIG_SYM
#define TARGET_BIG_SYM powerpc_elf64_fbsd_vec