HOW (R_PPC64_DTPREL34, 4, 34, 0x3ffff0000ffffULL, 0, FALSE, signed,
ppc64_elf_unhandled_reloc),
- HOW (R_PPC64_GOT_TLSGD34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
+ HOW (R_PPC64_GOT_TLSGD_PCREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
- HOW (R_PPC64_GOT_TLSLD34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
+ HOW (R_PPC64_GOT_TLSLD_PCREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
- HOW (R_PPC64_GOT_TPREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
+ HOW (R_PPC64_GOT_TPREL_PCREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
- HOW (R_PPC64_GOT_DTPREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
+ HOW (R_PPC64_GOT_DTPREL_PCREL34, 4, 34, 0x3ffff0000ffffULL, 0, TRUE, signed,
ppc64_elf_unhandled_reloc),
HOW (R_PPC64_ADDR16_HIGHER34, 1, 16, 0xffff, 34, FALSE, dont,
}
static reloc_howto_type *
-ppc64_elf_reloc_type_lookup (bfd *abfd,
- bfd_reloc_code_real_type code)
+ppc64_elf_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
{
enum elf_ppc64_reloc_type r = R_PPC64_NONE;
break;
case BFD_RELOC_PPC64_DTPREL34: r = R_PPC64_DTPREL34;
break;
- case BFD_RELOC_PPC64_GOT_TLSGD34: r = R_PPC64_GOT_TLSGD34;
+ case BFD_RELOC_PPC64_GOT_TLSGD_PCREL34: r = R_PPC64_GOT_TLSGD_PCREL34;
break;
- case BFD_RELOC_PPC64_GOT_TLSLD34: r = R_PPC64_GOT_TLSLD34;
+ case BFD_RELOC_PPC64_GOT_TLSLD_PCREL34: r = R_PPC64_GOT_TLSLD_PCREL34;
break;
- case BFD_RELOC_PPC64_GOT_TPREL34: r = R_PPC64_GOT_TPREL34;
+ case BFD_RELOC_PPC64_GOT_TPREL_PCREL34: r = R_PPC64_GOT_TPREL_PCREL34;
break;
- case BFD_RELOC_PPC64_GOT_DTPREL34: r = R_PPC64_GOT_DTPREL34;
+ case BFD_RELOC_PPC64_GOT_DTPREL_PCREL34: r = R_PPC64_GOT_DTPREL_PCREL34;
break;
case BFD_RELOC_PPC64_ADDR16_HIGHER34: r = R_PPC64_ADDR16_HIGHER34;
break;
};
static reloc_howto_type *
-ppc64_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
- const char *r_name)
+ppc64_elf_reloc_name_lookup (bfd *abfd, const char *r_name)
{
unsigned int i;
+ static char *compat_map[][2] = {
+ { "R_PPC64_GOT_TLSGD34", "R_PPC64_GOT_TLSGD_PCREL34" },
+ { "R_PPC64_GOT_TLSLD34", "R_PPC64_GOT_TLSLD_PCREL34" },
+ { "R_PPC64_GOT_TPREL34", "R_PPC64_GOT_TPREL_PCREL34" },
+ { "R_PPC64_GOT_DTPREL34", "R_PPC64_GOT_DTPREL_PCREL34" }
+ };
for (i = 0; i < ARRAY_SIZE (ppc64_elf_howto_raw); i++)
if (ppc64_elf_howto_raw[i].name != NULL
&& strcasecmp (ppc64_elf_howto_raw[i].name, r_name) == 0)
return &ppc64_elf_howto_raw[i];
+ /* Handle old names of relocations in case they were used by
+ .reloc directives.
+ FIXME: Remove this soon. Mapping the reloc names is very likely
+ completely unnecessary. */
+ for (i = 0; i < ARRAY_SIZE (compat_map); i++)
+ if (strcasecmp (compat_map[i][0], r_name) == 0)
+ {
+ _bfd_error_handler (_("warning: %s should be used rather than %s"),
+ compat_map[i][1], compat_map[i][0]);
+ return ppc64_elf_reloc_name_lookup (abfd, compat_map[i][1]);
+ }
+
return NULL;
}
free_contents_and_exit_err:
count = -1;
free_contents_and_exit:
- if (contents)
- free (contents);
+ free (contents);
goto done;
}
. mtctr %r12
. bctr
- There are also ELFv1 powerxx variants of these stubs.
+ There are also ELFv1 power10 variants of these stubs.
ppc_stub_long_branch_notoc:
. pla %r12,dest@pcrel
. b dest
In cases where the high instructions would add zero, they are
omitted and following instructions modified in some cases.
- For example, a powerxx ppc_stub_plt_call_notoc might simplify down
+ For example, a power10 ppc_stub_plt_call_notoc might simplify down
to
. pld %r12,xxx@pcrel
. mtctr %r12
struct ppc_link_hash_entry *next_dot_sym;
} u;
- /* Track dynamic relocs copied for this symbol. */
- struct elf_dyn_relocs *dyn_relocs;
-
/* Link between function code and descriptor symbols. */
struct ppc_link_hash_entry *oh;
/* Whether func_desc_adjust needs to be run over symbols. */
unsigned int need_func_desc_adj:1;
- /* Whether there exist local gnu indirect function resolvers,
- referenced by dynamic relocations. */
- unsigned int local_ifunc_resolver:1;
- unsigned int maybe_local_ifunc_resolver:1;
-
/* Whether plt calls for ELFv2 localentry:0 funcs have been optimized. */
unsigned int has_plt_localentry0:1;
/* Whether calls are made via the PLT from NOTOC functions. */
unsigned int notoc_plt:1;
- /* Whether to use powerxx instructions in linkage stubs. */
- unsigned int powerxx_stubs:1;
+ /* Whether to use power10 instructions in linkage stubs. */
+ unsigned int power10_stubs:1;
/* Incremented every time we size stubs. */
unsigned int stub_iteration;
return;
/* Copy over any dynamic relocs we may have on the indirect sym. */
- if (eind->dyn_relocs != NULL)
+ if (ind->dyn_relocs != NULL)
{
- if (edir->dyn_relocs != NULL)
+ if (dir->dyn_relocs != NULL)
{
struct elf_dyn_relocs **pp;
struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
- for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ for (pp = &ind->dyn_relocs; (p = *pp) != NULL; )
{
struct elf_dyn_relocs *q;
- for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ for (q = dir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec)
{
q->pc_count += p->pc_count;
if (q == NULL)
pp = &p->next;
}
- *pp = edir->dyn_relocs;
+ *pp = dir->dyn_relocs;
}
- edir->dyn_relocs = eind->dyn_relocs;
- eind->dyn_relocs = NULL;
+ dir->dyn_relocs = ind->dyn_relocs;
+ ind->dyn_relocs = NULL;
}
/* Copy over got entries that we may have already seen to the
if (bfd_link_relocatable (info))
return TRUE;
- /* Don't do anything special with non-loaded, non-alloced sections.
- In particular, any relocs in such sections should not affect GOT
- and PLT reference counting (ie. we don't allow them to create GOT
- or PLT entries), there's no possibility or desire to optimize TLS
- relocs, and there's not much point in propagating relocs to shared
- libs that the dynamic linker won't relocate. */
- if ((sec->flags & SEC_ALLOC) == 0)
- return TRUE;
-
BFD_ASSERT (is_ppc64_elf (abfd));
htab = ppc_hash_table (info);
case R_PPC64_DTPREL34:
case R_PPC64_PCREL34:
case R_PPC64_GOT_PCREL34:
- case R_PPC64_GOT_TLSGD34:
- case R_PPC64_GOT_TLSLD34:
- case R_PPC64_GOT_TPREL34:
- case R_PPC64_GOT_DTPREL34:
+ case R_PPC64_GOT_TLSGD_PCREL34:
+ case R_PPC64_GOT_TLSLD_PCREL34:
+ case R_PPC64_GOT_TPREL_PCREL34:
+ case R_PPC64_GOT_DTPREL_PCREL34:
case R_PPC64_PLT_PCREL34:
case R_PPC64_PLT_PCREL34_NOTOC:
case R_PPC64_PCREL28:
- htab->powerxx_stubs = 1;
+ htab->power10_stubs = 1;
break;
default:
break;
case R_PPC64_GOT_TLSLD16_LO:
case R_PPC64_GOT_TLSLD16_HI:
case R_PPC64_GOT_TLSLD16_HA:
- case R_PPC64_GOT_TLSLD34:
+ case R_PPC64_GOT_TLSLD_PCREL34:
tls_type = TLS_TLS | TLS_LD;
goto dogottls;
case R_PPC64_GOT_TLSGD16_LO:
case R_PPC64_GOT_TLSGD16_HI:
case R_PPC64_GOT_TLSGD16_HA:
- case R_PPC64_GOT_TLSGD34:
+ case R_PPC64_GOT_TLSGD_PCREL34:
tls_type = TLS_TLS | TLS_GD;
goto dogottls;
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_HI:
case R_PPC64_GOT_TPREL16_HA:
- case R_PPC64_GOT_TPREL34:
+ case R_PPC64_GOT_TPREL_PCREL34:
if (bfd_link_dll (info))
info->flags |= DF_STATIC_TLS;
tls_type = TLS_TLS | TLS_TPREL;
case R_PPC64_GOT_DTPREL16_LO_DS:
case R_PPC64_GOT_DTPREL16_HI:
case R_PPC64_GOT_DTPREL16_HA:
- case R_PPC64_GOT_DTPREL34:
+ case R_PPC64_GOT_DTPREL_PCREL34:
tls_type = TLS_TLS | TLS_DTPREL;
dogottls:
sec->has_tls_reloc = 1;
if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
rel->r_addend, tls_type))
return FALSE;
-
- /* We may also need a plt entry if the symbol turns out to be
- an ifunc. */
- if (h != NULL && !bfd_link_pic (info) && abiversion (abfd) != 1)
- {
- if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
- return FALSE;
- }
break;
case R_PPC64_PLT16_HA:
struct elf_dyn_relocs *p;
struct elf_dyn_relocs **head;
- head = &ppc_elf_hash_entry (h)->dyn_relocs;
+ head = &h->dyn_relocs;
p = *head;
if (p == NULL || p->sec != sec)
{
return TRUE;
}
-/* Find dynamic relocs for H that apply to read-only sections. */
-
-static asection *
-readonly_dynrelocs (struct elf_link_hash_entry *h)
-{
- struct ppc_link_hash_entry *eh = ppc_elf_hash_entry (h);
- struct elf_dyn_relocs *p;
-
- for (p = eh->dyn_relocs; p != NULL; p = p->next)
- {
- asection *s = p->sec->output_section;
-
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
- return p->sec;
- }
- return NULL;
-}
-
/* Return true if we have dynamic relocs against H or any of its weak
aliases, that apply to read-only sections. Cannot be used after
size_dynamic_sections. */
struct ppc_link_hash_entry *eh = ppc_elf_hash_entry (h);
do
{
- if (readonly_dynrelocs (&eh->elf))
+ if (_bfd_elf_readonly_dynrelocs (&eh->elf))
return TRUE;
eh = ppc_elf_hash_entry (eh->elf.u.alias);
}
{
struct elf_dyn_relocs *p;
- for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ for (p = eh->elf.dyn_relocs; p != NULL; p = p->next)
if (p->pc_count != 0)
return TRUE;
return FALSE;
if (!bfd_link_pic (info)
&& h->type != STT_GNU_IFUNC
&& local)
- ppc_elf_hash_entry (h)->dyn_relocs = NULL;
+ h->dyn_relocs = NULL;
/* Clear procedure linkage table information for any symbol that
won't need a .plt entry. */
extra work in ld.so when resolving these symbols. */
if (global_entry_stub (h))
{
- if (!readonly_dynrelocs (h))
+ if (!_bfd_elf_readonly_dynrelocs (h))
{
h->pointer_equality_needed = 0;
/* If we haven't seen a branch reloc and the symbol
else if (!bfd_link_pic (info))
/* We are going to be defining the function symbol on the
plt stub, so no dyn_relocs needed when non-pic. */
- ppc_elf_hash_entry (h)->dyn_relocs = NULL;
+ h->dyn_relocs = NULL;
}
/* ELFv2 function symbols can't have copy relocs. */
return TRUE;
}
else if (!h->needs_plt
- && !readonly_dynrelocs (h))
+ && !_bfd_elf_readonly_dynrelocs (h))
{
/* If we haven't seen a branch reloc and the symbol isn't an
ifunc then we don't need a plt entry. */
h->root.u.def.value = def->root.u.def.value;
if (def->root.u.def.section == htab->elf.sdynbss
|| def->root.u.def.section == htab->elf.sdynrelro)
- ppc_elf_hash_entry (h)->dyn_relocs = NULL;
+ h->dyn_relocs = NULL;
return TRUE;
}
}
/* We no longer want dyn_relocs. */
- ppc_elf_hash_entry (h)->dyn_relocs = NULL;
+ h->dyn_relocs = NULL;
return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
{
struct elf_dyn_relocs *p;
struct elf_dyn_relocs **pp;
- pp = &ppc_elf_hash_entry (h)->dyn_relocs;
+ pp = &h->dyn_relocs;
/* elf_gc_sweep may have already removed all dyn relocs associated
with local syms for a given section. Also, symbol flags are
bfd_byte *loc;
if (!bfd_malloc_and_get_section (ibfd, sec, &loc))
{
- if (loc != NULL)
- free (loc);
+ free (loc);
error_ret:
- if (local_syms != NULL
- && symtab_hdr->contents != (unsigned char *) local_syms)
+ if (symtab_hdr->contents != (unsigned char *) local_syms)
free (local_syms);
if (elf_section_data (sec)->relocs != relstart)
free (relstart);
{
if (elf_section_data (sec)->relocs != relstart)
free (relstart);
- if (local_syms != NULL
- && symtab_hdr->contents != (bfd_byte *) local_syms)
+ if (symtab_hdr->contents != (bfd_byte *) local_syms)
free (local_syms);
return FALSE;
}
err_free_rel:
if (elf_section_data (sec)->relocs != relstart)
free (relstart);
- if (toc_ref != NULL)
- free (toc_ref);
- if (locsyms != NULL
- && (elf_symtab_hdr (ibfd).contents
- != (unsigned char *) locsyms))
+ free (toc_ref);
+ if (elf_symtab_hdr (ibfd).contents
+ != (unsigned char *) locsyms)
free (locsyms);
return ret;
}
{
case R_PPC64_GOT_TLSLD16:
case R_PPC64_GOT_TLSLD16_LO:
- case R_PPC64_GOT_TLSLD34:
+ case R_PPC64_GOT_TLSLD_PCREL34:
expecting_tls_get_addr = 1;
found_tls_get_addr_arg = 1;
/* Fall through. */
case R_PPC64_GOT_TLSGD16:
case R_PPC64_GOT_TLSGD16_LO:
- case R_PPC64_GOT_TLSGD34:
+ case R_PPC64_GOT_TLSGD_PCREL34:
expecting_tls_get_addr = 1;
found_tls_get_addr_arg = 1;
/* Fall through. */
tls_type = TLS_TLS | TLS_GD;
break;
- case R_PPC64_GOT_TPREL34:
+ case R_PPC64_GOT_TPREL_PCREL34:
case R_PPC64_GOT_TPREL16_DS:
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_HI:
}
}
- if (toc_ref != NULL)
- free (toc_ref);
+ free (toc_ref);
htab->do_tls_opt = 1;
return TRUE;
}
off = insn2 & 0xffff;
break;
+ case 6: /* lxvp, stxvp */
+ if ((insn2 & 0xe) != 0)
+ return FALSE;
+ insn1 = ((1ULL << 58) | (1ULL << 52)
+ | ((insn2 & 1) == 0 ? 58ULL << 26 : 62ULL << 26)
+ | (insn2 & (31ULL << 21)));
+ off = insn2 & 0xfff0;
+ break;
+
case 62: /* std, stq */
if ((insn2 & 1) != 0)
return FALSE;
if (used == NULL)
{
error_ret:
- if (local_syms != NULL
- && symtab_hdr->contents != (unsigned char *) local_syms)
+ if (symtab_hdr->contents != (unsigned char *) local_syms)
free (local_syms);
if (sec != NULL
- && relstart != NULL
&& elf_section_data (sec)->relocs != relstart)
free (relstart);
- if (toc_relocs != NULL
- && elf_section_data (toc)->relocs != toc_relocs)
+ if (elf_section_data (toc)->relocs != toc_relocs)
free (toc_relocs);
- if (skip != NULL)
- free (skip);
+ free (skip);
return FALSE;
}
rel_hdr->sh_size = toc->reloc_count * sz;
}
}
- else if (toc_relocs != NULL
- && elf_section_data (toc)->relocs != toc_relocs)
+ else if (elf_section_data (toc)->relocs != toc_relocs)
free (toc_relocs);
if (local_syms != NULL
if (relstart == NULL)
{
got_error_ret:
- if (local_syms != NULL
- && symtab_hdr->contents != (unsigned char *) local_syms)
+ if (symtab_hdr->contents != (unsigned char *) local_syms)
free (local_syms);
if (sec != NULL
- && relstart != NULL
&& elf_section_data (sec)->relocs != relstart)
free (relstart);
return FALSE;
|| discarded_section (sym_sec))
continue;
+ if ((h ? h->type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ continue;
+
if (!SYMBOL_REFERENCES_LOCAL (info, h))
continue;
IFUNCs which are handled even in static executables. */
if (!htab->elf.dynamic_sections_created
&& h->type != STT_GNU_IFUNC)
- eh->dyn_relocs = NULL;
+ h->dyn_relocs = NULL;
/* Discard relocs on undefined symbols that must be local. */
else if (h->root.type == bfd_link_hash_undefined
&& ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
- eh->dyn_relocs = NULL;
+ h->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;
+ h->dyn_relocs = NULL;
- if (eh->dyn_relocs != NULL)
+ if (h->dyn_relocs != NULL)
{
struct elf_dyn_relocs *p, **pp;
avoid writing weird assembly. */
if (SYMBOL_CALLS_LOCAL (info, h))
{
- for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
{
p->count -= p->pc_count;
p->pc_count = 0;
}
}
- if (eh->dyn_relocs != NULL)
+ if (h->dyn_relocs != NULL)
{
/* Ensure we catch all the cases where this symbol
should be made dynamic. */
/* But if that didn't work out, discard dynamic relocs. */
if (h->dynindx == -1)
- eh->dyn_relocs = NULL;
+ h->dyn_relocs = NULL;
}
else
- eh->dyn_relocs = NULL;
+ h->dyn_relocs = NULL;
}
/* Finally, allocate space. */
- for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ for (p = h->dyn_relocs; p != NULL; p = p->next)
{
asection *sreloc = elf_section_data (p->sec)->sreloc;
if (eh->elf.type == STT_GNU_IFUNC)
return TRUE;
}
-/* Set DF_TEXTREL if we find any dynamic relocs that apply to
- read-only sections. */
-
-static bfd_boolean
-maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
-{
- asection *sec;
-
- if (h->root.type == bfd_link_hash_indirect)
- return TRUE;
-
- sec = readonly_dynrelocs (h);
- if (sec != NULL)
- {
- struct bfd_link_info *info = (struct bfd_link_info *) inf;
-
- info->flags |= DF_TEXTREL;
- info->callbacks->minfo (_("%pB: dynamic relocation against `%pT'"
- " in read-only section `%pA'\n"),
- sec->owner, h->root.root.string, sec);
-
- /* Not an error, just cut short the traversal. */
- return FALSE;
- }
- return TRUE;
-}
-
/* Set the sizes of the dynamic sections. */
static bfd_boolean
/* If any dynamic relocs apply to a read-only section,
then we need a DT_TEXTREL entry. */
if ((info->flags & DF_TEXTREL) == 0)
- elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
+ elf_link_hash_traverse (&htab->elf,
+ _bfd_elf_maybe_set_textrel, info);
if ((info->flags & DF_TEXTREL) != 0)
{
}
static bfd_byte *
-build_powerxx_offset (bfd *abfd, bfd_byte *p, bfd_vma off, int odd,
+build_power10_offset (bfd *abfd, bfd_byte *p, bfd_vma off, int odd,
bfd_boolean load)
{
uint64_t insn;
}
static unsigned int
-size_powerxx_offset (bfd_vma off, int odd)
+size_power10_offset (bfd_vma off, int odd)
{
if (off - odd + (1ULL << 33) < 1ULL << 34)
return odd + 8;
}
static unsigned int
-num_relocs_for_powerxx_offset (bfd_vma off, int odd)
+num_relocs_for_power10_offset (bfd_vma off, int odd)
{
if (off - odd + (1ULL << 33) < 1ULL << 34)
return 1;
}
static Elf_Internal_Rela *
-emit_relocs_for_powerxx_offset (struct bfd_link_info *info,
+emit_relocs_for_power10_offset (struct bfd_link_info *info,
Elf_Internal_Rela *r, bfd_vma roff,
bfd_vma targ, bfd_vma off, int odd)
{
if (stub_entry->stub_type >= ppc_stub_plt_call_notoc)
{
- if (htab->powerxx_stubs)
+ if (htab->power10_stubs)
{
bfd_vma start = (stub_entry->stub_offset
+ stub_entry->group->stub_sec->output_offset
+ stub_entry->group->stub_sec->output_section->vma);
if (stub_entry->stub_type > ppc_stub_plt_call_notoc)
start += 4;
- size = 8 + size_powerxx_offset (off, start & 4);
+ size = 8 + size_power10_offset (off, start & 4);
}
else
size = 8 + size_offset (off - 8);
relp = p;
num_rel = 0;
- if (htab->powerxx_stubs)
+ if (htab->power10_stubs)
{
bfd_boolean load = stub_entry->stub_type >= ppc_stub_plt_call_notoc;
- p = build_powerxx_offset (htab->params->stub_bfd, p, off, odd, load);
+ p = build_power10_offset (htab->params->stub_bfd, p, off, odd, load);
}
else
{
if (info->emitrelocations)
{
bfd_vma roff = relp - stub_entry->group->stub_sec->contents;
- if (htab->powerxx_stubs)
- num_rel += num_relocs_for_powerxx_offset (off, odd);
+ if (htab->power10_stubs)
+ num_rel += num_relocs_for_power10_offset (off, odd);
else
{
num_rel += num_relocs_for_offset (off);
r = get_relocs (stub_entry->group->stub_sec, num_rel);
if (r == NULL)
return FALSE;
- if (htab->powerxx_stubs)
- r = emit_relocs_for_powerxx_offset (info, r, roff, targ, off, odd);
+ if (htab->power10_stubs)
+ r = emit_relocs_for_power10_offset (info, r, roff, targ, off, odd);
else
r = emit_relocs_for_offset (info, r, roff, targ, off);
if (stub_entry->stub_type == ppc_stub_long_branch_notoc
}
}
- if (!htab->powerxx_stubs
+ if (!htab->power10_stubs
&& htab->glink_eh_frame != NULL
&& htab->glink_eh_frame->size != 0)
{
if (info->emitrelocations)
{
unsigned int num_rel;
- if (htab->powerxx_stubs)
- num_rel = num_relocs_for_powerxx_offset (off, odd);
+ if (htab->power10_stubs)
+ num_rel = num_relocs_for_power10_offset (off, odd);
else
num_rel = num_relocs_for_offset (off - 8);
stub_entry->group->stub_sec->reloc_count += num_rel;
stub_entry->group->stub_sec->flags |= SEC_RELOC;
}
- if (htab->powerxx_stubs)
- extra = size_powerxx_offset (off, odd);
+ if (htab->power10_stubs)
+ extra = size_power10_offset (off, odd);
else
extra = size_offset (off - 8);
/* Include branch insn plus those in the offset sequence. */
calculated. */
off -= extra;
- if (!htab->powerxx_stubs)
+ if (!htab->power10_stubs)
{
/* After the bcl, lr has been modified so we need to emit
.eh_frame info saying the return address is in r12. */
if (info->emitrelocations)
{
unsigned int num_rel;
- if (htab->powerxx_stubs)
- num_rel = num_relocs_for_powerxx_offset (off, odd);
+ if (htab->power10_stubs)
+ num_rel = num_relocs_for_power10_offset (off, odd);
else
num_rel = num_relocs_for_offset (off - 8);
stub_entry->group->stub_sec->reloc_count += num_rel;
size = plt_stub_size (htab, stub_entry, off);
- if (!htab->powerxx_stubs)
+ if (!htab->power10_stubs)
{
/* After the bcl, lr has been modified so we need to emit
.eh_frame info saying the return address is in r12. */
}
}
- if (local_syms != NULL
- && (elf_symtab_hdr (isec->owner).contents
- != (unsigned char *) local_syms))
+ if (elf_symtab_hdr (isec->owner).contents
+ != (unsigned char *) local_syms)
free (local_syms);
if (elf_section_data (isec)->relocs != relstart)
free (relstart);
if (elf_section_data (section)->relocs == NULL)
free (internal_relocs);
error_ret_free_local:
- if (local_syms != NULL
- && (symtab_hdr->contents
- != (unsigned char *) local_syms))
+ if (symtab_hdr->contents
+ != (unsigned char *) local_syms)
free (local_syms);
return FALSE;
}
}
maybe_strip_output (info, htab->brlt);
+ if (htab->relbrlt != NULL)
+ maybe_strip_output (info, htab->relbrlt);
if (htab->glink_eh_frame != NULL)
maybe_strip_output (info, htab->glink_eh_frame);
{
plt = htab->elf.iplt;
relplt = htab->elf.irelplt;
- htab->local_ifunc_resolver = 1;
+ htab->elf.ifunc_resolvers = TRUE;
if (htab->opd_abi)
rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
else
+ ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE (htab))
/ PLT_ENTRY_SIZE (htab) * sizeof (Elf64_External_Rela)));
if (h->type == STT_GNU_IFUNC && is_static_defined (h))
- htab->maybe_local_ifunc_resolver = 1;
+ htab->elf.ifunc_resolvers = TRUE;
bfd_elf64_swap_reloca_out (info->output_bfd, &rela, loc);
}
}
if (!get_sym_h (NULL, &sym, &sym_sec, NULL, &local_syms,
lplt - local_plt, ibfd))
{
- if (local_syms != NULL
- && symtab_hdr->contents != (unsigned char *) local_syms)
+ if (symtab_hdr->contents != (unsigned char *) local_syms)
free (local_syms);
return FALSE;
}
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
{
- htab->local_ifunc_resolver = 1;
+ htab->elf.ifunc_resolvers = TRUE;
plt = htab->elf.iplt;
relplt = htab->elf.irelplt;
}
}
break;
- case R_PPC64_GOT_TPREL34:
+ case R_PPC64_GOT_TPREL_PCREL34:
if ((tls_mask & TLS_TLS) != 0
&& (tls_mask & TLS_TPREL) == 0)
{
}
break;
- case R_PPC64_GOT_TLSGD34:
+ case R_PPC64_GOT_TLSGD_PCREL34:
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
{
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
{
/* IE, pla -> pld */
pinsn += (-2ULL << 56) + (57ULL << 26) - (14ULL << 26);
- r_type = R_PPC64_GOT_TPREL34;
+ r_type = R_PPC64_GOT_TPREL_PCREL34;
}
else
{
}
break;
- case R_PPC64_GOT_TLSLD34:
+ case R_PPC64_GOT_TLSLD_PCREL34:
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
{
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
break;
case R_PPC64_GOT16_DS:
+ if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x8000 < 0x10000
&& SYMBOL_REFERENCES_LOCAL (info, &h->elf))
case R_PPC64_GOT16_LO_DS:
case R_PPC64_GOT16_HA:
+ if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x80008000ULL < 0x100000000ULL
&& SYMBOL_REFERENCES_LOCAL (info, &h->elf))
break;
case R_PPC64_GOT_PCREL34:
+ if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ break;
from = (rel->r_offset
+ input_section->output_section->vma
+ input_section->output_offset);
case R_PPC64_GOT_TLSGD16_LO:
case R_PPC64_GOT_TLSGD16_HI:
case R_PPC64_GOT_TLSGD16_HA:
- case R_PPC64_GOT_TLSGD34:
+ case R_PPC64_GOT_TLSGD_PCREL34:
tls_type = TLS_TLS | TLS_GD;
goto dogot;
case R_PPC64_GOT_TLSLD16_LO:
case R_PPC64_GOT_TLSLD16_HI:
case R_PPC64_GOT_TLSLD16_HA:
- case R_PPC64_GOT_TLSLD34:
+ case R_PPC64_GOT_TLSLD_PCREL34:
tls_type = TLS_TLS | TLS_LD;
goto dogot;
case R_PPC64_GOT_TPREL16_LO_DS:
case R_PPC64_GOT_TPREL16_HI:
case R_PPC64_GOT_TPREL16_HA:
- case R_PPC64_GOT_TPREL34:
+ case R_PPC64_GOT_TPREL_PCREL34:
tls_type = TLS_TLS | TLS_TPREL;
goto dogot;
case R_PPC64_GOT_DTPREL16_LO_DS:
case R_PPC64_GOT_DTPREL16_HI:
case R_PPC64_GOT_DTPREL16_HA:
- case R_PPC64_GOT_DTPREL34:
+ case R_PPC64_GOT_DTPREL_PCREL34:
tls_type = TLS_TLS | TLS_DTPREL;
goto dogot;
if (ifunc)
{
relgot = htab->elf.irelplt;
- if (indx == 0)
- htab->local_ifunc_resolver = 1;
- else if (is_static_defined (&h->elf))
- htab->maybe_local_ifunc_resolver = 1;
+ if (indx == 0 || is_static_defined (&h->elf))
+ htab->elf.ifunc_resolvers = TRUE;
}
else if (indx != 0
|| (bfd_link_pic (info)
relocation = got->output_section->vma + got->output_offset + off;
addend = 0;
if (!(r_type == R_PPC64_GOT_PCREL34
- || r_type == R_PPC64_GOT_TLSGD34
- || r_type == R_PPC64_GOT_TLSLD34
- || r_type == R_PPC64_GOT_TPREL34
- || r_type == R_PPC64_GOT_DTPREL34))
+ || r_type == R_PPC64_GOT_TLSGD_PCREL34
+ || r_type == R_PPC64_GOT_TLSLD_PCREL34
+ || r_type == R_PPC64_GOT_TPREL_PCREL34
+ || r_type == R_PPC64_GOT_DTPREL_PCREL34))
addend = -(TOCstart + htab->sec_info[input_section->id].toc_off);
}
break;
if (bfd_link_pic (info)
? ((h == NULL
- || h->dyn_relocs != NULL)
+ || h->elf.dyn_relocs != NULL)
&& ((h != NULL && pc_dynrelocs (h))
|| must_be_dyn_reloc (info, r_type)))
: (h != NULL
- ? h->dyn_relocs != NULL
+ ? h->elf.dyn_relocs != NULL
: ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))
{
bfd_boolean skip, relocate;
: ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
{
sreloc = htab->elf.irelplt;
- if (indx == 0)
- htab->local_ifunc_resolver = 1;
- else if (is_static_defined (&h->elf))
- htab->maybe_local_ifunc_resolver = 1;
+ if (indx == 0 || is_static_defined (&h->elf))
+ htab->elf.ifunc_resolvers = TRUE;
}
if (sreloc == NULL)
abort ();
case R_PPC64_GOT_PCREL34:
case R_PPC64_TPREL34:
case R_PPC64_DTPREL34:
- case R_PPC64_GOT_TLSGD34:
- case R_PPC64_GOT_TLSLD34:
- case R_PPC64_GOT_TPREL34:
- case R_PPC64_GOT_DTPREL34:
+ case R_PPC64_GOT_TLSGD_PCREL34:
+ case R_PPC64_GOT_TLSLD_PCREL34:
+ case R_PPC64_GOT_TPREL_PCREL34:
+ case R_PPC64_GOT_DTPREL_PCREL34:
case R_PPC64_PLT_PCREL34:
case R_PPC64_PLT_PCREL34_NOTOC:
case R_PPC64_D28:
reloc_name, sym_name, (int) r);
ret = FALSE;
}
- if (more_info != NULL)
- free (more_info);
+ free (more_info);
}
copy_reloc:
if (wrel != rel)
break;
case DT_TEXTREL:
- if (htab->local_ifunc_resolver)
- info->callbacks->einfo
- (_("%X%P: text relocations and GNU indirect "
- "functions will result in a segfault at runtime\n"));
- else if (htab->maybe_local_ifunc_resolver)
+ if (htab->elf.ifunc_resolvers)
info->callbacks->einfo
(_("%P: warning: text relocations and GNU indirect "
"functions may result in a segfault at runtime\n"));