2014-03-12 Aldy Hernandez <aldyh@redhat.com>
Copy over bfd/elf64-ppc.c from upstream binutils-2_24-branch.
Additional supporting changes to get elf64-ppc.c to build (tests,
header files, etc).
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 4688ddd..34ad362 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -643,7 +643,8 @@ enum elf_reloc_type_class {
reloc_class_normal,
reloc_class_relative,
reloc_class_plt,
- reloc_class_copy
+ reloc_class_copy,
+ reloc_class_ifunc
};
struct elf_reloc_cookie
@@ -1130,7 +1131,7 @@ struct elf_backend_data
/* This function returns class of a reloc type. */
enum elf_reloc_type_class (*elf_backend_reloc_type_class)
- (const Elf_Internal_Rela *);
+ (const struct bfd_link_info *, const asection *, const Elf_Internal_Rela *);
/* This function, if defined, removes information about discarded functions
from other sections which mention them. */
@@ -1788,7 +1789,8 @@ extern bfd_boolean _bfd_elf_can_make_relative
(bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section);
extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
- (const Elf_Internal_Rela *);
+ (const struct bfd_link_info *, const asection *,
+ const Elf_Internal_Rela *);
extern bfd_vma _bfd_elf_rela_local_sym
(bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *);
extern bfd_vma _bfd_elf_rel_local_sym
@@ -2156,6 +2158,8 @@ extern bfd_boolean _bfd_elf_default_relocs_compatible
extern bfd_boolean _bfd_elf_relocs_compatible
(const bfd_target *, const bfd_target *);
+extern bfd_boolean _bfd_elf_notice_as_needed
+(bfd *, struct bfd_link_info *, enum notice_asneeded_action);
extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
(bfd *, struct bfd_link_info *, const char *);
diff --git a/bfd/elf.c b/bfd/elf.c
index dcbd50a..661fcc4 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9877,7 +9877,9 @@ bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
}
enum elf_reloc_type_class
-_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
+_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
{
return reloc_class_normal;
}
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index a3680f2..2082441 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -9349,8 +9349,15 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
}
static enum elf_reloc_type_class
-ppc_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+ppc_elf_reloc_type_class (const struct bfd_link_info *info,
+ const asection *rel_sec,
+ const Elf_Internal_Rela *rela)
{
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+
+ if (rel_sec == htab->reliplt)
+ return reloc_class_ifunc;
+
switch (ELF32_R_TYPE (rela->r_info))
{
case R_PPC_RELATIVE:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 80c2a4d..6ae78f3 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -97,7 +97,7 @@ static bfd_vma opd_entry_value
#define elf_backend_copy_indirect_symbol ppc64_elf_copy_indirect_symbol
#define elf_backend_add_symbol_hook ppc64_elf_add_symbol_hook
#define elf_backend_check_directives ppc64_elf_process_dot_syms
-#define elf_backend_as_needed_cleanup ppc64_elf_as_needed_cleanup
+#define elf_backend_notice_as_needed ppc64_elf_notice_as_needed
#define elf_backend_archive_symbol_lookup ppc64_elf_archive_symbol_lookup
#define elf_backend_check_relocs ppc64_elf_check_relocs
#define elf_backend_gc_keep ppc64_elf_gc_keep
@@ -134,7 +134,7 @@ static bfd_vma opd_entry_value
/* Offsets to some stack save slots. */
#define STK_LR 16
#define STK_TOC(htab) (htab->opd_abi ? 40 : 24)
-/* This one is dodgy. ABIv2 does not have a linker word, so use the
+/* This one is dodgy. ELFv2 does not have a linker word, so use the
CR save slot. Used only by optimised __tls_get_addr call stub,
relying on __tls_get_addr_opt not saving CR.. */
#define STK_LINKER(htab) (htab->opd_abi ? 32 : 8)
@@ -2592,7 +2592,7 @@ ppc64_elf_toc_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
if (TOCstart == 0)
- TOCstart = ppc64_elf_toc (input_section->output_section->owner);
+ TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
/* Subtract the TOC base address. */
reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
@@ -2615,7 +2615,7 @@ ppc64_elf_toc_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
if (TOCstart == 0)
- TOCstart = ppc64_elf_toc (input_section->output_section->owner);
+ TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
/* Subtract the TOC base address. */
reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
@@ -2642,7 +2642,7 @@ ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
if (TOCstart == 0)
- TOCstart = ppc64_elf_toc (input_section->output_section->owner);
+ TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
octets = reloc_entry->address * bfd_octets_per_byte (abfd);
bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
@@ -2735,8 +2735,13 @@ struct ppc64_elf_obj_tdata
sections means we potentially need one of these for each input bfd. */
struct got_entry tlsld_got;
- /* A copy of relocs before they are modified for --emit-relocs. */
- Elf_Internal_Rela *opd_relocs;
+ union {
+ /* A copy of relocs before they are modified for --emit-relocs. */
+ Elf_Internal_Rela *relocs;
+
+ /* Section contents. */
+ bfd_byte *contents;
+ } opd;
/* Nonzero if this bfd has small toc/got relocs, ie. that expect
the reloc to be in the range -32768 to 32767. */
@@ -3768,9 +3773,6 @@ struct ppc_stub_hash_entry {
struct ppc_link_hash_entry *h;
struct plt_entry *plt_ent;
- /* And the reloc addend that this was derived from. */
- bfd_vma addend;
-
/* Where this stub is being called from, or, in the case of combined
stub sections, the first input section in the group. */
asection *id_sec;
@@ -3791,6 +3793,21 @@ struct ppc_branch_hash_entry {
unsigned int iter;
};
+/* Used to track dynamic relocations for local symbols. */
+struct ppc_dyn_relocs
+{
+ struct ppc_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ unsigned int count : 31;
+
+ /* Whether this entry is for STT_GNU_IFUNC symbols. */
+ unsigned int ifunc : 1;
+};
+
struct ppc_link_hash_entry
{
struct elf_link_hash_entry elf;
@@ -3892,12 +3909,7 @@ struct ppc_link_hash_table
/* List of input sections for each output section. */
asection **input_list;
- /* Short-cuts to get to dynamic linker sections. */
- asection *got;
- asection *plt;
- asection *relplt;
- asection *iplt;
- asection *reliplt;
+ /* Shortcuts to get to dynamic linker sections. */
asection *dynbss;
asection *relbss;
asection *glink;
@@ -3910,9 +3922,6 @@ struct ppc_link_hash_table
struct ppc_link_hash_entry *tls_get_addr;
struct ppc_link_hash_entry *tls_get_addr_fd;
- /* The special .TOC. symbol. */
- struct ppc_link_hash_entry *dot_toc_dot;
-
/* The size of reliplt used by got entry relocs. */
bfd_size_type got_reli_size;
@@ -4204,9 +4213,85 @@ ppc64_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
_bfd_elf_link_hash_table_free (hash);
}
+/* Create sections for linker generated code. */
+
+static bfd_boolean
+create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+ flagword flags;
+
+ htab = ppc_hash_table (info);
+
+ /* Create .sfpr for code to save and restore fp regs. */
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->sfpr = bfd_make_section_anyway_with_flags (dynobj, ".sfpr",
+ flags);
+ if (htab->sfpr == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
+ return FALSE;
+
+ /* Create .glink for lazy dynamic linking support. */
+ htab->glink = bfd_make_section_anyway_with_flags (dynobj, ".glink",
+ flags);
+ if (htab->glink == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
+ return FALSE;
+
+ if (!info->no_ld_generated_unwind_info)
+ {
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->glink_eh_frame = bfd_make_section_anyway_with_flags (dynobj,
+ ".eh_frame",
+ flags);
+ if (htab->glink_eh_frame == NULL
+ || !bfd_set_section_alignment (dynobj, htab->glink_eh_frame, 2))
+ return FALSE;
+ }
+
+ flags = SEC_ALLOC | SEC_LINKER_CREATED;
+ htab->elf.iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
+ if (htab->elf.iplt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->elf.iplt, 3))
+ return FALSE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->elf.irelplt
+ = bfd_make_section_anyway_with_flags (dynobj, ".rela.iplt", flags);
+ if (htab->elf.irelplt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->elf.irelplt, 3))
+ return FALSE;
+
+ /* Create branch lookup table for plt_branch stubs. */
+ flags = (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->brlt = bfd_make_section_anyway_with_flags (dynobj, ".branch_lt",
+ flags);
+ if (htab->brlt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->brlt, 3))
+ return FALSE;
+
+ if (!info->shared)
+ return TRUE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->relbrlt = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.branch_lt",
+ flags);
+ if (htab->relbrlt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->relbrlt, 3))
+ return FALSE;
+
+ return TRUE;
+}
+
/* Satisfy the ELF linker by filling in some fields in our fake bfd. */
-void
+bfd_boolean
ppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
{
struct ppc_link_hash_table *htab;
@@ -4218,9 +4303,14 @@ ppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
the start of the output TOC section. */
htab = ppc_hash_table (info);
if (htab == NULL)
- return;
+ return FALSE;
htab->stub_bfd = abfd;
htab->elf.dynobj = abfd;
+
+ if (info->relocatable)
+ return TRUE;
+
+ return create_linkage_sections (htab->elf.dynobj, info);
}
/* Build a name for an entry in the stub hash table. */
@@ -4370,85 +4460,6 @@ ppc_add_stub (const char *stub_name,
return stub_entry;
}
-/* Create sections for linker generated code. */
-
-static bfd_boolean
-create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
-{
- struct ppc_link_hash_table *htab;
- flagword flags;
-
- htab = ppc_hash_table (info);
- if (htab == NULL)
- return FALSE;
-
- /* Create .sfpr for code to save and restore fp regs. */
- flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
- | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
- htab->sfpr = bfd_make_section_anyway_with_flags (dynobj, ".sfpr",
- flags);
- if (htab->sfpr == NULL
- || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
- return FALSE;
-
- /* Create .glink for lazy dynamic linking support. */
- htab->glink = bfd_make_section_anyway_with_flags (dynobj, ".glink",
- flags);
- if (htab->glink == NULL
- || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
- return FALSE;
-
- if (!info->no_ld_generated_unwind_info)
- {
- flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY | SEC_LINKER_CREATED);
- htab->glink_eh_frame = bfd_make_section_anyway_with_flags (dynobj,
- ".eh_frame",
- flags);
- if (htab->glink_eh_frame == NULL
- || !bfd_set_section_alignment (dynobj, htab->glink_eh_frame, 2))
- return FALSE;
- }
-
- flags = SEC_ALLOC | SEC_LINKER_CREATED;
- htab->iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
- if (htab->iplt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->iplt, 3))
- return FALSE;
-
- flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
- | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
- htab->reliplt = bfd_make_section_anyway_with_flags (dynobj,
- ".rela.iplt",
- flags);
- if (htab->reliplt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->reliplt, 3))
- return FALSE;
-
- /* Create branch lookup table for plt_branch stubs. */
- flags = (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
- htab->brlt = bfd_make_section_anyway_with_flags (dynobj, ".branch_lt",
- flags);
- if (htab->brlt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->brlt, 3))
- return FALSE;
-
- if (!info->shared)
- return TRUE;
-
- flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
- | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
- htab->relbrlt = bfd_make_section_anyway_with_flags (dynobj,
- ".rela.branch_lt",
- flags);
- if (htab->relbrlt == NULL
- || ! bfd_set_section_alignment (dynobj, htab->relbrlt, 3))
- return FALSE;
-
- return TRUE;
-}
-
/* Create .got and .rela.got sections in ABFD, and .got in dynobj if
not already done. */
@@ -4464,15 +4475,9 @@ create_got_section (bfd *abfd, struct bfd_link_info *info)
if (htab == NULL)
return FALSE;
- if (!htab->got)
- {
- if (! _bfd_elf_create_got_section (htab->elf.dynobj, info))
- return FALSE;
-
- htab->got = bfd_get_linker_section (htab->elf.dynobj, ".got");
- if (!htab->got)
- abort ();
- }
+ if (!htab->elf.sgot
+ && !_bfd_elf_create_got_section (htab->elf.dynobj, info))
+ return FALSE;
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
@@ -4507,15 +4512,11 @@ ppc64_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
if (htab == NULL)
return FALSE;
- if (!htab->got)
- htab->got = bfd_get_linker_section (dynobj, ".got");
- htab->plt = bfd_get_linker_section (dynobj, ".plt");
- htab->relplt = bfd_get_linker_section (dynobj, ".rela.plt");
htab->dynbss = bfd_get_linker_section (dynobj, ".dynbss");
if (!info->shared)
htab->relbss = bfd_get_linker_section (dynobj, ".rela.bss");
- if (!htab->got || !htab->plt || !htab->relplt || !htab->dynbss
+ if (!htab->elf.sgot || !htab->elf.splt || !htab->elf.srelplt || !htab->dynbss
|| (!info->shared && !htab->relbss))
abort ();
@@ -4941,7 +4942,12 @@ ppc64_elf_process_dot_syms (bfd *ibfd, struct bfd_link_info *info)
while ((eh = *p) != NULL)
{
*p = NULL;
- if (!add_symbol_adjust (eh, info))
+ if (&eh->elf == htab->elf.hgot)
+ ;
+ else if (htab->elf.hgot == NULL
+ && strcmp (eh->elf.root.root.string, ".TOC.") == 0)
+ htab->elf.hgot = &eh->elf;
+ else if (!add_symbol_adjust (eh, info))
return FALSE;
p = &eh->u.next_dot_sym;
}
@@ -4968,17 +4974,22 @@ ppc64_elf_process_dot_syms (bfd *ibfd, struct bfd_link_info *info)
/* Undo hash table changes when an --as-needed input file is determined
not to be needed. */
+__attribute__((unused))
static bfd_boolean
-ppc64_elf_as_needed_cleanup (bfd *ibfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info)
+ppc64_elf_notice_as_needed (bfd *ibfd,
+ struct bfd_link_info *info,
+ enum notice_asneeded_action act)
{
- struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ if (act == notice_not_needed)
+ {
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
- if (htab == NULL)
- return FALSE;
+ if (htab == NULL)
+ return FALSE;
- htab->dot_syms = NULL;
- return TRUE;
+ htab->dot_syms = NULL;
+ }
+ return _bfd_elf_notice_as_needed (ibfd, info, act);
}
/* If --just-symbols against a final linked binary, then assume we need
@@ -4991,10 +5002,8 @@ ppc64_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
&& (sec->owner->flags & (EXEC_P | DYNAMIC)) != 0
&& is_ppc64_elf (sec->owner))
{
- asection *got = bfd_get_section_by_name (sec->owner, ".got");
- if (got != NULL
- && got->size >= elf_backend_got_header_size
- && bfd_get_section_by_name (sec->owner, ".opd") != NULL)
+ if (abiversion (sec->owner) >= 2
+ || bfd_get_section_by_name (sec->owner, ".opd") != NULL)
sec->has_toc_reloc = 1;
}
_bfd_elf_link_just_syms (sec, info);
@@ -5162,10 +5171,6 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
ppc64_elf_section_data (sec)->sec_type = sec_opd;
}
- if (htab->sfpr == NULL
- && !create_linkage_sections (htab->elf.dynobj, info))
- return FALSE;
-
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
@@ -5183,6 +5188,13 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
h = elf_follow_link (h);
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+
+ if (h == htab->elf.hgot)
+ sec->has_toc_reloc = 1;
}
tls_type = 0;
@@ -5656,7 +5668,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if ((info->shared
&& (must_be_dyn_reloc (info, r_type)
|| (h != NULL
- && (! info->symbolic
+ && (!SYMBOLIC_BIND (info, h)
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (ELIMINATE_COPY_RELOCS
@@ -5667,9 +5679,6 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|| (!info->shared
&& ifunc != NULL))
{
- struct elf_dyn_relocs *p;
- struct elf_dyn_relocs **head;
-
/* We must copy these reloc types into the output file.
Create a reloc section in dynobj and make room for
this reloc. */
@@ -5686,13 +5695,34 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
relocations we need for this symbol. */
if (h != NULL)
{
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
head = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ p = bfd_alloc (htab->elf.dynobj, sizeof *p);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+ p->count += 1;
+ if (!must_be_dyn_reloc (info, r_type))
+ p->pc_count += 1;
}
else
{
/* Track dynamic relocs needed for local syms too.
We really need local syms available to do this
easily. Oh well. */
+ struct ppc_dyn_relocs *p;
+ struct ppc_dyn_relocs **head;
+ bfd_boolean is_ifunc;
asection *s;
void *vpp;
Elf_Internal_Sym *isym;
@@ -5707,25 +5737,24 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
s = sec;
vpp = &elf_section_data (s)->local_dynrel;
- head = (struct elf_dyn_relocs **) vpp;
- }
-
- p = *head;
- if (p == NULL || p->sec != sec)
- {
- p = bfd_alloc (htab->elf.dynobj, sizeof *p);
- if (p == NULL)
- return FALSE;
- p->next = *head;
- *head = p;
- p->sec = sec;
- p->count = 0;
- p->pc_count = 0;
+ head = (struct ppc_dyn_relocs **) vpp;
+ is_ifunc = ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC;
+ p = *head;
+ if (p != NULL && p->sec == sec && p->ifunc != is_ifunc)
+ p = p->next;
+ if (p == NULL || p->sec != sec || p->ifunc != is_ifunc)
+ {
+ p = bfd_alloc (htab->elf.dynobj, sizeof *p);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->ifunc = is_ifunc;
+ p->count = 0;
+ }
+ p->count += 1;
}
-
- p->count += 1;
- if (!must_be_dyn_reloc (info, r_type))
- p->pc_count += 1;
}
break;
@@ -5828,12 +5857,16 @@ opd_entry_value (asection *opd_sec,
at a final linked executable with addr2line or somesuch. */
if (opd_sec->reloc_count == 0)
{
- char buf[8];
+ bfd_byte *contents = ppc64_elf_tdata (opd_bfd)->opd.contents;
- if (!bfd_get_section_contents (opd_bfd, opd_sec, buf, offset, 8))
- return (bfd_vma) -1;
+ if (contents == NULL)
+ {
+ if (!bfd_malloc_and_get_section (opd_bfd, opd_sec, &contents))
+ return (bfd_vma) -1;
+ ppc64_elf_tdata (opd_bfd)->opd.contents = contents;
+ }
- val = bfd_get_64 (opd_bfd, buf);
+ val = bfd_get_64 (opd_bfd, contents + offset);
if (code_sec != NULL)
{
asection *sec, *likely = NULL;
@@ -5865,7 +5898,7 @@ opd_entry_value (asection *opd_sec,
BFD_ASSERT (is_ppc64_elf (opd_bfd));
- relocs = ppc64_elf_tdata (opd_bfd)->opd_relocs;
+ relocs = ppc64_elf_tdata (opd_bfd)->opd.relocs;
if (relocs == NULL)
relocs = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, TRUE);
@@ -5921,11 +5954,30 @@ opd_entry_value (asection *opd_sec,
sym_hashes = elf_sym_hashes (opd_bfd);
rh = sym_hashes[symndx - symtab_hdr->sh_info];
- rh = elf_follow_link (rh);
- BFD_ASSERT (rh->root.type == bfd_link_hash_defined
- || rh->root.type == bfd_link_hash_defweak);
- val = rh->root.u.def.value;
- sec = rh->root.u.def.section;
+ if (rh != NULL)
+ {
+ rh = elf_follow_link (rh);
+ BFD_ASSERT (rh->root.type == bfd_link_hash_defined
+ || rh->root.type == bfd_link_hash_defweak);
+ val = rh->root.u.def.value;
+ sec = rh->root.u.def.section;
+ }
+ else
+ {
+ /* Handle the odd case where we can be called
+ during bfd_elf_link_add_symbols before the
+ symbol hashes have been fully populated. */
+ Elf_Internal_Sym *sym;
+
+ sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr, 1,
+ symndx, NULL, NULL, NULL);
+ if (sym == NULL)
+ break;
+
+ val = sym->st_value;
+ sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
+ free (sym);
+ }
}
val += look->r_addend;
if (code_off != NULL)
@@ -6782,6 +6834,21 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
if (htab == NULL)
return FALSE;
+ if (!info->relocatable
+ && htab->elf.hgot != NULL)
+ {
+ _bfd_elf_link_hash_hide_symbol (info, htab->elf.hgot, TRUE);
+ /* Make .TOC. defined so as to prevent it being made dynamic.
+ The wrong value here is fixed later in ppc64_elf_set_toc. */
+ htab->elf.hgot->type = STT_OBJECT;
+ htab->elf.hgot->root.type = bfd_link_hash_defined;
+ htab->elf.hgot->root.u.def.value = 0;
+ htab->elf.hgot->root.u.def.section = bfd_abs_section_ptr;
+ htab->elf.hgot->def_regular = 1;
+ htab->elf.hgot->other = ((htab->elf.hgot->other & ~ELF_ST_VISIBILITY (-1))
+ | STV_HIDDEN);
+ }
+
if (htab->sfpr == NULL)
/* We don't have any relocs. */
return TRUE;
@@ -7267,7 +7334,7 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
}
/* Handles decrementing dynamic reloc counts for the reloc specified by
- R_INFO in section SEC. If LOCAL_SYMS is NULL, then H and SYM_SEC
+ R_INFO in section SEC. If LOCAL_SYMS is NULL, then H and SYM
have already been determined. */
static bfd_boolean
@@ -7276,11 +7343,10 @@ dec_dynrel_count (bfd_vma r_info,
struct bfd_link_info *info,
Elf_Internal_Sym **local_syms,
struct elf_link_hash_entry *h,
- asection *sym_sec)
+ Elf_Internal_Sym *sym)
{
enum elf_ppc64_reloc_type r_type;
- struct elf_dyn_relocs *p;
- struct elf_dyn_relocs **pp;
+ asection *sym_sec = NULL;
/* Can this reloc be dynamic? This switch, and later tests here
should be kept in sync with the code in check_relocs. */
@@ -7339,7 +7405,6 @@ dec_dynrel_count (bfd_vma r_info,
if (local_syms != NULL)
{
unsigned long r_symndx;
- Elf_Internal_Sym *sym;
bfd *ibfd = sec->owner;
r_symndx = ELF64_R_SYM (r_info);
@@ -7350,7 +7415,7 @@ dec_dynrel_count (bfd_vma r_info,
if ((info->shared
&& (must_be_dyn_reloc (info, r_type)
|| (h != NULL
- && (!info->symbolic
+ && (!SYMBOLIC_BIND (info, h)
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (ELIMINATE_COPY_RELOCS
@@ -7363,40 +7428,62 @@ dec_dynrel_count (bfd_vma r_info,
return TRUE;
if (h != NULL)
- pp = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
- else
{
- if (sym_sec != NULL)
- {
- void *vpp = &elf_section_data (sym_sec)->local_dynrel;
- pp = (struct elf_dyn_relocs **) vpp;
- }
- else
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **pp;
+ pp = &((struct ppc_link_hash_entry *) 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
+ changed by elf_gc_sweep_symbol, confusing the test above. Don't
+ report a dynreloc miscount. */
+ if (*pp == NULL && info->gc_sections)
+ return TRUE;
+
+ while ((p = *pp) != NULL)
{
- void *vpp = &elf_section_data (sec)->local_dynrel;
- pp = (struct elf_dyn_relocs **) vpp;
+ if (p->sec == sec)
+ {
+ if (!must_be_dyn_reloc (info, r_type))
+ p->pc_count -= 1;
+ p->count -= 1;
+ if (p->count == 0)
+ *pp = p->next;
+ return TRUE;
+ }
+ pp = &p->next;
}
}
+ else
+ {
+ struct ppc_dyn_relocs *p;
+ struct ppc_dyn_relocs **pp;
+ void *vpp;
+ bfd_boolean is_ifunc;
- /* elf_gc_sweep may have already removed all dyn relocs associated
- with local syms for a given section. Also, symbol flags are
- changed by elf_gc_sweep_symbol, confusing the test above. Don't
- report a dynreloc miscount. */
- if (*pp == NULL && info->gc_sections)
- return TRUE;
+ if (local_syms == NULL)
+ sym_sec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+ if (sym_sec == NULL)
+ sym_sec = sec;
- while ((p = *pp) != NULL)
- {
- if (p->sec == sec)
+ vpp = &elf_section_data (sym_sec)->local_dynrel;
+ pp = (struct ppc_dyn_relocs **) vpp;
+
+ if (*pp == NULL && info->gc_sections)
+ return TRUE;
+
+ is_ifunc = ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC;
+ while ((p = *pp) != NULL)
{
- if (!must_be_dyn_reloc (info, r_type))
- p->pc_count -= 1;
- p->count -= 1;
- if (p->count == 0)
- *pp = p->next;
- return TRUE;
+ if (p->sec == sec && p->ifunc == is_ifunc)
+ {
+ p->count -= 1;
+ if (p->count == 0)
+ *pp = p->next;
+ return TRUE;
+ }
+ pp = &p->next;
}
- pp = &p->next;
}
info->callbacks->einfo (_("%P: dynreloc miscount for %B, section %A\n"),
@@ -7729,7 +7816,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
if (!NO_OPD_RELOCS
&& !info->relocatable
&& !dec_dynrel_count (rel->r_info, sec, info,
- NULL, h, sym_sec))
+ NULL, h, sym))
goto error_ret;
}
else
@@ -8339,13 +8426,13 @@ ppc64_elf_tls_optimize (struct bfd_link_info *info)
/* If we got rid of a DTPMOD/DTPREL reloc pair then
we'll lose one or two dyn relocs. */
if (!dec_dynrel_count (rel->r_info, sec, info,
- NULL, h, sym_sec))
+ NULL, h, sym))
return FALSE;
if (tls_set == (TLS_EXPLICIT | TLS_GD))
{
if (!dec_dynrel_count ((rel + 1)->r_info, sec, info,
- NULL, h, sym_sec))
+ NULL, h, sym))
return FALSE;
}
}
@@ -9137,19 +9224,18 @@ allocate_got (struct elf_link_hash_entry *h,
got->size += entsize;
dyn = htab->elf.dynamic_sections_created;
- if ((info->shared
- || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
- && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- || h->root.type != bfd_link_hash_undefweak))
+ if (h->type == STT_GNU_IFUNC)
{
- asection *relgot = ppc64_elf_tdata (gent->owner)->relgot;
- relgot->size += rentsize;
+ htab->elf.irelplt->size += rentsize;
+ htab->got_reli_size += rentsize;
}
- else if (h->type == STT_GNU_IFUNC)
+ else if ((info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
{
- asection *relgot = htab->reliplt;
+ asection *relgot = ppc64_elf_tdata (gent->owner)->relgot;
relgot->size += rentsize;
- htab->got_reli_size += rentsize;
}
}
@@ -9207,16 +9293,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (!htab->elf.dynamic_sections_created
|| h->dynindx == -1)
{
- s = htab->iplt;
+ s = htab->elf.iplt;
pent->plt.offset = s->size;
s->size += PLT_ENTRY_SIZE (htab);
- s = htab->reliplt;
+ s = htab->elf.irelplt;
}
else
{
/* If this is the first .plt entry, make room for the special
first entry. */
- s = htab->plt;
+ s = htab->elf.splt;
if (s->size == 0)
s->size += PLT_INITIAL_ENTRY_SIZE (htab);
@@ -9240,7 +9326,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
s->size += 4;
/* We also need to make an entry in the .rela.plt section. */
- s = htab->relplt;
+ s = htab->elf.srelplt;
}
s->size += sizeof (Elf64_External_Rela);
doneone = TRUE;
@@ -9330,8 +9416,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (eh->dyn_relocs == NULL
|| (!htab->elf.dynamic_sections_created
- && (h->type != STT_GNU_IFUNC
- || !htab->opd_abi)))
+ && h->type != STT_GNU_IFUNC))
return TRUE;
/* In the shared -Bsymbolic case, discard space allocated for
@@ -9419,8 +9504,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
asection *sreloc = elf_section_data (p->sec)->sreloc;
- if (!htab->elf.dynamic_sections_created)
- sreloc = htab->reliplt;
+ if (eh->elf.type == STT_GNU_IFUNC)
+ sreloc = htab->elf.irelplt;
sreloc->size += p->count * sizeof (Elf64_External_Rela);
}
@@ -9535,14 +9620,13 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
unsigned char *lgot_masks;
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
- asection *srel;
if (!is_ppc64_elf (ibfd))
continue;
for (s = ibfd->sections; s != NULL; s = s->next)
{
- struct elf_dyn_relocs *p;
+ struct ppc_dyn_relocs *p;
for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
{
@@ -9556,9 +9640,9 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
}
else if (p->count != 0)
{
- srel = elf_section_data (p->sec)->sreloc;
- if (!htab->elf.dynamic_sections_created)
- srel = htab->reliplt;
+ asection *srel = elf_section_data (p->sec)->sreloc;
+ if (p->ifunc)
+ srel = htab->elf.irelplt;
srel->size += p->count * sizeof (Elf64_External_Rela);
if ((p->sec->output_section->flags & SEC_READONLY) != 0)
info->flags |= DF_TEXTREL;
@@ -9577,7 +9661,6 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
end_local_plt = local_plt + locsymcount;
lgot_masks = (unsigned char *) end_local_plt;
s = ppc64_elf_tdata (ibfd)->got;
- srel = ppc64_elf_tdata (ibfd)->relgot;
for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
{
struct got_entry **pent, *ent;
@@ -9593,19 +9676,25 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
}
else
{
- unsigned int num = 1;
+ unsigned int ent_size = 8;
+ unsigned int rel_size = sizeof (Elf64_External_Rela);
+
ent->got.offset = s->size;
if ((ent->tls_type & *lgot_masks & TLS_GD) != 0)
- num = 2;
- s->size += num * 8;
- if (info->shared)
- srel->size += num * sizeof (Elf64_External_Rela);
- else if ((*lgot_masks & PLT_IFUNC) != 0)
{
- htab->reliplt->size
- += num * sizeof (Elf64_External_Rela);
- htab->got_reli_size
- += num * sizeof (Elf64_External_Rela);
+ ent_size *= 2;
+ rel_size *= 2;
+ }
+ s->size += ent_size;
+ if ((*lgot_masks & PLT_IFUNC) != 0)
+ {
+ htab->elf.irelplt->size += rel_size;
+ htab->got_reli_size += rel_size;
+ }
+ else if (info->shared)
+ {
+ asection *srel = ppc64_elf_tdata (ibfd)->relgot;
+ srel->size += rel_size;
}
pent = &ent->next;
}
@@ -9622,11 +9711,11 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
for (ent = *local_plt; ent != NULL; ent = ent->next)
if (ent->plt.refcount > 0)
{
- s = htab->iplt;
+ s = htab->elf.iplt;
ent->plt.offset = s->size;
s->size += PLT_ENTRY_SIZE (htab);
- htab->reliplt->size += sizeof (Elf64_External_Rela);
+ htab->elf.irelplt->size += sizeof (Elf64_External_Rela);
}
else
ent->plt.offset = (bfd_vma) -1;
@@ -9689,9 +9778,9 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
if (s == htab->brlt || s == htab->relbrlt)
/* These haven't been allocated yet; don't strip. */
continue;
- else if (s == htab->got
- || s == htab->plt
- || s == htab->iplt
+ else if (s == htab->elf.sgot
+ || s == htab->elf.splt
+ || s == htab->elf.iplt
|| s == htab->glink
|| s == htab->dynbss)
{
@@ -9708,7 +9797,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
{
if (s->size != 0)
{
- if (s != htab->relplt)
+ if (s != htab->elf.srelplt)
relocs = TRUE;
/* We use the reloc_count field as a counter if we need
@@ -9758,7 +9847,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
continue;
s = ppc64_elf_tdata (ibfd)->got;
- if (s != NULL && s != htab->got)
+ if (s != NULL && s != htab->elf.sgot)
{
if (s->size == 0)
s->flags |= SEC_EXCLUDE;
@@ -9803,7 +9892,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
return FALSE;
}
- if (htab->plt != NULL && htab->plt->size != 0)
+ if (htab->elf.splt != NULL && htab->elf.splt->size != 0)
{
if (!add_dynamic_entry (DT_PLTGOT, 0)
|| !add_dynamic_entry (DT_PLTRELSZ, 0)
@@ -10509,8 +10598,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
r[0].r_offset = loc - stub_entry->stub_sec->contents;
if (bfd_big_endian (info->output_bfd))
r[0].r_offset += 2;
- if (stub_entry->stub_type == ppc_stub_plt_branch_r2off
- && htab->opd_abi)
+ if (stub_entry->stub_type == ppc_stub_plt_branch_r2off)
r[0].r_offset += 4;
r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
r[0].r_addend = dest;
@@ -10523,8 +10611,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
}
}
- if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
- || !htab->opd_abi)
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
{
if (PPC_HA (off) != 0)
{
@@ -10543,7 +10630,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
{
bfd_vma r2off = get_r2off (info, stub_entry);
- if (r2off == 0)
+ if (r2off == 0 && htab->opd_abi)
{
htab->stub_error = TRUE;
return FALSE;
@@ -10551,28 +10638,29 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
bfd_put_32 (htab->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
loc += 4;
- size = 20;
+ size = 16;
if (PPC_HA (off) != 0)
{
size += 4;
bfd_put_32 (htab->stub_bfd, ADDIS_R11_R2 | PPC_HA (off), loc);
loc += 4;
bfd_put_32 (htab->stub_bfd, LD_R12_0R11 | PPC_LO (off), loc);
- loc += 4;
}
else
- {
- bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
- loc += 4;
- }
+ bfd_put_32 (htab->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
if (PPC_HA (r2off) != 0)
{
size += 4;
+ loc += 4;
bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
+ }
+ if (PPC_LO (r2off) != 0)
+ {
+ size += 4;
loc += 4;
+ bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
}
- bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
}
loc += 4;
bfd_put_32 (htab->stub_bfd, MTCTR_R12, loc);
@@ -10605,11 +10693,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
if (dest >= (bfd_vma) -2)
abort ();
- plt = htab->plt;
+ plt = htab->elf.splt;
if (!htab->elf.dynamic_sections_created
|| stub_entry->h == NULL
|| stub_entry->h->elf.dynindx == -1)
- plt = htab->iplt;
+ plt = htab->elf.iplt;
dest += plt->output_offset + plt->output_section->vma;
@@ -10628,8 +10716,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+ stub_entry->target_section->output_offset
+ stub_entry->target_section->output_section->vma);
- rl = (htab->reliplt->contents
- + (htab->reliplt->reloc_count++
+ rl = (htab->elf.irelplt->contents
+ + (htab->elf.irelplt->reloc_count++
* sizeof (Elf64_External_Rela)));
bfd_elf64_swap_reloca_out (info->output_bfd, &rela, rl);
stub_entry->plt_ent->plt.offset |= 1;
@@ -10664,10 +10752,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
if (info->emitrelocations)
{
r = get_relocs (stub_entry->stub_sec,
- (2
- + (PPC_HA (off) != 0)
- + (htab->plt_static_chain
- && PPC_HA (off + 16) == PPC_HA (off))));
+ ((PPC_HA (off) != 0)
+ + (htab->opd_abi
+ ? 2 + (htab->plt_static_chain
+ && PPC_HA (off + 16) == PPC_HA (off))
+ : 1)));
if (r == NULL)
return FALSE;
r[0].r_offset = loc - stub_entry->stub_sec->contents;
@@ -10759,11 +10848,11 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
off = stub_entry->plt_ent->plt.offset & ~(bfd_vma) 1;
if (off >= (bfd_vma) -2)
abort ();
- plt = htab->plt;
+ plt = htab->elf.splt;
if (!htab->elf.dynamic_sections_created
|| stub_entry->h == NULL
|| stub_entry->h->elf.dynindx == -1)
- plt = htab->iplt;
+ plt = htab->elf.iplt;
off += (plt->output_offset
+ plt->output_section->vma
- elf_gp (plt->output_section->owner)
@@ -10866,8 +10955,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
stub_entry->stub_sec->flags |= SEC_RELOC;
}
- if (stub_entry->stub_type != ppc_stub_plt_branch_r2off
- || !htab->opd_abi)
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
{
size = 12;
if (PPC_HA (off) != 0)
@@ -10875,12 +10963,14 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
}
else
{
- size = 20;
+ size = 16;
if (PPC_HA (off) != 0)
size += 4;
if (PPC_HA (r2off) != 0)
size += 4;
+ if (PPC_LO (r2off) != 0)
+ size += 4;
}
}
else if (info->emitrelocations)
@@ -10917,9 +11007,6 @@ ppc64_elf_setup_section_lists
htab->add_stub_section = add_stub_section;
htab->layout_sections_again = layout_sections_again;
- if (htab->brlt == NULL)
- return 0;
-
/* Find the top input section id. */
for (input_bfd = info->input_bfds, top_id = 3;
input_bfd != NULL;
@@ -10972,8 +11059,7 @@ ppc64_elf_start_multitoc_partition (struct bfd_link_info *info)
{
struct ppc_link_hash_table *htab = ppc_hash_table (info);
- elf_gp (info->output_bfd) = ppc64_elf_toc (info->output_bfd);
- htab->toc_curr = elf_gp (info->output_bfd);
+ htab->toc_curr = ppc64_elf_set_toc (info, info->output_bfd);
htab->toc_bfd = NULL;
htab->toc_first_sec = NULL;
}
@@ -11134,8 +11220,8 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
}
/* Zap sizes of got sections. */
- htab->reliplt->rawsize = htab->reliplt->size;
- htab->reliplt->size -= htab->got_reli_size;
+ htab->elf.irelplt->rawsize = htab->elf.irelplt->size;
+ htab->elf.irelplt->size -= htab->got_reli_size;
htab->got_reli_size = 0;
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
@@ -11167,7 +11253,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
unsigned char *lgot_masks;
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
- asection *s, *srel;
+ asection *s;
if (!is_ppc64_elf (ibfd))
continue;
@@ -11183,26 +11269,31 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
end_local_plt = local_plt + locsymcount;
lgot_masks = (unsigned char *) end_local_plt;
s = ppc64_elf_tdata (ibfd)->got;
- srel = ppc64_elf_tdata (ibfd)->relgot;
for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
{
struct got_entry *ent;
for (ent = *lgot_ents; ent != NULL; ent = ent->next)
{
- unsigned int num = 1;
+ unsigned int ent_size = 8;
+ unsigned int rel_size = sizeof (Elf64_External_Rela);
+
ent->got.offset = s->size;
if ((ent->tls_type & *lgot_masks & TLS_GD) != 0)
- num = 2;
- s->size += num * 8;
- if (info->shared)
- srel->size += num * sizeof (Elf64_External_Rela);
- else if ((*lgot_masks & PLT_IFUNC) != 0)
{
- htab->reliplt->size
- += num * sizeof (Elf64_External_Rela);
- htab->got_reli_size
- += num * sizeof (Elf64_External_Rela);
+ ent_size *= 2;
+ rel_size *= 2;
+ }
+ s->size += ent_size;
+ if ((*lgot_masks & PLT_IFUNC) != 0)
+ {
+ htab->elf.irelplt->size += rel_size;
+ htab->got_reli_size += rel_size;
+ }
+ else if (info->shared)
+ {
+ asection *srel = ppc64_elf_tdata (ibfd)->relgot;
+ srel->size += rel_size;
}
}
}
@@ -11232,7 +11323,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
}
}
- done_something = htab->reliplt->rawsize != htab->reliplt->size;
+ done_something = htab->elf.irelplt->rawsize != htab->elf.irelplt->size;
if (!done_something)
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
{
@@ -11517,42 +11608,25 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
if (htab->multi_toc_needed)
{
- /* If a code section has a function that uses the TOC then we need
- to use the right TOC (obviously). Also, make sure that .opd gets
- the correct TOC value for R_PPC64_TOC relocs that don't have or
- can't find their function symbol (shouldn't ever happen now).
- Also specially treat .fixup for the linux kernel. .fixup
- contains branches, but only back to the function that hit an
- exception. */
- if (isec->has_toc_reloc
- || (isec->flags & SEC_CODE) == 0
- || strcmp (isec->name, ".fixup") == 0)
+ /* Analyse sections that aren't already flagged as needing a
+ valid toc pointer. Exclude .fixup for the linux kernel.
+ .fixup contains branches, but only back to the function that
+ hit an exception. */
+ if (!(isec->has_toc_reloc
+ || (isec->flags & SEC_CODE) == 0
+ || strcmp (isec->name, ".fixup") == 0
+ || isec->call_check_done))
{
- if (elf_gp (isec->owner) != 0)
- htab->toc_curr = elf_gp (isec->owner);
- }
- else
- {
- if (!isec->call_check_done
- && toc_adjusting_stub_needed (info, isec) < 0)
+ if (toc_adjusting_stub_needed (info, isec) < 0)
return FALSE;
- /* If we make a local call from this section, ie. a branch
- without a following nop, then we have no place to put a
- toc restoring insn. We must use the same toc group as
- the callee.
- Testing makes_toc_func_call actually tests for *any*
- calls to functions that need a good toc pointer. A more
- precise test would be better, as this one will set
- incorrect values for pasted .init/.fini fragments.
- (Fixed later in check_pasted_section.) */
- if (isec->makes_toc_func_call
- && elf_gp (isec->owner) != 0)
- htab->toc_curr = elf_gp (isec->owner);
- }
- }
-
- /* Functions that don't use the TOC can belong in any TOC group.
- Use the last TOC base. */
+ }
+ /* Make all sections use the TOC assigned for this object file.
+ This will be wrong for pasted sections; We fix that in
+ check_pasted_section(). */
+ if (elf_gp (isec->owner) != 0)
+ htab->toc_curr = elf_gp (isec->owner);
+ }
+
htab->stub_group[isec->id].toc_off = htab->toc_curr;
return TRUE;
}
@@ -11805,9 +11879,6 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
}
}
htab->plt_thread_safe = plt_thread_safe;
- htab->dot_toc_dot = ((struct ppc_link_hash_entry *)
- elf_link_hash_lookup (&htab->elf, ".TOC.",
- FALSE, FALSE, TRUE));
stubs_always_before_branch = group_size < 0;
if (group_size < 0)
stub_group_size = -group_size;
@@ -12105,7 +12176,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
}
stub_entry->h = hash;
stub_entry->plt_ent = plt_ent;
- stub_entry->addend = irela->r_addend;
+ stub_entry->other = hash ? hash->elf.other : sym->st_other;
if (stub_entry->h != NULL)
htab->stub_globals += 1;
@@ -12214,7 +12285,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
move, we'll be called again. Provide a value for TOCstart. */
bfd_vma
-ppc64_elf_toc (bfd *obfd)
+ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd)
{
asection *s;
bfd_vma TOCstart;
@@ -12265,6 +12336,19 @@ ppc64_elf_toc (bfd *obfd)
if (s != NULL)
TOCstart = s->output_section->vma + s->output_offset;
+ _bfd_set_gp_value (obfd, TOCstart);
+
+ if (info != NULL && s != NULL && is_ppc64_elf (obfd))
+ {
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (htab != NULL
+ && htab->elf.hgot != NULL)
+ {
+ htab->elf.hgot->root.u.def.value = TOC_BASE_OFF;
+ htab->elf.hgot->root.u.def.section = s;
+ }
+ }
return TOCstart;
}
@@ -12303,10 +12387,10 @@ build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
bfd_vma off;
p = s->contents + h->root.u.def.value;
- plt = htab->plt;
+ plt = htab->elf.splt;
if (!htab->elf.dynamic_sections_created
|| h->dynindx == -1)
- plt = htab->iplt;
+ plt = htab->elf.iplt;
off = pent->plt.offset + plt->output_offset + plt->output_section->vma;
off -= h->root.u.def.value + s->output_offset + s->output_section->vma;
@@ -12394,7 +12478,9 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
h->non_elf = 0;
}
}
- plt0 = htab->plt->output_section->vma + htab->plt->output_offset - 16;
+ plt0 = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ - 16);
if (info->emitrelocations)
{
Elf_Internal_Rela *r = get_relocs (htab->glink, 1);
@@ -12882,8 +12968,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
}
else
{
- bfd_boolean ignored;
-
+ int ignored;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
h_elf, sec, relocation,
@@ -12917,13 +13002,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
}
}
}
- if (h_elf == &htab->dot_toc_dot->elf)
- {
- relocation = (TOCstart
- + htab->stub_group[input_section->id].toc_off);
- sec = bfd_abs_section_ptr;
- unresolved_reloc = FALSE;
- }
}
h = (struct ppc_link_hash_entry *) h_elf;
@@ -12936,6 +13014,14 @@ ppc64_elf_relocate_section (bfd *output_bfd,
if (info->relocatable)
continue;
+ if (h != NULL && &h->elf == htab->elf.hgot)
+ {
+ relocation = (TOCstart
+ + htab->stub_group[input_section->id].toc_off);
+ sec = bfd_abs_section_ptr;
+ unresolved_reloc = FALSE;
+ }
+
/* TLS optimizations. Replace instruction sequences and relocs
based on information we collected in tls_optimize. We edit
RELOCS so that --emit-relocs will output something sensible
@@ -13491,60 +13577,90 @@ ppc64_elf_relocate_section (bfd *output_bfd,
{
bfd_boolean can_plt_call = FALSE;
+ /* All of these stubs will modify r2, so there must be a
+ branch and link followed by a nop. The nop is
+ replaced by an insn to restore r2. */
if (rel->r_offset + 8 <= input_section->size)
{
- unsigned long nop;
- nop = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
- if (nop == NOP
- || nop == CROR_151515 || nop == CROR_313131)
+ unsigned long br;
+
+ br = bfd_get_32 (input_bfd,
+ contents + rel->r_offset);
+ if ((br & 1) != 0)
{
- if (h != NULL
- && (h == htab->tls_get_addr_fd
- || h == htab->tls_get_addr)
- && !htab->no_tls_get_addr_opt)
+ unsigned long nop;
+
+ nop = bfd_get_32 (input_bfd,
+ contents + rel->r_offset + 4);
+ if (nop == NOP
+ || nop == CROR_151515 || nop == CROR_313131)
{
- /* Special stub used, leave nop alone. */
+ if (h != NULL
+ && (h == htab->tls_get_addr_fd
+ || h == htab->tls_get_addr)
+ && !htab->no_tls_get_addr_opt)
+ {
+ /* Special stub used, leave nop alone. */
+ }
+ else
+ bfd_put_32 (input_bfd,
+ LD_R2_0R1 + STK_TOC (htab),
+ contents + rel->r_offset + 4);
+ can_plt_call = TRUE;
}
- else
- bfd_put_32 (input_bfd, LD_R2_40R1,
- contents + rel->r_offset + 4);
- can_plt_call = TRUE;
}
}
- if (!can_plt_call)
+ if (!can_plt_call && h != NULL)
{
- if (stub_entry->stub_type == ppc_stub_plt_call
- || stub_entry->stub_type == ppc_stub_plt_call_r2save)
- {
- /* If this is a plain branch rather than a branch
- and link, don't require a nop. However, don't
- allow tail calls in a shared library as they
- will result in r2 being corrupted. */
- unsigned long br;
- br = bfd_get_32 (input_bfd, contents + rel->r_offset);
- if (info->executable && (br & 1) == 0)
- can_plt_call = TRUE;
- else
- stub_entry = NULL;
- }
- else if (h != NULL
- && strcmp (h->elf.root.root.string,
- ".__libc_start_main") == 0)
+ const char *name = h->elf.root.root.string;
+
+ if (*name == '.')
+ ++name;
+
+ if (strncmp (name, "__libc_start_main", 17) == 0
+ && (name[17] == 0 || name[17] == '@'))
{
- /* Allow crt1 branch to go via a toc adjusting stub. */
+ /* Allow crt1 branch to go via a toc adjusting
+ stub. Other calls that never return could do
+ the same, if we could detect such. */
can_plt_call = TRUE;
}
- else
+ }
+
+ if (!can_plt_call)
+ {
+ /* g++ as of 20130507 emits self-calls without a
+ following nop. This is arguably wrong since we
+ have conflicting information. On the one hand a
+ global symbol and on the other a local call
+ sequence, but don't error for this special case.
+ It isn't possible to cheaply verify we have
+ exactly such a call. Allow all calls to the same
+ section. */
+ asection *code_sec = sec;
+
+ if (get_opd_info (sec) != NULL)
{
- info->callbacks->einfo
- (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
- "recompile with -fPIC"),
- input_bfd, input_section, rel->r_offset, sym_name);
+ bfd_vma off = (relocation + addend
+ - sec->output_section->vma
+ - sec->output_offset);
- bfd_set_error (bfd_error_bad_value);
- ret = FALSE;
+ opd_entry_value (sec, off, &code_sec, NULL, FALSE);
}
+ if (code_sec == input_section)
+ can_plt_call = TRUE;
+ }
+
+ if (!can_plt_call)
+ {
+ info->callbacks->einfo
+ (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
+ "recompile with -fPIC\n"),
+ input_bfd, input_section, rel->r_offset, sym_name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
}
if (can_plt_call
@@ -13790,15 +13906,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
ifunc = (h != NULL
? h->elf.type == STT_GNU_IFUNC
: ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC);
- if ((info->shared || indx != 0)
- && (h == NULL
- || (tls_type == (TLS_TLS | TLS_LD)
- && !h->elf.def_dynamic)
- || ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
- || h->elf.root.type != bfd_link_hash_undefweak))
+ if (ifunc)
+ relgot = htab->elf.irelplt;
+ else if ((info->shared || indx != 0)
+ && (h == NULL
+ || (tls_type == (TLS_TLS | TLS_LD)
+ && !h->elf.def_dynamic)
+ || ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
+ || h->elf.root.type != bfd_link_hash_undefweak))
relgot = ppc64_elf_tdata (ent->owner)->relgot;
- else if (ifunc)
- relgot = htab->reliplt;
if (relgot != NULL)
{
outrel.r_offset = (got->output_section->vma
@@ -13905,15 +14021,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
symbol. This happens when statically linking PIC code,
or when using -Bsymbolic. Go find a match if there is a
PLT entry. */
- if (htab->plt != NULL)
+ if (htab->elf.splt != NULL)
{
struct plt_entry *ent;
for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
if (ent->plt.offset != (bfd_vma) -1
&& ent->addend == orig_rel.r_addend)
{
- relocation = (htab->plt->output_section->vma
- + htab->plt->output_offset
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ ent->plt.offset);
unresolved_reloc = FALSE;
break;
@@ -14125,9 +14241,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
{
BFD_ASSERT (h->elf.dynindx != -1);
outrel.r_info = ELF64_R_INFO (h->elf.dynindx, r_type);
- if (h->elf.dynindx == -1
- && h->elf.root.type == bfd_link_hash_undefweak)
- memset (&outrel, 0, sizeof outrel);
}
else
{
@@ -14222,8 +14335,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
}
sreloc = elf_section_data (input_section)->sreloc;
- if (!htab->elf.dynamic_sections_created)
- sreloc = htab->reliplt;
+ if (h != NULL
+ ? h->elf.type == STT_GNU_IFUNC
+ : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ sreloc = htab->elf.irelplt;
if (sreloc == NULL)
abort ();
@@ -14529,8 +14644,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
bfd_size_type amt;
amt = input_section->reloc_count * sizeof (Elf_Internal_Rela);
rel = bfd_alloc (input_bfd, amt);
- BFD_ASSERT (ppc64_elf_tdata (input_bfd)->opd_relocs == NULL);
- ppc64_elf_tdata (input_bfd)->opd_relocs = rel;
+ BFD_ASSERT (ppc64_elf_tdata (input_bfd)->opd.relocs == NULL);
+ ppc64_elf_tdata (input_bfd)->opd.relocs = rel;
if (rel == NULL)
return FALSE;
memcpy (rel, relocs, amt);
@@ -14600,8 +14715,8 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
&& h->def_regular
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- rela.r_offset = (htab->iplt->output_section->vma
- + htab->iplt->output_offset
+ rela.r_offset = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ ent->plt.offset);
if (htab->opd_abi)
rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
@@ -14611,18 +14726,18 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
+ h->root.u.def.section->output_offset
+ h->root.u.def.section->output_section->vma
+ ent->addend);
- loc = (htab->reliplt->contents
- + (htab->reliplt->reloc_count++
+ loc = (htab->elf.irelplt->contents
+ + (htab->elf.irelplt->reloc_count++
* sizeof (Elf64_External_Rela)));
}
else
{
- rela.r_offset = (htab->plt->output_section->vma
- + htab->plt->output_offset
+ rela.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ ent->plt.offset);
rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
rela.r_addend = ent->addend;
- loc = (htab->relplt->contents
+ loc = (htab->elf.srelplt->contents
+ ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE (htab))
/ PLT_ENTRY_SIZE (htab) * sizeof (Elf64_External_Rela)));
}
@@ -14680,9 +14795,15 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
dynamic linker, before writing them out. */
static enum elf_reloc_type_class
-ppc64_elf_reloc_type_class (const Elf_Internal_Rela *rela)
+ppc64_elf_reloc_type_class (const struct bfd_link_info *info,
+ const asection *rel_sec,
+ const Elf_Internal_Rela *rela)
{
enum elf_ppc64_reloc_type r_type;
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (rel_sec == htab->elf.irelplt)
+ return reloc_class_ifunc;
r_type = ELF64_R_TYPE (rela->r_info);
switch (r_type)
@@ -14719,7 +14840,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
{
Elf64_External_Dyn *dyncon, *dynconend;
- if (sdyn == NULL || htab->got == NULL)
+ if (sdyn == NULL || htab->elf.sgot == NULL)
abort ();
dyncon = (Elf64_External_Dyn *) sdyn->contents;
@@ -14766,23 +14887,23 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
break;
case DT_PLTGOT:
- s = htab->plt;
+ s = htab->elf.splt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
break;
case DT_JMPREL:
- s = htab->relplt;
+ s = htab->elf.srelplt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
break;
case DT_PLTRELSZ:
- dyn.d_un.d_val = htab->relplt->size;
+ dyn.d_un.d_val = htab->elf.srelplt->size;
break;
case DT_RELASZ:
/* Don't count procedure linkage table relocs in the
overall reloc count. */
- s = htab->relplt;
+ s = htab->elf.srelplt;
if (s == NULL)
continue;
dyn.d_un.d_val -= s->size;
@@ -14792,7 +14913,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
/* We may not be using the standard ELF linker script.
If .rela.plt is the first .rela section, we adjust
DT_RELA to not include it. */
- s = htab->relplt;
+ s = htab->elf.srelplt;
if (s == NULL)
continue;
if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
@@ -14805,22 +14926,22 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
}
}
- if (htab->got != NULL && htab->got->size != 0)
+ if (htab->elf.sgot != NULL && htab->elf.sgot->size != 0)
{
/* Fill in the first entry in the global offset table.
We use it to hold the link-time TOCbase. */
bfd_put_64 (output_bfd,
elf_gp (output_bfd) + TOC_BASE_OFF,
- htab->got->contents);
+ htab->elf.sgot->contents);
/* Set .got entry size. */
- elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 8;
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 8;
}
- if (htab->plt != NULL && htab->plt->size != 0)
+ if (htab->elf.splt != NULL && htab->elf.splt->size != 0)
{
/* Set .plt entry size. */
- elf_section_data (htab->plt->output_section)->this_hdr.sh_entsize
+ elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize
= PLT_ENTRY_SIZE (htab);
}
diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h
index 2728b27..06c655f 100644
--- a/bfd/elf64-ppc.h
+++ b/bfd/elf64-ppc.h
@@ -19,7 +19,7 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
-void ppc64_elf_init_stub_bfd
+bfd_boolean ppc64_elf_init_stub_bfd
(bfd *, struct bfd_link_info *);
bfd_boolean ppc64_elf_edit_opd
(struct bfd_link_info *, bfd_boolean);
@@ -31,8 +31,8 @@ bfd_boolean ppc64_elf_edit_toc
(struct bfd_link_info *);
bfd_boolean ppc64_elf_has_small_toc_reloc
(asection *);
-bfd_vma ppc64_elf_toc
- (bfd *);
+bfd_vma ppc64_elf_set_toc
+ (struct bfd_link_info *, bfd *);
int ppc64_elf_setup_section_lists
(struct bfd_link_info *, asection *(*) (const char *, asection *),
void (*) (void));
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c319183..0c963e1 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8493,7 +8493,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
(*swap_in) (abfd, erel, s->rela);
- s->type = (*bed->elf_backend_reloc_type_class) (s->rela);
+ s->type = (*bed->elf_backend_reloc_type_class) (info, o, s->rela);
s->u.sym_mask = r_sym_mask;
p += sort_elt;
erel += ext_size;
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 86c9b1b..97e0918 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -424,6 +424,9 @@
#ifndef elf_backend_check_directives
#define elf_backend_check_directives 0
#endif
+#ifndef elf_backend_notice_as_needed
+#define elf_backend_notice_as_needed _bfd_elf_notice_as_needed
+#endif
#ifndef elf_backend_as_needed_cleanup
#define elf_backend_as_needed_cleanup 0
#endif
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index bad3e2c..4239f90 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -423,7 +423,7 @@ ppc_layout_sections_again (void)
if (!link_info.relocatable)
_bfd_set_gp_value (link_info.output_bfd,
- ppc64_elf_toc (link_info.output_bfd));
+ ppc64_elf_set_toc (&link_info, link_info.output_bfd));
need_laying_out = -1;
}
@@ -525,7 +525,7 @@ gld${EMULATION_NAME}_after_allocation (void)
if (!link_info.relocatable)
_bfd_set_gp_value (link_info.output_bfd,
- ppc64_elf_toc (link_info.output_bfd));
+ ppc64_elf_set_toc (&link_info, link_info.output_bfd));
}
}
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 837ad64..87e4ea8 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -82,7 +82,7 @@ proc supports_ppc64 { } {
global ld
catch "exec $ld --help | grep emulations" tmp
- if [ string match "*elf64ppc*" $tmp ] then {
+ if [ regexp "elf64l?ppc" $tmp ] then {
return 1
} else {
return 0
@@ -243,7 +243,7 @@ set ppceabitests {
}
if [istarget "powerpc*le*-*-*"] then {
- set options_regsub(ld) {-melf32ppc -melf32lppc}
+ set options_regsub(ld) {{-melf([3264]*)ppc} {-melf\1lppc}}
for {set i 0} {$i < [llength $ppcelftests]} {incr i} {
set line [lindex $ppcelftests $i]
@@ -255,7 +255,7 @@ if [istarget "powerpc*le*-*-*"] then {
if [ supports_ppc64 ] then {
for {set i 0} {$i < [llength $ppc64elftests]} {incr i} {
- set line [lindex $ppcelftests $i]
+ set line [lindex $ppc64elftests $i]
set ld_options [lindex $line 1]
regsub -all elf64ppc $ld_options elf64lppc ld_options
set line [lreplace $line 1 1 $ld_options]
diff --git a/ld/testsuite/ld-powerpc/tlsexe.d b/ld/testsuite/ld-powerpc/tlsexe.d
index 0d5ee40..747b5e1 100644
--- a/ld/testsuite/ld-powerpc/tlsexe.d
+++ b/ld/testsuite/ld-powerpc/tlsexe.d
@@ -8,13 +8,13 @@
Disassembly of section \.text:
-.* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
+.* <.*plt_call\.__tls_get_addr(|_opt)>:
.* (e9 63 00 00|00 00 63 e9) ld r11,0\(r3\)
.* (e9 83 00 08|08 00 83 e9) ld r12,8\(r3\)
.* (7c 60 1b 78|78 1b 60 7c) mr r0,r3
.* (2c 2b 00 00|00 00 2b 2c) cmpdi r11,0
.* (7c 6c 6a 14|14 6a 6c 7c) add r3,r12,r13
-.* (4d 82 00 20|20 00 82 4d) beqlr
+.* (4d 82 00 20|20 00 82 4d) beqlr *
.* (7c 03 03 78|78 03 03 7c) mr r3,r0
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
.* (f9 61 00 20|20 00 61 f9) std r11,32\(r1\)
diff --git a/ld/testsuite/ld-powerpc/tlsexe.r b/ld/testsuite/ld-powerpc/tlsexe.r
index 72ef3f4..f78f300 100644
--- a/ld/testsuite/ld-powerpc/tlsexe.r
+++ b/ld/testsuite/ld-powerpc/tlsexe.r
@@ -1,7 +1,7 @@
#source: tls.s
#source: tlslib.s
#as: -a64
-#ld:
+#ld:
#readelf: -WSsrl
#target: powerpc64*-*-*
@@ -45,11 +45,11 @@ Program Headers:
Section to Segment mapping:
+Segment Sections\.\.\.
+0+ +
- +01 +\.interp
- +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +03 +\.tdata \.dynamic \.opd \.got \.plt
- +04 +\.dynamic
- +05 +\.tdata \.tbss
+ +01 +\.interp *
+ +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text *
+ +03 +\.tdata \.dynamic \.opd \.got \.plt *
+ +04 +\.dynamic *
+ +05 +\.tdata \.tbss *
Relocation section '\.rela\.dyn' at offset .* contains 3 entries:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
@@ -63,7 +63,7 @@ Relocation section '\.rela\.plt' at offset .* contains 1 entries:
Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* NOTYPE +LOCAL +DEFAULT +UND
+.* NOTYPE +LOCAL +DEFAULT +UND *
.* TLS +GLOBAL +DEFAULT +UND gd
.* TLS +GLOBAL +DEFAULT +UND ld
.* TLS +GLOBAL +DEFAULT +9 ld2
@@ -74,20 +74,20 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
Symbol table '\.symtab' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND
-.* SECTION +LOCAL +DEFAULT +1
-.* SECTION +LOCAL +DEFAULT +2
-.* SECTION +LOCAL +DEFAULT +3
-.* SECTION +LOCAL +DEFAULT +4
-.* SECTION +LOCAL +DEFAULT +5
-.* SECTION +LOCAL +DEFAULT +6
-.* SECTION +LOCAL +DEFAULT +7
-.* SECTION +LOCAL +DEFAULT +8
-.* SECTION +LOCAL +DEFAULT +9
-.* SECTION +LOCAL +DEFAULT +10
-.* SECTION +LOCAL +DEFAULT +11
-.* SECTION +LOCAL +DEFAULT +12
-.* SECTION +LOCAL +DEFAULT +13
+.* 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+.* SECTION +LOCAL +DEFAULT +1 *
+.* SECTION +LOCAL +DEFAULT +2 *
+.* SECTION +LOCAL +DEFAULT +3 *
+.* SECTION +LOCAL +DEFAULT +4 *
+.* SECTION +LOCAL +DEFAULT +5 *
+.* SECTION +LOCAL +DEFAULT +6 *
+.* SECTION +LOCAL +DEFAULT +7 *
+.* SECTION +LOCAL +DEFAULT +8 *
+.* SECTION +LOCAL +DEFAULT +9 *
+.* SECTION +LOCAL +DEFAULT +10 *
+.* SECTION +LOCAL +DEFAULT +11 *
+.* SECTION +LOCAL +DEFAULT +12 *
+.* SECTION +LOCAL +DEFAULT +13 *
.* FILE +LOCAL +DEFAULT +ABS .*
.* TLS +LOCAL +DEFAULT +8 gd4
.* TLS +LOCAL +DEFAULT +8 ld4
@@ -98,9 +98,9 @@ Symbol table '\.symtab' contains [0-9]+ entries:
.* TLS +LOCAL +DEFAULT +8 le5
.* (FUNC|NOTYPE) +LOCAL +DEFAULT +UND \.__tls_get_addr(|_opt)
.* FILE +LOCAL +DEFAULT +ABS .*
-.* NOTYPE +LOCAL +DEFAULT +7 00000010\.plt_call\.__tls_get_addr(|_opt)
.* OBJECT +LOCAL +DEFAULT +10 _DYNAMIC
.* NOTYPE +LOCAL +DEFAULT +7 __glink_PLTresolve
+.* NOTYPE +LOCAL +DEFAULT +7 .*\.plt_call\.__tls_get_addr(|_opt)
.* GLOBAL +DEFAULT +UND gd
.* GLOBAL +DEFAULT +9 le0
.* GLOBAL +DEFAULT +9 ld0
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.d b/ld/testsuite/ld-powerpc/tlsexetoc.d
index ee0f3b2..f38ca9c 100644
--- a/ld/testsuite/ld-powerpc/tlsexetoc.d
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.d
@@ -8,13 +8,13 @@
Disassembly of section \.text:
-.* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
+.* <.*plt_call\.__tls_get_addr(|_opt)>:
.* (e9 63 00 00|00 00 63 e9) ld r11,0\(r3\)
.* (e9 83 00 08|08 00 83 e9) ld r12,8\(r3\)
.* (7c 60 1b 78|78 1b 60 7c) mr r0,r3
.* (2c 2b 00 00|00 00 2b 2c) cmpdi r11,0
.* (7c 6c 6a 14|14 6a 6c 7c) add r3,r12,r13
-.* (4d 82 00 20|20 00 82 4d) beqlr
+.* (4d 82 00 20|20 00 82 4d) beqlr *
.* (7c 03 03 78|78 03 03 7c) mr r3,r0
.* (7d 68 02 a6|a6 02 68 7d) mflr r11
.* (f9 61 00 20|20 00 61 f9) std r11,32\(r1\)
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.g b/ld/testsuite/ld-powerpc/tlsexetoc.g
index dc563ad..b75c8e6 100644
--- a/ld/testsuite/ld-powerpc/tlsexetoc.g
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.g
@@ -4,7 +4,7 @@
#objdump: -sj.got
#target: powerpc64*-*-*
-.*: +file format elf64-powerpc
+.*
Contents of section \.got:
.* (00000000|d8850110) (100185d8|00000000) 00000000 00000000 .*
diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.r b/ld/testsuite/ld-powerpc/tlsexetoc.r
index e6f606b..d238f26 100644
--- a/ld/testsuite/ld-powerpc/tlsexetoc.r
+++ b/ld/testsuite/ld-powerpc/tlsexetoc.r
@@ -1,7 +1,7 @@
#source: tlslib.s
#source: tlstoc.s
#as: -a64
-#ld:
+#ld:
#readelf: -WSsrl
#target: powerpc64*-*-*
@@ -45,11 +45,11 @@ Program Headers:
Section to Segment mapping:
+Segment Sections\.\.\.
+0+ +
- +01 +\.interp
- +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +03 +\.tdata \.dynamic \.opd \.got \.plt
- +04 +\.dynamic
- +05 +\.tdata \.tbss
+ +01 +\.interp *
+ +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text *
+ +03 +\.tdata \.dynamic \.opd \.got \.plt *
+ +04 +\.dynamic *
+ +05 +\.tdata \.tbss *
Relocation section '\.rela\.dyn' at offset .* contains 3 entries:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
@@ -63,7 +63,7 @@ Relocation section '\.rela\.plt' at offset .* contains 1 entries:
Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* NOTYPE +LOCAL +DEFAULT +UND
+.* NOTYPE +LOCAL +DEFAULT +UND *
.* TLS +GLOBAL +DEFAULT +UND gd
.* TLS +GLOBAL +DEFAULT +UND ld
.* NOTYPE +GLOBAL +DEFAULT +13 __bss_start
@@ -73,20 +73,20 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
Symbol table '\.symtab' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* NOTYPE +LOCAL +DEFAULT +UND
-.* SECTION +LOCAL +DEFAULT +1
-.* SECTION +LOCAL +DEFAULT +2
-.* SECTION +LOCAL +DEFAULT +3
-.* SECTION +LOCAL +DEFAULT +4
-.* SECTION +LOCAL +DEFAULT +5
-.* SECTION +LOCAL +DEFAULT +6
-.* SECTION +LOCAL +DEFAULT +7
-.* SECTION +LOCAL +DEFAULT +8
-.* SECTION +LOCAL +DEFAULT +9
-.* SECTION +LOCAL +DEFAULT +10
-.* SECTION +LOCAL +DEFAULT +11
-.* SECTION +LOCAL +DEFAULT +12
-.* SECTION +LOCAL +DEFAULT +13
+.* NOTYPE +LOCAL +DEFAULT +UND *
+.* SECTION +LOCAL +DEFAULT +1 *
+.* SECTION +LOCAL +DEFAULT +2 *
+.* SECTION +LOCAL +DEFAULT +3 *
+.* SECTION +LOCAL +DEFAULT +4 *
+.* SECTION +LOCAL +DEFAULT +5 *
+.* SECTION +LOCAL +DEFAULT +6 *
+.* SECTION +LOCAL +DEFAULT +7 *
+.* SECTION +LOCAL +DEFAULT +8 *
+.* SECTION +LOCAL +DEFAULT +9 *
+.* SECTION +LOCAL +DEFAULT +10 *
+.* SECTION +LOCAL +DEFAULT +11 *
+.* SECTION +LOCAL +DEFAULT +12 *
+.* SECTION +LOCAL +DEFAULT +13 *
.* FILE +LOCAL +DEFAULT +ABS .*
.* TLS +LOCAL +DEFAULT +8 gd4
.* TLS +LOCAL +DEFAULT +8 ld4
@@ -98,9 +98,9 @@ Symbol table '\.symtab' contains [0-9]+ entries:
.* NOTYPE +LOCAL +DEFAULT +12 \.Lie0
.* (FUNC|NOTYPE) +LOCAL +DEFAULT +UND \.__tls_get_addr(|_opt)
.* FILE +LOCAL +DEFAULT +ABS .*
-.* NOTYPE +LOCAL +DEFAULT +7 00000010\.plt_call\.__tls_get_addr(|_opt)
.* OBJECT +LOCAL +DEFAULT +10 _DYNAMIC
.* NOTYPE +LOCAL +DEFAULT +7 __glink_PLTresolve
+.* NOTYPE +LOCAL +DEFAULT +7 .*\.plt_call\.__tls_get_addr(|_opt)
.* TLS +GLOBAL +DEFAULT +UND gd
.* TLS +GLOBAL +DEFAULT +9 le0
.* TLS +GLOBAL +DEFAULT +9 ld0
diff --git a/ld/testsuite/ld-powerpc/tlsso.d b/ld/testsuite/ld-powerpc/tlsso.d
index e64184d..7fe7e87 100644
--- a/ld/testsuite/ld-powerpc/tlsso.d
+++ b/ld/testsuite/ld-powerpc/tlsso.d
@@ -4,17 +4,17 @@
#objdump: -dr
#target: powerpc64*-*-*
-.*: +file format elf64-powerpc
+.*
Disassembly of section \.text:
-.* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
+.* <.*plt_call\.__tls_get_addr(|_opt)>:
.* (f8 41 00 28|28 00 41 f8) std r2,40\(r1\)
.* (e9 82 80 78|78 80 82 e9) ld r12,-32648\(r2\)
.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
.* (e8 42 80 80|80 80 42 e8) ld r2,-32640\(r2\)
.* (28 22 00 00|00 00 22 28) cmpldi r2,0
-.* (4c e2 04 20|20 04 e2 4c) bnectr\+
+.* (4c e2 04 20|20 04 e2 4c) bnectr\+ *
.* (48 00 00 ..|.. 00 00 48) b .* <__tls_get_addr@plt>
.* <\._start>:
diff --git a/ld/testsuite/ld-powerpc/tlsso.g b/ld/testsuite/ld-powerpc/tlsso.g
index 8fd3ce0..0ba9fda 100644
--- a/ld/testsuite/ld-powerpc/tlsso.g
+++ b/ld/testsuite/ld-powerpc/tlsso.g
@@ -4,7 +4,7 @@
#objdump: -sj.got
#target: powerpc64*-*-*
-.*: +file format elf64-powerpc
+.*
Contents of section \.got:
107e0 (00000000|e0870100) (000187e0|00000000) 00000000 00000000 .*
diff --git a/ld/testsuite/ld-powerpc/tlsso.r b/ld/testsuite/ld-powerpc/tlsso.r
index 6464be0..ddaaebc 100644
--- a/ld/testsuite/ld-powerpc/tlsso.r
+++ b/ld/testsuite/ld-powerpc/tlsso.r
@@ -39,10 +39,10 @@ Program Headers:
Section to Segment mapping:
+Segment Sections\.\.\.
- +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +01 +\.tdata \.dynamic \.opd \.got \.plt
- +02 +\.dynamic
- +03 +\.tdata \.tbss
+ +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text *
+ +01 +\.tdata \.dynamic \.opd \.got \.plt *
+ +02 +\.dynamic *
+ +03 +\.tdata \.tbss *
Relocation section '\.rela\.dyn' at offset .* contains 18 entries:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
@@ -71,9 +71,9 @@ Relocation section '\.rela\.plt' at offset .* contains 1 entries:
Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* NOTYPE +LOCAL +DEFAULT +UND
-.* SECTION +LOCAL +DEFAULT +6
-.* SECTION +LOCAL +DEFAULT +7
+.* NOTYPE +LOCAL +DEFAULT +UND *
+.* SECTION +LOCAL +DEFAULT +6 *
+.* SECTION +LOCAL +DEFAULT +7 *
.* TLS +GLOBAL +DEFAULT +UND gd
.* TLS +GLOBAL +DEFAULT +8 le0
.* NOTYPE +GLOBAL +DEFAULT +UND __tls_get_addr
@@ -91,19 +91,19 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
Symbol table '\.symtab' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* NOTYPE +LOCAL +DEFAULT +UND
-.* SECTION +LOCAL +DEFAULT +1
-.* SECTION +LOCAL +DEFAULT +2
-.* SECTION +LOCAL +DEFAULT +3
-.* SECTION +LOCAL +DEFAULT +4
-.* SECTION +LOCAL +DEFAULT +5
-.* SECTION +LOCAL +DEFAULT +6
-.* SECTION +LOCAL +DEFAULT +7
-.* SECTION +LOCAL +DEFAULT +8
-.* SECTION +LOCAL +DEFAULT +9
-.* SECTION +LOCAL +DEFAULT +10
-.* SECTION +LOCAL +DEFAULT +11
-.* SECTION +LOCAL +DEFAULT +12
+.* NOTYPE +LOCAL +DEFAULT +UND *
+.* SECTION +LOCAL +DEFAULT +1 *
+.* SECTION +LOCAL +DEFAULT +2 *
+.* SECTION +LOCAL +DEFAULT +3 *
+.* SECTION +LOCAL +DEFAULT +4 *
+.* SECTION +LOCAL +DEFAULT +5 *
+.* SECTION +LOCAL +DEFAULT +6 *
+.* SECTION +LOCAL +DEFAULT +7 *
+.* SECTION +LOCAL +DEFAULT +8 *
+.* SECTION +LOCAL +DEFAULT +9 *
+.* SECTION +LOCAL +DEFAULT +10 *
+.* SECTION +LOCAL +DEFAULT +11 *
+.* SECTION +LOCAL +DEFAULT +12 *
.* FILE +LOCAL +DEFAULT +ABS .*
.* TLS +LOCAL +DEFAULT +7 gd4
.* TLS +LOCAL +DEFAULT +7 ld4
@@ -115,7 +115,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
.* NOTYPE +LOCAL +DEFAULT +UND \.__tls_get_addr
.* FILE +LOCAL +DEFAULT +ABS .*
.* OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
-.* NOTYPE +LOCAL +DEFAULT +6 00000010\.plt_call\.__tls_get_addr
+.* NOTYPE +LOCAL +DEFAULT +6 .*\.plt_call\.__tls_get_addr
.* NOTYPE +LOCAL +DEFAULT +6 __glink_PLTresolve
.* TLS +GLOBAL +DEFAULT +UND gd
.* TLS +GLOBAL +DEFAULT +8 le0
diff --git a/ld/testsuite/ld-powerpc/tlstocso.d b/ld/testsuite/ld-powerpc/tlstocso.d
index fa3b77a..6aa1056 100644
--- a/ld/testsuite/ld-powerpc/tlstocso.d
+++ b/ld/testsuite/ld-powerpc/tlstocso.d
@@ -4,17 +4,17 @@
#objdump: -dr
#target: powerpc64*-*-*
-.*: +file format elf64-powerpc
+.*
Disassembly of section \.text:
-.* <00000010\.plt_call\.__tls_get_addr(|_opt)>:
+.* <.*plt_call\.__tls_get_addr(|_opt)>:
.* (f8 41 00 28|28 00 41 f8) std r2,40\(r1\)
.* (e9 82 80 70|70 80 82 e9) ld r12,-32656\(r2\)
.* (7d 89 03 a6|a6 03 89 7d) mtctr r12
.* (e8 42 80 78|78 80 42 e8) ld r2,-32648\(r2\)
.* (28 22 00 00|00 00 22 28) cmpldi r2,0
-.* (4c e2 04 20|20 04 e2 4c) bnectr\+
+.* (4c e2 04 20|20 04 e2 4c) bnectr\+ *
.* (48 00 00 ..|.. 00 00 48) b .* <__tls_get_addr@plt>
.* <\._start>:
diff --git a/ld/testsuite/ld-powerpc/tlstocso.g b/ld/testsuite/ld-powerpc/tlstocso.g
index a22497d..9da93ec 100644
--- a/ld/testsuite/ld-powerpc/tlstocso.g
+++ b/ld/testsuite/ld-powerpc/tlstocso.g
@@ -7,7 +7,7 @@
.*
Contents of section \.got:
- 106c8 00000000 (000186c8|c8860100) 00000000 00000000 .*
+ 10720 (00000000|20870100) (00018720|00000000) 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
diff --git a/ld/testsuite/ld-powerpc/tlstocso.r b/ld/testsuite/ld-powerpc/tlstocso.r
index f397915..f5bdfe3 100644
--- a/ld/testsuite/ld-powerpc/tlstocso.r
+++ b/ld/testsuite/ld-powerpc/tlstocso.r
@@ -39,10 +39,10 @@ Program Headers:
Section to Segment mapping:
+Segment Sections\.\.\.
- +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text
- +01 +\.tdata \.dynamic \.opd \.got \.plt
- +02 +\.dynamic
- +03 +\.tdata \.tbss
+ +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text *
+ +01 +\.tdata \.dynamic \.opd \.got \.plt *
+ +02 +\.dynamic *
+ +03 +\.tdata \.tbss *
Relocation section '\.rela\.dyn' at offset .* contains 13 entries:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
@@ -66,9 +66,9 @@ Relocation section '\.rela\.plt' at offset .* contains 1 entries:
Symbol table '\.dynsym' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* NOTYPE +LOCAL +DEFAULT +UND
-.* SECTION +LOCAL +DEFAULT +6
-.* SECTION +LOCAL +DEFAULT +7
+.* NOTYPE +LOCAL +DEFAULT +UND *
+.* SECTION +LOCAL +DEFAULT +6 *
+.* SECTION +LOCAL +DEFAULT +7 *
.* TLS +GLOBAL +DEFAULT +UND gd
.* TLS +GLOBAL +DEFAULT +8 le0
.* NOTYPE +GLOBAL +DEFAULT +UND __tls_get_addr
@@ -86,19 +86,19 @@ Symbol table '\.dynsym' contains [0-9]+ entries:
Symbol table '\.symtab' contains [0-9]+ entries:
+Num: +Value +Size +Type +Bind +Vis +Ndx +Name
-.* NOTYPE +LOCAL +DEFAULT +UND
-.* SECTION +LOCAL +DEFAULT +1
-.* SECTION +LOCAL +DEFAULT +2
-.* SECTION +LOCAL +DEFAULT +3
-.* SECTION +LOCAL +DEFAULT +4
-.* SECTION +LOCAL +DEFAULT +5
-.* SECTION +LOCAL +DEFAULT +6
-.* SECTION +LOCAL +DEFAULT +7
-.* SECTION +LOCAL +DEFAULT +8
-.* SECTION +LOCAL +DEFAULT +9
-.* SECTION +LOCAL +DEFAULT +10
-.* SECTION +LOCAL +DEFAULT +11
-.* SECTION +LOCAL +DEFAULT +12
+.* NOTYPE +LOCAL +DEFAULT +UND *
+.* SECTION +LOCAL +DEFAULT +1 *
+.* SECTION +LOCAL +DEFAULT +2 *
+.* SECTION +LOCAL +DEFAULT +3 *
+.* SECTION +LOCAL +DEFAULT +4 *
+.* SECTION +LOCAL +DEFAULT +5 *
+.* SECTION +LOCAL +DEFAULT +6 *
+.* SECTION +LOCAL +DEFAULT +7 *
+.* SECTION +LOCAL +DEFAULT +8 *
+.* SECTION +LOCAL +DEFAULT +9 *
+.* SECTION +LOCAL +DEFAULT +10 *
+.* SECTION +LOCAL +DEFAULT +11 *
+.* SECTION +LOCAL +DEFAULT +12 *
.* FILE +LOCAL +DEFAULT +ABS .*
.* TLS +LOCAL +DEFAULT +7 gd4
.* TLS +LOCAL +DEFAULT +7 ld4
@@ -111,7 +111,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
.* NOTYPE +LOCAL +DEFAULT +UND \.__tls_get_addr
.* FILE +LOCAL +DEFAULT +ABS .*
.* OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
-.* NOTYPE +LOCAL +DEFAULT +6 00000010\.plt_call\.__tls_get_addr
+.* NOTYPE +LOCAL +DEFAULT +6 .*\.plt_call\.__tls_get_addr
.* NOTYPE +LOCAL +DEFAULT +6 __glink_PLTresolve
.* TLS +GLOBAL +DEFAULT +UND gd
.* TLS +GLOBAL +DEFAULT +8 le0
diff --git a/ld/testsuite/ld-powerpc/tlstocso.t b/ld/testsuite/ld-powerpc/tlstocso.t
index ce4f44a..408d2a5 100644
--- a/ld/testsuite/ld-powerpc/tlstocso.t
+++ b/ld/testsuite/ld-powerpc/tlstocso.t
@@ -7,7 +7,7 @@
.*
Contents of section \.tdata:
-.* (12345678|78563412) (9abcdef0|f0debc9a) (23456789|89674523) (abcdef01|01efcdab) .*
-.* (3456789a|9a785634) (bcdef012|12f0debc) (456789ab|ab896745) (cdef0123|2301efcd) .*
-.* (56789abc|bc9a7856) (def01234|3412f0de) (6789abcd|cdab8967) (ef012345|452301ef) .*
-.* (789abcde|debc9a78) (f0123456|563412f0) .*
+.* (12345678|f0debc9a) (9abcdef0|78563412) (23456789|01efcdab) (abcdef01|89674523) .*
+.* (3456789a|12f0debc) (bcdef012|9a785634) (456789ab|2301efcd) (cdef0123|ab896745) .*
+.* (56789abc|3412f0de) (def01234|bc9a7856) (6789abcd|452301ef) (ef012345|cdab8967) .*
+.* (789abcde|563412f0) (f0123456|debc9a78) .*