+2019-09-18 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (must_be_dyn_reloc): Return 0 for TOC16 relocs.
+ (ppc64_elf_check_relocs): Support dynamic/copy relocs for TOC16.
+ (ppc64_elf_adjust_dynamic_symbol): Don't keep dynamic reloc when
+ needs_copy even if all relocs are in rw sections.
+ (dec_dynrel_count): Handle TOC16 relocs.
+ (ppc64_elf_relocate_section): Support dynamic relocs for TOC16.
+ (ppc64_elf_finish_dynamic_symbol): Adjust to handle needs_copy
+ semantic change.
+
2019-09-16 Phil Blundell <pb@pbcl.net>
* version.m4: Set version to 2.33.50.
case R_PPC64_REL32:
case R_PPC64_REL64:
case R_PPC64_REL30:
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_LO_DS:
return 0;
case R_PPC64_TPREL16:
case R_PPC64_TOC16_HA:
case R_PPC64_TOC16_LO_DS:
sec->has_toc_reloc = 1;
+ if (h != NULL && !bfd_link_pic (info))
+ {
+ /* We may need a copy reloc. */
+ h->non_got_ref = 1;
+ /* Strongly prefer a copy reloc over a dynamic reloc.
+ glibc ld.so as of 2019-08 will error out if one of
+ these relocations is emitted. */
+ h->needs_copy = 1;
+ goto dodyn;
+ }
break;
/* Marker reloc. */
/* If we don't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
- || (ELIMINATE_COPY_RELOCS && !alias_readonly_dynrelocs (h))
+ || (ELIMINATE_COPY_RELOCS
+ && !h->needs_copy
+ && !alias_readonly_dynrelocs (h))
/* Protected variables do not work with .dynbss. The copy in
.dynbss won't be used by the shared library with the protected
default:
return TRUE;
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_LO_DS:
+ if (h == NULL)
+ return TRUE;
+ break;
+
case R_PPC64_TPREL16:
case R_PPC64_TPREL16_LO:
case R_PPC64_TPREL16_HI:
case R_PPC64_TOC16_LO_DS:
case R_PPC64_TOC16_HA:
addend -= TOCstart + htab->sec_info[input_section->id].toc_off;
+ if (h != NULL)
+ goto dodyn;
break;
/* Relocate against the beginning of the section. */
break;
}
- if (h->needs_copy)
+ if (h->needs_copy
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->root.u.def.section == htab->elf.sdynbss
+ || h->root.u.def.section == htab->elf.sdynrelro))
{
/* This symbol needs a copy reloc. Set it up. */
Elf_Internal_Rela rela;
asection *srel;
bfd_byte *loc;
- if (h->dynindx == -1
- || (h->root.type != bfd_link_hash_defined
- && h->root.type != bfd_link_hash_defweak)
- || htab->elf.srelbss == NULL
- || htab->elf.sreldynrelro == NULL)
+ if (h->dynindx == -1)
abort ();
rela.r_offset = (h->root.u.def.value