|
|
|
@ -3713,10 +3713,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
|
|
|
|
|
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++)
|
|
|
|
|
{
|
|
|
|
@ -3998,7 +3998,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
@ -4580,7 +4580,7 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
@ -4694,21 +4694,17 @@ static bfd_boolean
|
|
|
|
|
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
|
|
|
|
@ -4718,8 +4714,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
|
|
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++)
|
|
|
|
@ -4778,26 +4772,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *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
|
|
|
|
@ -4856,11 +4830,7 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
|
|
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)
|
|
|
|
@ -4870,6 +4840,10 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
|
|
}
|
|
|
|
|
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:
|
|
|
|
@ -4925,8 +4899,11 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
@ -5291,8 +5268,8 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
@ -5303,24 +5280,22 @@ static bfd_boolean
|
|
|
|
|
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);
|
|
|
|
@ -5329,7 +5304,7 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
@ -5413,8 +5388,9 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
@ -5424,9 +5400,10 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
@ -5447,7 +5424,7 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|
|
|
|
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
|
|
|
|
@ -5834,18 +5811,16 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
@ -5953,21 +5928,19 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
@ -5980,51 +5953,37 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
|
|
of the dynobj section names depend upon the input files. */
|
|
|
|
|
name = bfd_get_section_name (dynobj, s);
|
|
|
|
|
|
|
|
|
|
if (s == htab->root.splt)
|
|
|
|
|
{
|
|
|
|
|
/* 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 (s == htab->root.sgot
|
|
|
|
|
|| s == htab->root.sgotplt)
|
|
|
|
|
else if (s == htab->root.splt)
|
|
|
|
|
{
|
|
|
|
|
if (s->size != 0)
|
|
|
|
|
got = TRUE;
|
|
|
|
|
/* 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->root.sdynbss
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
@ -6033,11 +5992,6 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
|
|
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;
|
|
|
|
@ -6048,7 +6002,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
|
|
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
|
|
|
|
@ -6061,10 +6015,11 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
|
|
|
|
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)))
|
|
|
|
@ -6171,8 +6126,6 @@ nios2_elf_add_symbol_hook (bfd *abfd,
|
|
|
|
|
asection **secp,
|
|
|
|
|
bfd_vma *valp)
|
|
|
|
|
{
|
|
|
|
|
bfd *dynobj;
|
|
|
|
|
|
|
|
|
|
if (sym->st_shndx == SHN_COMMON
|
|
|
|
|
&& !bfd_link_relocatable (info)
|
|
|
|
|
&& sym->st_size <= elf_gp_size (abfd)
|
|
|
|
@ -6187,12 +6140,11 @@ nios2_elf_add_symbol_hook (bfd *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;
|
|
|
|
|
}
|
|
|
|
|