Nios2 dynobj handling fixes
A number of places in elf32-nios.c created dynamic sections but didn't set the hash table dynobj. That meant we could have duplicate dynamic sections connected to a number of bfds, so size_dynamic_sections didn't properly discard or allocate contents. Also, the entire set of dynamic sections was created in check_relocs on seeing GOT relocs, when only .got related sections are needed, probably done to hide segfaults later in finish_dynamic_sections. The patch fixes these issues and makes the assembler emit errors when nios2 lacks the necessary pc-relative relocs for subtraction expressions, rather than silently generating bad code. eg. ld-elf/merge. I've also tidied uses of elf32_nios2_hash_table and elf_hash_table. bfd/ PR 20995 * elf32-nios2.c (nios2_elf32_relocate_section): Use htab rather than elf32_nios2_hash_table or elf_hash_table. (create_got_section): Likewise. (nios2_elf32_finish_dynamic_symbol): Likewise. (nios2_elf32_adjust_dynamic_symbol): Likewise. (nios2_elf32_size_dynamic_sections): Likewise. (nios2_elf32_check_relocs): Delete dynobj, sgot, and srelgot vars. Use htab equivalents directly instead. Don't create all dynamic sections on needing just the GOT. Use a goto rather than a fall-through with reloc test. Ensure htab->dynobj is set when making dynamic sreloc section. (nios2_elf32_finish_dynamic_sections): Delete dynobj, use htab equivalent directly instead. Don't segfault on looking for .dynamic when dynamic sections have not been created. Don't segfault on .got.plt being discarded. (nios2_elf32_size_dynamic_sections): Delete plt and got vars. Don't set "relocs" on .rela.plt. Do handle .sbss. Delete fixme and another not so relevant comment. (nios2_elf_add_symbol_hook): Delete dynobj var. If not already set, set hash table dynobj on creating .sbss. gas/ * config/tc-nios2.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define. ld/ * testsuite/ld-elf/merge.d: xfail for nios.
This commit is contained in:
parent
7ba71655a4
commit
4ef97a1b45
6 changed files with 94 additions and 102 deletions
|
@ -1,3 +1,27 @@
|
||||||
|
2017-02-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 20995
|
||||||
|
* elf32-nios2.c (nios2_elf32_relocate_section): Use htab
|
||||||
|
rather than elf32_nios2_hash_table or elf_hash_table.
|
||||||
|
(create_got_section): Likewise.
|
||||||
|
(nios2_elf32_finish_dynamic_symbol): Likewise.
|
||||||
|
(nios2_elf32_adjust_dynamic_symbol): Likewise.
|
||||||
|
(nios2_elf32_size_dynamic_sections): Likewise.
|
||||||
|
(nios2_elf32_check_relocs): Delete dynobj, sgot, and srelgot
|
||||||
|
vars. Use htab equivalents directly instead. Don't create
|
||||||
|
all dynamic sections on needing just the GOT. Use a goto
|
||||||
|
rather than a fall-through with reloc test. Ensure
|
||||||
|
htab->dynobj is set when making dynamic sreloc section.
|
||||||
|
(nios2_elf32_finish_dynamic_sections): Delete dynobj, use htab
|
||||||
|
equivalent directly instead. Don't segfault on looking for
|
||||||
|
.dynamic when dynamic sections have not been created. Don't
|
||||||
|
segfault on .got.plt being discarded.
|
||||||
|
(nios2_elf32_size_dynamic_sections): Delete plt and got vars.
|
||||||
|
Don't set "relocs" on .rela.plt. Do handle .sbss. Delete
|
||||||
|
fixme and another not so relevant comment.
|
||||||
|
(nios2_elf_add_symbol_hook): Delete dynobj var. If not
|
||||||
|
already set, set hash table dynobj on creating .sbss.
|
||||||
|
|
||||||
2017-02-28 Alan Modra <amodra@gmail.com>
|
2017-02-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* reloc.c (BFD_RELOC_PPC_16DX_HA): New.
|
* reloc.c (BFD_RELOC_PPC_16DX_HA): New.
|
||||||
|
|
|
@ -3713,10 +3713,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
|
||||||
splt = htab->root.splt;
|
splt = htab->root.splt;
|
||||||
local_got_offsets = elf_local_got_offsets (input_bfd);
|
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;
|
got_base = 0;
|
||||||
else
|
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++)
|
for (rel = relocs; rel < relend; rel++)
|
||||||
{
|
{
|
||||||
|
@ -3998,7 +3998,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
|
||||||
|
|
||||||
off = h->got.offset;
|
off = h->got.offset;
|
||||||
BFD_ASSERT (off != (bfd_vma) -1);
|
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,
|
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
|
||||||
bfd_link_pic (info),
|
bfd_link_pic (info),
|
||||||
h)
|
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. */
|
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,
|
h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,
|
||||||
"_gp_got");
|
"_gp_got");
|
||||||
elf32_nios2_hash_table (info)->h_gp_got = h;
|
htab->h_gp_got = h;
|
||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -4694,21 +4694,17 @@ static bfd_boolean
|
||||||
nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||||
asection *sec, const Elf_Internal_Rela *relocs)
|
asection *sec, const Elf_Internal_Rela *relocs)
|
||||||
{
|
{
|
||||||
bfd *dynobj;
|
|
||||||
Elf_Internal_Shdr *symtab_hdr;
|
Elf_Internal_Shdr *symtab_hdr;
|
||||||
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
|
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
|
||||||
const Elf_Internal_Rela *rel;
|
const Elf_Internal_Rela *rel;
|
||||||
const Elf_Internal_Rela *rel_end;
|
const Elf_Internal_Rela *rel_end;
|
||||||
struct elf32_nios2_link_hash_table *htab;
|
struct elf32_nios2_link_hash_table *htab;
|
||||||
asection *sgot;
|
|
||||||
asection *srelgot;
|
|
||||||
asection *sreloc = NULL;
|
asection *sreloc = NULL;
|
||||||
bfd_signed_vma *local_got_refcounts;
|
bfd_signed_vma *local_got_refcounts;
|
||||||
|
|
||||||
if (bfd_link_relocatable (info))
|
if (bfd_link_relocatable (info))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
dynobj = elf_hash_table (info)->dynobj;
|
|
||||||
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||||
sym_hashes = elf_sym_hashes (abfd);
|
sym_hashes = elf_sym_hashes (abfd);
|
||||||
sym_hashes_end = (sym_hashes
|
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);
|
local_got_refcounts = elf_local_got_refcounts (abfd);
|
||||||
|
|
||||||
htab = elf32_nios2_hash_table (info);
|
htab = elf32_nios2_hash_table (info);
|
||||||
sgot = htab->root.sgot;
|
|
||||||
srelgot = htab->root.srelgot;
|
|
||||||
|
|
||||||
rel_end = relocs + sec->reloc_count;
|
rel_end = relocs + sec->reloc_count;
|
||||||
for (rel = relocs; rel < rel_end; rel++)
|
for (rel = relocs; rel < rel_end; rel++)
|
||||||
|
@ -4778,26 +4772,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||||
break;
|
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)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
struct elf32_nios2_link_hash_entry *eh
|
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;
|
elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Fall through */
|
make_got:
|
||||||
case R_NIOS2_TLS_LDM16:
|
|
||||||
if (r_type == R_NIOS2_TLS_LDM16)
|
|
||||||
htab->tls_ldm_got.refcount++;
|
|
||||||
|
|
||||||
if (htab->root.sgot == NULL)
|
if (htab->root.sgot == NULL)
|
||||||
{
|
{
|
||||||
if (htab->root.dynobj == NULL)
|
if (htab->root.dynobj == NULL)
|
||||||
|
@ -4870,6 +4840,10 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case R_NIOS2_TLS_LDM16:
|
||||||
|
htab->tls_ldm_got.refcount++;
|
||||||
|
goto make_got;
|
||||||
|
|
||||||
/* This relocation describes the C++ object vtable hierarchy.
|
/* This relocation describes the C++ object vtable hierarchy.
|
||||||
Reconstruct it for later use during GC. */
|
Reconstruct it for later use during GC. */
|
||||||
case R_NIOS2_GNU_VTINHERIT:
|
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. */
|
section in dynobj and make room for this reloc. */
|
||||||
if (sreloc == NULL)
|
if (sreloc == NULL)
|
||||||
{
|
{
|
||||||
|
if (htab->root.dynobj == NULL)
|
||||||
|
htab->root.dynobj = abfd;
|
||||||
|
|
||||||
sreloc = _bfd_elf_make_dynamic_reloc_section
|
sreloc = _bfd_elf_make_dynamic_reloc_section
|
||||||
(sec, dynobj, 2, abfd, TRUE);
|
(sec, htab->root.dynobj, 2, abfd, TRUE);
|
||||||
if (sreloc == NULL)
|
if (sreloc == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -5291,8 +5268,8 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
|
||||||
|
|
||||||
/* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute. */
|
/* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute. */
|
||||||
if (strcmp (h->root.root.string, "_DYNAMIC") == 0
|
if (strcmp (h->root.root.string, "_DYNAMIC") == 0
|
||||||
|| h == elf_hash_table (info)->hgot
|
|| h == htab->root.hgot
|
||||||
|| h == elf32_nios2_hash_table (info)->h_gp_got)
|
|| h == htab->h_gp_got)
|
||||||
sym->st_shndx = SHN_ABS;
|
sym->st_shndx = SHN_ABS;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -5303,24 +5280,22 @@ static bfd_boolean
|
||||||
nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
|
nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
|
||||||
struct bfd_link_info *info)
|
struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
bfd *dynobj;
|
|
||||||
asection *sgotplt;
|
asection *sgotplt;
|
||||||
asection *sdyn;
|
asection *sdyn;
|
||||||
struct elf32_nios2_link_hash_table *htab;
|
struct elf32_nios2_link_hash_table *htab;
|
||||||
|
|
||||||
htab = elf32_nios2_hash_table (info);
|
htab = elf32_nios2_hash_table (info);
|
||||||
dynobj = elf_hash_table (info)->dynobj;
|
|
||||||
sgotplt = htab->root.sgotplt;
|
sgotplt = htab->root.sgotplt;
|
||||||
BFD_ASSERT (sgotplt != NULL);
|
sdyn = NULL;
|
||||||
sdyn = bfd_get_linker_section (dynobj, ".dynamic");
|
|
||||||
|
|
||||||
if (elf_hash_table (info)->dynamic_sections_created)
|
if (htab->root.dynamic_sections_created)
|
||||||
{
|
{
|
||||||
asection *splt;
|
asection *splt;
|
||||||
Elf32_External_Dyn *dyncon, *dynconend;
|
Elf32_External_Dyn *dyncon, *dynconend;
|
||||||
|
|
||||||
splt = htab->root.splt;
|
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;
|
dyncon = (Elf32_External_Dyn *) sdyn->contents;
|
||||||
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
|
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
|
||||||
|
@ -5329,7 +5304,7 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
|
||||||
Elf_Internal_Dyn dyn;
|
Elf_Internal_Dyn dyn;
|
||||||
asection *s;
|
asection *s;
|
||||||
|
|
||||||
bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
|
bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
|
||||||
|
|
||||||
switch (dyn.d_tag)
|
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. */
|
/* Fill in the first three entries in the global offset table. */
|
||||||
if (sgotplt->size > 0)
|
if (sgotplt != NULL && sgotplt->size > 0)
|
||||||
{
|
{
|
||||||
if (sdyn == NULL)
|
if (sdyn == NULL)
|
||||||
bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
|
bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
|
||||||
|
@ -5424,9 +5400,10 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
|
||||||
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 + 4);
|
||||||
bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
|
bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
|
||||||
}
|
|
||||||
|
|
||||||
|
if (sgotplt->output_section != bfd_abs_section_ptr)
|
||||||
elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
|
elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -5447,7 +5424,7 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
|
||||||
unsigned align2;
|
unsigned align2;
|
||||||
|
|
||||||
htab = elf32_nios2_hash_table (info);
|
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. */
|
/* Make sure we know what is going on here. */
|
||||||
BFD_ASSERT (dynobj != NULL
|
BFD_ASSERT (dynobj != NULL
|
||||||
|
@ -5834,18 +5811,16 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
{
|
{
|
||||||
bfd *dynobj;
|
bfd *dynobj;
|
||||||
asection *s;
|
asection *s;
|
||||||
bfd_boolean plt;
|
|
||||||
bfd_boolean got;
|
|
||||||
bfd_boolean relocs;
|
bfd_boolean relocs;
|
||||||
bfd *ibfd;
|
bfd *ibfd;
|
||||||
struct elf32_nios2_link_hash_table *htab;
|
struct elf32_nios2_link_hash_table *htab;
|
||||||
|
|
||||||
htab = elf32_nios2_hash_table (info);
|
htab = elf32_nios2_hash_table (info);
|
||||||
dynobj = elf_hash_table (info)->dynobj;
|
dynobj = htab->root.dynobj;
|
||||||
BFD_ASSERT (dynobj != NULL);
|
BFD_ASSERT (dynobj != NULL);
|
||||||
|
|
||||||
htab->res_n_size = 0;
|
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. */
|
/* Set the contents of the .interp section to the interpreter. */
|
||||||
if (bfd_link_executable (info) && !info->nointerp)
|
if (bfd_link_executable (info) && !info->nointerp)
|
||||||
|
@ -5953,21 +5928,19 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
sym dynamic relocs. */
|
sym dynamic relocs. */
|
||||||
elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
|
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
|
/* If the .got section is more than 0x8000 bytes, we add
|
||||||
0x8000 to the value of _gp_got, so that 16-bit relocations
|
0x8000 to the value of _gp_got, so that 16-bit relocations
|
||||||
have a greater chance of working. */
|
have a greater chance of working. */
|
||||||
if (htab->root.sgot->size >= 0x8000
|
if (htab->root.sgot->size >= 0x8000
|
||||||
&& elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value == 0)
|
&& htab->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 = 0x8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The check_relocs and adjust_dynamic_symbol entry points have
|
/* The check_relocs and adjust_dynamic_symbol entry points have
|
||||||
determined the sizes of the various dynamic sections. Allocate
|
determined the sizes of the various dynamic sections. Allocate
|
||||||
memory for them. */
|
memory for them. */
|
||||||
plt = FALSE;
|
|
||||||
got = FALSE;
|
|
||||||
relocs = FALSE;
|
relocs = FALSE;
|
||||||
for (s = dynobj->sections; s != NULL; s = s->next)
|
for (s = dynobj->sections; s != NULL; s = s->next)
|
||||||
{
|
{
|
||||||
|
@ -5980,22 +5953,11 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
of the dynobj section names depend upon the input files. */
|
of the dynobj section names depend upon the input files. */
|
||||||
name = bfd_get_section_name (dynobj, s);
|
name = bfd_get_section_name (dynobj, s);
|
||||||
|
|
||||||
if (s == htab->root.splt)
|
if (CONST_STRNEQ (name, ".rela"))
|
||||||
{
|
|
||||||
/* 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 (s->size != 0)
|
if (s->size != 0)
|
||||||
{
|
{
|
||||||
|
if (s != htab->root.srelplt)
|
||||||
relocs = TRUE;
|
relocs = TRUE;
|
||||||
|
|
||||||
/* We use the reloc_count field as a counter if we need
|
/* We use the reloc_count field as a counter if we need
|
||||||
|
@ -6003,28 +5965,25 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
s->reloc_count = 0;
|
s->reloc_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (s == htab->root.sgot
|
else if (s == htab->root.splt)
|
||||||
|| s == htab->root.sgotplt)
|
|
||||||
{
|
{
|
||||||
if (s->size != 0)
|
/* Correct for the number of res_N branches. */
|
||||||
got = TRUE;
|
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)
|
&& s != htab->root.sdynrelro)
|
||||||
/* It's not one of our sections, so don't allocate space. */
|
/* It's not one of our sections, so don't allocate space. */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (s->size == 0)
|
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;
|
s->flags |= SEC_EXCLUDE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -6033,11 +5992,6 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Allocate memory for the section contents. */
|
/* 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);
|
s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
|
||||||
if (s->contents == NULL)
|
if (s->contents == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -6048,7 +6002,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
if (htab->res_n_size)
|
if (htab->res_n_size)
|
||||||
elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);
|
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
|
/* Add some entries to the .dynamic section. We fill in the
|
||||||
values later, in elf_nios2_finish_dynamic_sections, but we
|
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))
|
if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (got && !add_dynamic_entry (DT_PLTGOT, 0))
|
if (htab->root.sgotplt->size != 0
|
||||||
|
&& !add_dynamic_entry (DT_PLTGOT, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (plt
|
if (htab->root.splt->size != 0
|
||||||
&& (!add_dynamic_entry (DT_PLTRELSZ, 0)
|
&& (!add_dynamic_entry (DT_PLTRELSZ, 0)
|
||||||
|| !add_dynamic_entry (DT_PLTREL, DT_RELA)
|
|| !add_dynamic_entry (DT_PLTREL, DT_RELA)
|
||||||
|| !add_dynamic_entry (DT_JMPREL, 0)))
|
|| !add_dynamic_entry (DT_JMPREL, 0)))
|
||||||
|
@ -6171,8 +6126,6 @@ nios2_elf_add_symbol_hook (bfd *abfd,
|
||||||
asection **secp,
|
asection **secp,
|
||||||
bfd_vma *valp)
|
bfd_vma *valp)
|
||||||
{
|
{
|
||||||
bfd *dynobj;
|
|
||||||
|
|
||||||
if (sym->st_shndx == SHN_COMMON
|
if (sym->st_shndx == SHN_COMMON
|
||||||
&& !bfd_link_relocatable (info)
|
&& !bfd_link_relocatable (info)
|
||||||
&& sym->st_size <= elf_gp_size (abfd)
|
&& 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;
|
flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
|
||||||
|
|
||||||
dynobj = elf_hash_table (info)->dynobj;
|
if (htab->root.dynobj == NULL)
|
||||||
if (!dynobj)
|
htab->root.dynobj = abfd;
|
||||||
dynobj = abfd;
|
|
||||||
|
|
||||||
htab->sbss = bfd_make_section_anyway_with_flags (dynobj, ".sbss",
|
htab->sbss = bfd_make_section_anyway_with_flags (htab->root.dynobj,
|
||||||
flags);
|
".sbss", flags);
|
||||||
if (htab->sbss == NULL)
|
if (htab->sbss == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2017-02-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* config/tc-nios2.h (TC_FORCE_RELOCATION_SUB_LOCAL): Define.
|
||||||
|
|
||||||
2017-02-28 Alan Modra <amodra@gmail.com>
|
2017-02-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* config/tc-ppc.c (md_assemble): Use BFD_RELOC_PPC_16DX_HA for addpcis.
|
* config/tc-ppc.c (md_assemble): Use BFD_RELOC_PPC_16DX_HA for addpcis.
|
||||||
|
|
|
@ -101,6 +101,14 @@ extern flagword nios2_elf_section_flags (flagword, int, int);
|
||||||
|
|
||||||
#define DIFF_EXPR_OK
|
#define DIFF_EXPR_OK
|
||||||
|
|
||||||
|
/* Don't allow the generic code to convert fixups involving the
|
||||||
|
subtraction of a label in the current section to pc-relative if we
|
||||||
|
don't have the necessary pc-relative relocation. */
|
||||||
|
#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \
|
||||||
|
(!((FIX)->fx_r_type == BFD_RELOC_16 \
|
||||||
|
|| (FIX)->fx_r_type == BFD_RELOC_NIOS2_LO16 \
|
||||||
|
|| (FIX)->fx_r_type == BFD_RELOC_NIOS2_HIADJ16))
|
||||||
|
|
||||||
/* Nios2 ABI doesn't have 32-bit PCREL relocation, and, as relocations for
|
/* Nios2 ABI doesn't have 32-bit PCREL relocation, and, as relocations for
|
||||||
CFI information will be in section other than .text, we can't use PC-biased
|
CFI information will be in section other than .text, we can't use PC-biased
|
||||||
relocs. */
|
relocs. */
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2017-02-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* testsuite/ld-elf/merge.d: xfail for nios.
|
||||||
|
|
||||||
2017-02-28 Alan Modra <amodra@gmail.com>
|
2017-02-28 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* testsuite/ld-powerpc/addpcis.d: Define ext1 and ext2 at
|
* testsuite/ld-powerpc/addpcis.d: Define ext1 and ext2 at
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#xfail: "bfin-*-*" "cr16-*-*" "cris*-*-*" "crx-*-*" "d10v-*-*" "d30v-*-*"
|
#xfail: "bfin-*-*" "cr16-*-*" "cris*-*-*" "crx-*-*" "d10v-*-*" "d30v-*-*"
|
||||||
#xfail: "dlx-*-*" "fr30-*-*" "frv-*-*" "hppa*64*-*-*" "h8300-*-*" "score-*-*"
|
#xfail: "dlx-*-*" "fr30-*-*" "frv-*-*" "hppa*64*-*-*" "h8300-*-*" "score-*-*"
|
||||||
#xfail: "i370-*-*" "i860-*-*" "i960-*-*" "ip2k-*-*" "iq2000-*-*" "lm32-*-*"
|
#xfail: "i370-*-*" "i860-*-*" "i960-*-*" "ip2k-*-*" "iq2000-*-*" "lm32-*-*"
|
||||||
#xfail: "mcore-*-*" "mn102*-*-*" "ms1-*-*" "mep-*-*" "m68hc11-*-*"
|
#xfail: "mcore-*-*" "mn102*-*-*" "ms1-*-*" "mep-*-*" "m68hc11-*-*" "nios2-*-*"
|
||||||
#xfail: "or32-*-*" "pj-*-*" "sparc*-*-*" "tic6x-*-*" "vax-*-*" "xstormy16-*-*"
|
#xfail: "or32-*-*" "pj-*-*" "sparc*-*-*" "tic6x-*-*" "vax-*-*" "xstormy16-*-*"
|
||||||
#xfail: "xtensa*-*-*" "metag-*-*" "ft32-*-*" "pru-*-*"
|
#xfail: "xtensa*-*-*" "metag-*-*" "ft32-*-*" "pru-*-*"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue