/* PowerPC-specific support for 32-bit ELF
- Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Copyright (C) 1994-2015 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
apuinfo_list_init ();
/* Read in the input sections contents. */
- for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
+ for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link.next)
{
unsigned long datum;
*valp = sym->st_size;
}
- if ((abfd->flags & DYNAMIC) == 0
- && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
- || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
return TRUE;
case R_PPC_GOT_TPREL16_LO:
case R_PPC_GOT_TPREL16_HI:
case R_PPC_GOT_TPREL16_HA:
- if (!info->executable)
+ if (info->shared)
info->flags |= DF_STATIC_TLS;
tls_type = TLS_TLS | TLS_TPREL;
goto dogottls;
case R_PPC_TPREL16_LO:
case R_PPC_TPREL16_HI:
case R_PPC_TPREL16_HA:
- if (!info->executable)
+ if (info->shared)
info->flags |= DF_STATIC_TLS;
goto dodyn;
--secure-plt and we never see REL16 relocs. */
if (plt_type == PLT_UNSET)
plt_type = PLT_OLD;
- for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link_next)
+ for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
if (is_ppc_elf (ibfd))
{
if (ppc_elf_tdata (ibfd)->has_rel16)
notify relocate_section that optimization can be done, and
adjust got and plt refcounts. */
for (pass = 0; pass < 2; ++pass)
- for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
Elf_Internal_Sym *locsyms = NULL;
Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
will go to this object, or will remain undefined. */
h->plt.plist = NULL;
h->needs_plt = 0;
+ h->pointer_equality_needed = 0;
}
else
{
+ /* Taking a function's address in a read/write section
+ doesn't require us to define the function symbol in the
+ executable on a plt call stub. A dynamic reloc can
+ be used instead. */
+ if (h->pointer_equality_needed
+ && h->type != STT_GNU_IFUNC
+ && !htab->is_vxworks
+ && !ppc_elf_hash_entry (h)->has_sda_refs
+ && !readonly_dynrelocs (h))
+ {
+ h->pointer_equality_needed = 0;
+ h->non_got_ref = 0;
+ }
+
/* After adjust_dynamic_symbol, non_got_ref set in the
non-shared case means that we have allocated space in
.dynbss for the symbol and thus dyn_relocs for this
relocations against this symbol to the PLT entry. Allow
dynamic relocs if the reference is weak, and the dynamic
relocs will not cause text relocation. */
- if (!h->ref_regular_nonweak
- && h->non_got_ref
- && h->type != STT_GNU_IFUNC
- && !htab->is_vxworks
- && !ppc_elf_hash_entry (h)->has_sda_refs
- && !readonly_dynrelocs (h))
+ else if (!h->ref_regular_nonweak
+ && h->non_got_ref
+ && h->type != STT_GNU_IFUNC
+ && !htab->is_vxworks
+ && !ppc_elf_hash_entry (h)->has_sda_refs
+ && !readonly_dynrelocs (h))
h->non_got_ref = 0;
}
return TRUE;
h->needs_copy = 1;
}
- return _bfd_elf_adjust_dynamic_copy (h, s);
+ return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
\f
/* Generate a symbol to mark plt call stubs. For non-PIC code the sym is
/* Set up .got offsets for local syms, and space for local dynamic
relocs. */
- for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
bfd_signed_vma *local_got;
bfd_signed_vma *end_local_got;
sda->root.u.def.section = htab->elf.hgot->root.u.def.section;
sda->root.u.def.value = htab->elf.hgot->root.u.def.value;
}
+ if (info->emitrelocations)
+ {
+ struct elf_link_hash_entry *sda = htab->sdata[0].sym;
+
+ if (sda != NULL && sda->ref_regular)
+ sda->root.u.def.section->flags |= SEC_KEEP;
+ sda = htab->sdata[1].sym;
+ if (sda != NULL && sda->ref_regular)
+ sda->root.u.def.section->flags |= SEC_KEEP;
+ }
if (htab->glink != NULL
&& htab->glink->size != 0
|| s == htab->sgotplt
|| s == htab->sbss
|| s == htab->dynbss
- || s == htab->dynsbss
- || s == htab->sdata[0].section
- || s == htab->sdata[1].section)
+ || s == htab->dynsbss)
{
/* Strip these too. */
}
+ else if (s == htab->sdata[0].section
+ || s == htab->sdata[1].section)
+ {
+ strip_section = (s->flags & SEC_KEEP) == 0;
+ }
else if (CONST_STRNEQ (bfd_get_section_name (htab->elf.dynobj, s),
".rela"))
{
bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
addr = isec->output_section->vma + isec->output_offset;
- end_addr = addr + trampoff - 1;
+ end_addr = addr + trampoff;
addr &= -pagesize;
crossings = ((end_addr & -pagesize) - addr) >> htab->params->pagesize_p2;
if (crossings != 0)
/* Keep space aligned, to ensure the patch code itself does
not cross a page. Don't decrease size calculated on a
previous pass as otherwise we might never settle on a layout. */
- newsize = 15 - (end_addr & 15);
+ newsize = 15 - ((end_addr - 1) & 15);
newsize += crossings * 16;
if (relax_info->workaround_size < newsize)
{
#define ELF_MACHINE_CODE EM_PPC
#ifdef __QNXTARGET__
#define ELF_MAXPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
#else
#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x10000
#endif
#define ELF_MINPAGESIZE 0x1000
-#define ELF_COMMONPAGESIZE 0x1000
#define elf_info_to_howto ppc_elf_info_to_howto
#ifdef EM_CYGNUS_POWERPC