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