/* 32-bit ELF support for Nios II.
- Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ Copyright (C) 2012-2017 Free Software Foundation, Inc.
Contributed by Nigel Gray (ngray@altera.com).
Contributed by Mentor Graphics, Inc.
splt = htab->root.splt;
local_got_offsets = elf_local_got_offsets (input_bfd);
- if (elf32_nios2_hash_table (info)->h_gp_got == NULL)
+ if (htab->h_gp_got == NULL)
got_base = 0;
else
- got_base = elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value;
+ got_base = htab->h_gp_got->root.u.def.value;
for (rel = relocs; rel < relend; rel++)
{
off = h->got.offset;
BFD_ASSERT (off != (bfd_vma) -1);
- dyn = elf_hash_table (info)->dynamic_sections_created;
+ dyn = htab->root.dynamic_sections_created;
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
bfd_link_pic (info),
h)
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not "
+ (_("%B(%A+%#Lx): %s relocation not "
"permitted in shared object"),
input_bfd, input_section,
- (long) rel->r_offset, howto->name);
+ rel->r_offset, howto->name);
return FALSE;
}
else
points to the base of the GOT while _gp_got may include a bias. */
h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,
"_gp_got");
- elf32_nios2_hash_table (info)->h_gp_got = h;
+ htab->h_gp_got = h;
if (h == NULL)
return FALSE;
nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
asection *sec, const Elf_Internal_Rela *relocs)
{
- bfd *dynobj;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
struct elf32_nios2_link_hash_table *htab;
- asection *sgot;
- asection *srelgot;
asection *sreloc = NULL;
bfd_signed_vma *local_got_refcounts;
if (bfd_link_relocatable (info))
return TRUE;
- dynobj = elf_hash_table (info)->dynobj;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
sym_hashes_end = (sym_hashes
local_got_refcounts = elf_local_got_refcounts (abfd);
htab = elf32_nios2_hash_table (info);
- sgot = htab->root.sgot;
- srelgot = htab->root.srelgot;
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
/* 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;
}
r_type = ELF32_R_TYPE (rel->r_info);
break;
}
- if (dynobj == NULL)
- {
- /* Create the .got section. */
- elf_hash_table (info)->dynobj = dynobj = abfd;
- nios2_elf32_create_dynamic_sections (dynobj, info);
- }
-
- if (sgot == NULL)
- {
- sgot = htab->root.sgot;
- BFD_ASSERT (sgot != NULL);
- }
-
- if (srelgot == NULL
- && (h != NULL || bfd_link_pic (info)))
- {
- srelgot = htab->root.srelgot;
- BFD_ASSERT (srelgot != NULL);
- }
-
if (h != NULL)
{
struct elf32_nios2_link_hash_entry *eh
elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;
}
}
- /* Fall through */
- case R_NIOS2_TLS_LDM16:
- if (r_type == R_NIOS2_TLS_LDM16)
- htab->tls_ldm_got.refcount++;
-
+ make_got:
if (htab->root.sgot == NULL)
{
if (htab->root.dynobj == NULL)
}
break;
+ case R_NIOS2_TLS_LDM16:
+ htab->tls_ldm_got.refcount++;
+ goto make_got;
+
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_NIOS2_GNU_VTINHERIT:
section in dynobj and make room for this reloc. */
if (sreloc == NULL)
{
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+
sreloc = _bfd_elf_make_dynamic_reloc_section
- (sec, dynobj, 2, abfd, TRUE);
+ (sec, htab->root.dynobj, 2, abfd, TRUE);
if (sreloc == NULL)
return FALSE;
}
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- s = htab->root.srelbss;
- BFD_ASSERT (s != NULL);
-
rela.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_COPY);
rela.r_addend = 0;
+ if (h->root.u.def.section == htab->root.sdynrelro)
+ s = htab->root.sreldynrelro;
+ else
+ s = htab->root.srelbss;
+ BFD_ASSERT (s != NULL);
loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
}
/* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute. */
if (strcmp (h->root.root.string, "_DYNAMIC") == 0
- || h == elf_hash_table (info)->hgot
- || h == elf32_nios2_hash_table (info)->h_gp_got)
+ || h == htab->root.hgot
+ || h == htab->h_gp_got)
sym->st_shndx = SHN_ABS;
return TRUE;
nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
- bfd *dynobj;
asection *sgotplt;
asection *sdyn;
struct elf32_nios2_link_hash_table *htab;
htab = elf32_nios2_hash_table (info);
- dynobj = elf_hash_table (info)->dynobj;
sgotplt = htab->root.sgotplt;
- BFD_ASSERT (sgotplt != NULL);
- sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ sdyn = NULL;
- if (elf_hash_table (info)->dynamic_sections_created)
+ if (htab->root.dynamic_sections_created)
{
asection *splt;
Elf32_External_Dyn *dyncon, *dynconend;
splt = htab->root.splt;
- BFD_ASSERT (splt != NULL && sdyn != NULL);
+ sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic");
+ BFD_ASSERT (splt != NULL && sdyn != NULL && sgotplt != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
Elf_Internal_Dyn dyn;
asection *s;
- bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+ bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
switch (dyn.d_tag)
{
}
}
}
+
/* Fill in the first three entries in the global offset table. */
- if (sgotplt->size > 0)
+ if (sgotplt != NULL && sgotplt->size > 0)
{
if (sdyn == NULL)
bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
sgotplt->contents);
bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
- }
- elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+ if (sgotplt->output_section != bfd_abs_section_ptr)
+ elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+ }
return TRUE;
}
{
struct elf32_nios2_link_hash_table *htab;
bfd *dynobj;
- asection *s;
+ asection *s, *srel;
unsigned align2;
htab = elf32_nios2_hash_table (info);
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
/* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL
determine the address it must put in the global offset table, so
both the dynamic object and the regular object will refer to the
same memory location for the variable. */
- s = htab->root.sdynbss;
- BFD_ASSERT (s != NULL);
-
/* We must generate a R_NIOS2_COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the
runtime process image. We need to remember the offset into the
.rela.bss section we are going to use. */
- if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
{
- asection *srel;
-
+ s = htab->root.sdynrelro;
+ srel = htab->root.sreldynrelro;
+ }
+ else
+ {
+ s = htab->root.sdynbss;
srel = htab->root.srelbss;
- BFD_ASSERT (srel != NULL);
+ }
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
srel->size += sizeof (Elf32_External_Rela);
h->needs_copy = 1;
}
{
bfd *dynobj;
asection *s;
- bfd_boolean plt;
- bfd_boolean got;
bfd_boolean relocs;
bfd *ibfd;
struct elf32_nios2_link_hash_table *htab;
htab = elf32_nios2_hash_table (info);
- dynobj = elf_hash_table (info)->dynobj;
+ dynobj = htab->root.dynobj;
BFD_ASSERT (dynobj != NULL);
htab->res_n_size = 0;
- if (elf_hash_table (info)->dynamic_sections_created)
+ if (htab->root.dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
if (bfd_link_executable (info) && !info->nointerp)
sym dynamic relocs. */
elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
- if (elf_hash_table (info)->dynamic_sections_created)
+ if (htab->root.dynamic_sections_created)
{
/* If the .got section is more than 0x8000 bytes, we add
0x8000 to the value of _gp_got, so that 16-bit relocations
have a greater chance of working. */
if (htab->root.sgot->size >= 0x8000
- && elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value == 0)
- elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value = 0x8000;
+ && htab->h_gp_got->root.u.def.value == 0)
+ htab->h_gp_got->root.u.def.value = 0x8000;
}
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
- plt = FALSE;
- got = FALSE;
relocs = FALSE;
for (s = dynobj->sections; s != NULL; s = s->next)
{
of the dynobj section names depend upon the input files. */
name = bfd_get_section_name (dynobj, s);
- if (strcmp (name, ".plt") == 0)
- {
- /* Remember whether there is a PLT. */
- plt = s->size != 0;
-
- /* Correct for the number of res_N branches. */
- if (plt && !bfd_link_pic (info))
- {
- htab->res_n_size = (s->size-28) / 3;
- s->size += htab->res_n_size;
- }
- }
- else if (CONST_STRNEQ (name, ".rela"))
+ if (CONST_STRNEQ (name, ".rela"))
{
if (s->size != 0)
{
- relocs = TRUE;
+ if (s != htab->root.srelplt)
+ relocs = TRUE;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
s->reloc_count = 0;
}
}
- else if (CONST_STRNEQ (name, ".got"))
- got = s->size != 0;
- else if (strcmp (name, ".dynbss") != 0)
+ else if (s == htab->root.splt)
+ {
+ /* Correct for the number of res_N branches. */
+ if (s->size != 0 && !bfd_link_pic (info))
+ {
+ htab->res_n_size = (s->size - 28) / 3;
+ s->size += htab->res_n_size;
+ }
+ }
+ else if (s != htab->sbss
+ && s != htab->root.sgot
+ && s != htab->root.sgotplt
+ && s != htab->root.sdynbss
+ && s != htab->root.sdynrelro)
/* It's not one of our sections, so don't allocate space. */
continue;
if (s->size == 0)
{
- /* If we don't need this section, strip it from the
- output file. This is mostly to handle .rela.bss and
- .rela.plt. We must create both sections in
- create_dynamic_sections, because they must be created
- before the linker maps input sections to output
- sections. The linker does that before
- adjust_dynamic_symbol is called, and it is that
- function which decides whether anything needs to go
- into these sections. */
s->flags |= SEC_EXCLUDE;
continue;
}
continue;
/* Allocate memory for the section contents. */
- /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
- Unused entries should be reclaimed before the section's contents
- are written out, but at the moment this does not happen. Thus in
- order to prevent writing out garbage, we initialize the section's
- contents to zero. */
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
if (s->contents == NULL)
return FALSE;
if (htab->res_n_size)
elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);
- if (elf_hash_table (info)->dynamic_sections_created)
+ if (htab->root.dynamic_sections_created)
{
/* Add some entries to the .dynamic section. We fill in the
values later, in elf_nios2_finish_dynamic_sections, but we
if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
- if (got && !add_dynamic_entry (DT_PLTGOT, 0))
+ if (htab->root.sgotplt->size != 0
+ && !add_dynamic_entry (DT_PLTGOT, 0))
return FALSE;
- if (plt
+ if (htab->root.splt->size != 0
&& (!add_dynamic_entry (DT_PLTRELSZ, 0)
|| !add_dynamic_entry (DT_PLTREL, DT_RELA)
|| !add_dynamic_entry (DT_JMPREL, 0)))
asection **secp,
bfd_vma *valp)
{
- bfd *dynobj;
-
if (sym->st_shndx == SHN_COMMON
&& !bfd_link_relocatable (info)
&& sym->st_size <= elf_gp_size (abfd)
{
flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
- dynobj = elf_hash_table (info)->dynobj;
- if (!dynobj)
- dynobj = abfd;
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
- htab->sbss = bfd_make_section_anyway_with_flags (dynobj, ".sbss",
- flags);
+ htab->sbss = bfd_make_section_anyway_with_flags (htab->root.dynobj,
+ ".sbss", flags);
if (htab->sbss == NULL)
return FALSE;
}
#define elf_backend_can_refcount 1
#define elf_backend_plt_readonly 1
#define elf_backend_want_got_plt 1
+#define elf_backend_want_dynrelro 1
#define elf_backend_rela_normal 1
#define elf_backend_dtrel_excludes_plt 1