|
|
d570a8 |
diff -Nrup a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
|
|
|
d570a8 |
--- a/bfd/elf64-ppc.c 2015-06-23 07:38:21.531023391 -0600
|
|
|
d570a8 |
+++ b/bfd/elf64-ppc.c 2015-06-23 07:39:23.606689926 -0600
|
|
|
d570a8 |
@@ -4963,81 +4963,77 @@ ppc64_elf_before_check_relocs (bfd *ibfd
|
|
|
d570a8 |
{
|
|
|
d570a8 |
struct ppc_link_hash_table *htab;
|
|
|
d570a8 |
struct ppc_link_hash_entry **p, *eh;
|
|
|
d570a8 |
+ asection *opd = bfd_get_section_by_name (ibfd, ".opd");
|
|
|
d570a8 |
|
|
|
d570a8 |
- if (!is_ppc64_elf (info->output_bfd))
|
|
|
d570a8 |
- return TRUE;
|
|
|
d570a8 |
- htab = ppc_hash_table (info);
|
|
|
d570a8 |
- if (htab == NULL)
|
|
|
d570a8 |
- return FALSE;
|
|
|
d570a8 |
-
|
|
|
d570a8 |
- if (is_ppc64_elf (ibfd))
|
|
|
d570a8 |
+ if (opd != NULL && opd->size != 0)
|
|
|
d570a8 |
{
|
|
|
d570a8 |
- asection *opd = bfd_get_section_by_name (ibfd, ".opd");
|
|
|
d570a8 |
-
|
|
|
d570a8 |
- if (opd != NULL && opd->size != 0)
|
|
|
d570a8 |
+ if (abiversion (ibfd) == 0)
|
|
|
d570a8 |
+ set_abiversion (ibfd, 1);
|
|
|
d570a8 |
+ else if (abiversion (ibfd) == 2)
|
|
|
d570a8 |
{
|
|
|
d570a8 |
- if (abiversion (ibfd) == 0)
|
|
|
d570a8 |
- set_abiversion (ibfd, 1);
|
|
|
d570a8 |
- else if (abiversion (ibfd) == 2)
|
|
|
d570a8 |
- {
|
|
|
d570a8 |
- info->callbacks->einfo (_("%P: %B .opd not allowed in ABI"
|
|
|
d570a8 |
- " version %d\n"),
|
|
|
d570a8 |
- ibfd, abiversion (ibfd));
|
|
|
d570a8 |
- bfd_set_error (bfd_error_bad_value);
|
|
|
d570a8 |
- return FALSE;
|
|
|
d570a8 |
- }
|
|
|
d570a8 |
-
|
|
|
d570a8 |
- if ((ibfd->flags & DYNAMIC) == 0
|
|
|
d570a8 |
- && (opd->flags & SEC_RELOC) != 0
|
|
|
d570a8 |
- && opd->reloc_count != 0
|
|
|
d570a8 |
- && !bfd_is_abs_section (opd->output_section))
|
|
|
d570a8 |
- {
|
|
|
d570a8 |
- /* Garbage collection needs some extra help with .opd sections.
|
|
|
d570a8 |
- We don't want to necessarily keep everything referenced by
|
|
|
d570a8 |
- relocs in .opd, as that would keep all functions. Instead,
|
|
|
d570a8 |
- if we reference an .opd symbol (a function descriptor), we
|
|
|
d570a8 |
- want to keep the function code symbol's section. This is
|
|
|
d570a8 |
- easy for global symbols, but for local syms we need to keep
|
|
|
d570a8 |
- information about the associated function section. */
|
|
|
d570a8 |
- bfd_size_type amt;
|
|
|
d570a8 |
- asection **opd_sym_map;
|
|
|
d570a8 |
-
|
|
|
d570a8 |
- amt = opd->size * sizeof (*opd_sym_map) / 8;
|
|
|
d570a8 |
- opd_sym_map = bfd_zalloc (ibfd, amt);
|
|
|
d570a8 |
- if (opd_sym_map == NULL)
|
|
|
d570a8 |
- return FALSE;
|
|
|
d570a8 |
- ppc64_elf_section_data (opd)->u.opd.func_sec = opd_sym_map;
|
|
|
d570a8 |
- BFD_ASSERT (ppc64_elf_section_data (opd)->sec_type == sec_normal);
|
|
|
d570a8 |
- ppc64_elf_section_data (opd)->sec_type = sec_opd;
|
|
|
d570a8 |
- }
|
|
|
d570a8 |
+ info->callbacks->einfo (_("%P: %B .opd not allowed in ABI"
|
|
|
d570a8 |
+ " version %d\n"),
|
|
|
d570a8 |
+ ibfd, abiversion (ibfd));
|
|
|
d570a8 |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
d570a8 |
+ return FALSE;
|
|
|
d570a8 |
}
|
|
|
d570a8 |
|
|
|
d570a8 |
- /* For input files without an explicit abiversion in e_flags
|
|
|
d570a8 |
- we should have flagged any with symbol st_other bits set
|
|
|
d570a8 |
- as ELFv1 and above flagged those with .opd as ELFv2.
|
|
|
d570a8 |
- Set the output abiversion if not yet set, and for any input
|
|
|
d570a8 |
- still ambiguous, take its abiversion from the output.
|
|
|
d570a8 |
- Differences in ABI are reported later. */
|
|
|
d570a8 |
- if (abiversion (info->output_bfd) == 0)
|
|
|
d570a8 |
- set_abiversion (info->output_bfd, abiversion (ibfd));
|
|
|
d570a8 |
- else if (abiversion (ibfd) == 0)
|
|
|
d570a8 |
- set_abiversion (ibfd, abiversion (info->output_bfd));
|
|
|
d570a8 |
-
|
|
|
d570a8 |
- p = &htab->dot_syms;
|
|
|
d570a8 |
- while ((eh = *p) != NULL)
|
|
|
d570a8 |
+ if ((ibfd->flags & DYNAMIC) == 0
|
|
|
d570a8 |
+ && (opd->flags & SEC_RELOC) != 0
|
|
|
d570a8 |
+ && opd->reloc_count != 0
|
|
|
d570a8 |
+ && !bfd_is_abs_section (opd->output_section))
|
|
|
d570a8 |
{
|
|
|
d570a8 |
- *p = NULL;
|
|
|
d570a8 |
- if (&eh->elf == htab->elf.hgot)
|
|
|
d570a8 |
- ;
|
|
|
d570a8 |
- else if (htab->elf.hgot == NULL
|
|
|
d570a8 |
- && strcmp (eh->elf.root.root.string, ".TOC.") == 0)
|
|
|
d570a8 |
- htab->elf.hgot = &eh->elf;
|
|
|
d570a8 |
- else if (!add_symbol_adjust (eh, info))
|
|
|
d570a8 |
+ /* Garbage collection needs some extra help with .opd sections.
|
|
|
d570a8 |
+ We don't want to necessarily keep everything referenced by
|
|
|
d570a8 |
+ relocs in .opd, as that would keep all functions. Instead,
|
|
|
d570a8 |
+ if we reference an .opd symbol (a function descriptor), we
|
|
|
d570a8 |
+ want to keep the function code symbol's section. This is
|
|
|
d570a8 |
+ easy for global symbols, but for local syms we need to keep
|
|
|
d570a8 |
+ information about the associated function section. */
|
|
|
d570a8 |
+ bfd_size_type amt;
|
|
|
d570a8 |
+ asection **opd_sym_map;
|
|
|
d570a8 |
+
|
|
|
d570a8 |
+ amt = opd->size * sizeof (*opd_sym_map) / 8;
|
|
|
d570a8 |
+ opd_sym_map = bfd_zalloc (ibfd, amt);
|
|
|
d570a8 |
+ if (opd_sym_map == NULL)
|
|
|
d570a8 |
return FALSE;
|
|
|
d570a8 |
- p = &eh->u.next_dot_sym;
|
|
|
d570a8 |
+ ppc64_elf_section_data (opd)->u.opd.func_sec = opd_sym_map;
|
|
|
d570a8 |
+ BFD_ASSERT (ppc64_elf_section_data (opd)->sec_type == sec_normal);
|
|
|
d570a8 |
+ ppc64_elf_section_data (opd)->sec_type = sec_opd;
|
|
|
d570a8 |
}
|
|
|
d570a8 |
}
|
|
|
d570a8 |
|
|
|
d570a8 |
+ if (!is_ppc64_elf (info->output_bfd))
|
|
|
d570a8 |
+ return TRUE;
|
|
|
d570a8 |
+ htab = ppc_hash_table (info);
|
|
|
d570a8 |
+ if (htab == NULL)
|
|
|
d570a8 |
+ return FALSE;
|
|
|
d570a8 |
+
|
|
|
d570a8 |
+ /* For input files without an explicit abiversion in e_flags
|
|
|
d570a8 |
+ we should have flagged any with symbol st_other bits set
|
|
|
d570a8 |
+ as ELFv1 and above flagged those with .opd as ELFv2.
|
|
|
d570a8 |
+ Set the output abiversion if not yet set, and for any input
|
|
|
d570a8 |
+ still ambiguous, take its abiversion from the output.
|
|
|
d570a8 |
+ Differences in ABI are reported later. */
|
|
|
d570a8 |
+ if (abiversion (info->output_bfd) == 0)
|
|
|
d570a8 |
+ set_abiversion (info->output_bfd, abiversion (ibfd));
|
|
|
d570a8 |
+ else if (abiversion (ibfd) == 0)
|
|
|
d570a8 |
+ set_abiversion (ibfd, abiversion (info->output_bfd));
|
|
|
d570a8 |
+
|
|
|
d570a8 |
+ p = &htab->dot_syms;
|
|
|
d570a8 |
+ while ((eh = *p) != NULL)
|
|
|
d570a8 |
+ {
|
|
|
d570a8 |
+ *p = NULL;
|
|
|
d570a8 |
+ if (&eh->elf == htab->elf.hgot)
|
|
|
d570a8 |
+ ;
|
|
|
d570a8 |
+ else if (htab->elf.hgot == NULL
|
|
|
d570a8 |
+ && strcmp (eh->elf.root.root.string, ".TOC.") == 0)
|
|
|
d570a8 |
+ htab->elf.hgot = &eh->elf;
|
|
|
d570a8 |
+ else if (!add_symbol_adjust (eh, info))
|
|
|
d570a8 |
+ return FALSE;
|
|
|
d570a8 |
+ p = &eh->u.next_dot_sym;
|
|
|
d570a8 |
+ }
|
|
|
d570a8 |
+
|
|
|
d570a8 |
/* Clear the list for non-ppc64 input files. */
|
|
|
d570a8 |
p = &htab->dot_syms;
|
|
|
d570a8 |
while ((eh = *p) != NULL)
|
|
|
d570a8 |
diff -Nrup a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
|
|
|
d570a8 |
--- a/ld/emultempl/ppc64elf.em 2015-06-23 07:38:21.489024293 -0600
|
|
|
d570a8 |
+++ b/ld/emultempl/ppc64elf.em 2015-06-23 07:39:23.606689926 -0600
|
|
|
d570a8 |
@@ -539,7 +539,8 @@ ppc_finish (void)
|
|
|
d570a8 |
/* e_entry on PowerPC64 points to the function descriptor for
|
|
|
d570a8 |
_start. If _start is missing, default to the first function
|
|
|
d570a8 |
descriptor in the .opd section. */
|
|
|
d570a8 |
- if ((elf_elfheader (link_info.output_bfd)->e_flags & EF_PPC64_ABI) == 1)
|
|
|
d570a8 |
+ if (stub_file != NULL
|
|
|
d570a8 |
+ && (elf_elfheader (link_info.output_bfd)->e_flags & EF_PPC64_ABI) == 1)
|
|
|
d570a8 |
entry_section = ".opd";
|
|
|
d570a8 |
|
|
|
d570a8 |
if (stub_added)
|