/* 32-bit ELF support for TI C6X
- Copyright (C) 2010-2016 Free Software Foundation, Inc.
+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
Contributed by Joseph Myers <joseph@codesourcery.com>
Bernd Schmidt <bernds@codesourcery.com>
{
struct elf_link_hash_table elf;
- /* Short-cuts to get to dynamic linker sections. */
- asection *sdynbss;
- asection *srelbss;
-
/* C6X specific command line arguments. */
struct elf32_tic6x_params params;
|| ! bfd_set_section_alignment (dynobj, htab->elf.splt, 5))
return FALSE;
- htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
- if (!bfd_link_pic (info))
- htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-
- if (!htab->sdynbss
- || (!bfd_link_pic (info) && !htab->srelbss))
- abort ();
-
return TRUE;
}
struct elf_link_hash_entry *h,
Elf_Internal_Sym * sym)
{
- bfd *dynobj;
struct elf32_tic6x_link_hash_table *htab;
htab = elf32_tic6x_hash_table (info);
- dynobj = htab->elf.dynobj;
if (h->plt.offset != (bfd_vma) -1)
{
/* This symbol has an entry in the global offset table.
Set it up. */
- sgot = bfd_get_linker_section (dynobj, ".got");
- srela = bfd_get_linker_section (dynobj, ".rela.got");
+ sgot = htab->elf.sgot;
+ srela = htab->elf.srelgot;
BFD_ASSERT (sgot != NULL && srela != NULL);
/* If this is a -Bsymbolic link, and the symbol is defined
if (h->needs_copy)
{
Elf_Internal_Rela rel;
+ asection *s;
/* This symbol needs a copy reloc. Set it up. */
if (h->dynindx == -1
|| (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak)
- || htab->srelbss == NULL)
+ || htab->elf.srelbss == NULL
+ || htab->elf.sreldynrelro == NULL)
abort ();
rel.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_offset);
rel.r_info = ELF32_R_INFO (h->dynindx, R_C6000_COPY);
rel.r_addend = 0;
+ if (h->root.u.def.section == htab->elf.sdynrelro)
+ s = htab->elf.sreldynrelro;
+ else
+ s = htab->elf.srelbss;
- elf32_tic6x_install_rela (output_bfd, htab->srelbss, &rel);
+ elf32_tic6x_install_rela (output_bfd, s, &rel);
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
{
struct elf32_tic6x_link_hash_table *htab;
bfd *dynobj;
- asection *s;
+ asection *s, *srel;
dynobj = elf_hash_table (info)->dynobj;
/* We must generate a R_C6000_COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the
runtime process image. */
+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+ {
+ s = htab->elf.sdynrelro;
+ srel = htab->elf.sreldynrelro;
+ }
+ else
+ {
+ s = htab->elf.sdynbss;
+ srel = htab->elf.srelbss;
+ }
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
{
- htab->srelbss->size += sizeof (Elf32_External_Rela);
+ srel->size += sizeof (Elf32_External_Rela);
h->needs_copy = 1;
}
- s = htab->sdynbss;
-
return _bfd_elf_adjust_dynamic_copy (info, h, s);
}
goto done_reloc;
}
}
+ /* Fall through. */
case R_C6000_PCR_S12:
case R_C6000_PCR_S10:
allowed to pass us these kinds of things. */
if (h == NULL)
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s with non-zero addend %d"
" against local symbol"),
input_bfd,
rel->r_addend);
else
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B, section %A: relocation %s with non-zero addend %d"
" against symbol `%s'"),
input_bfd,
/* Invalid in relocatable object. */
default:
/* Unknown relocation. */
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: invalid relocation type %d"),
input_bfd, r_type);
ok = FALSE;
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: bad symbol index: %d"),
abfd, r_symndx);
return FALSE;
/* PR15323, ref flags aren't set for references in the same
object. */
- h->root.non_ir_ref = 1;
+ h->root.non_ir_ref_regular = 1;
}
switch (r_type)
else if (s == htab->elf.splt
|| s == htab->elf.sgot
|| s == htab->elf.sgotplt
- || s == htab->sdynbss)
+ || s == htab->elf.sdynbss
+ || s == htab->elf.sdynrelro)
{
/* Strip this section if we don't need it; see the
comment below. */
if ((tag & 127) < 64)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: error: unknown mandatory EABI object attribute %d"),
abfd, tag);
bfd_set_error (bfd_error_bad_value);
else
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("%B: warning: unknown EABI object attribute %d"),
abfd, tag);
return TRUE;
succeeded, FALSE otherwise. */
static bfd_boolean
-elf32_tic6x_merge_attributes (bfd *ibfd, bfd *obfd)
+elf32_tic6x_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
bfd_boolean result = TRUE;
obj_attribute *in_attr;
obj_attribute *out_attr;
< in_attr[Tag_ABI_stack_align_needed].i)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("error: %B requires more stack alignment than %B preserves"),
ibfd, obfd);
result = FALSE;
< out_attr[Tag_ABI_stack_align_needed].i)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("error: %B requires more stack alignment than %B preserves"),
obfd, ibfd);
result = FALSE;
if (array_align_out < array_expect_in)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("error: %B requires more array alignment than %B preserves"),
ibfd, obfd);
result = FALSE;
if (array_align_in < array_expect_out)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("error: %B requires more array alignment than %B preserves"),
obfd, ibfd);
result = FALSE;
&& out_attr[i].i != in_attr[i].i)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("warning: %B and %B differ in wchar_t size"), obfd, ibfd);
}
break;
if (out_attr[i].i != in_attr[i].i)
{
_bfd_error_handler
+ /* xgettext:c-format */
(_("warning: %B and %B differ in whether code is "
"compiled for DSBT"),
obfd, ibfd);
}
/* Merge Tag_ABI_compatibility attributes and any common GNU ones. */
- if (!_bfd_elf_merge_object_attributes (ibfd, obfd))
+ if (!_bfd_elf_merge_object_attributes (ibfd, info))
return FALSE;
result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
}
static bfd_boolean
-elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+elf32_tic6x_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
- if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ if (!_bfd_generic_verify_endian_match (ibfd, info))
return FALSE;
- if (! is_tic6x_elf (ibfd) || ! is_tic6x_elf (obfd))
+ if (! is_tic6x_elf (ibfd) || ! is_tic6x_elf (info->output_bfd))
return TRUE;
- if (!elf32_tic6x_merge_attributes (ibfd, obfd))
+ if (!elf32_tic6x_merge_attributes (ibfd, info))
return FALSE;
return TRUE;
#define elf_backend_can_refcount 1
#define elf_backend_want_got_plt 1
#define elf_backend_want_dynbss 1
+#define elf_backend_want_dynrelro 1
#define elf_backend_plt_readonly 1
#define elf_backend_rela_normal 1
#define elf_backend_got_header_size 8