* elf32-sh.c (sh_elf_relocate_section): Handle non-ELF output
BFD.
This commit is contained in:
parent
d898aefbfa
commit
e0af1f531c
2 changed files with 45 additions and 29 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2010-08-20 Maciej W. Rozycki <macro@codesourcery.com>
|
||||||
|
|
||||||
|
* elf32-sh.c (sh_elf_relocate_section): Handle non-ELF output
|
||||||
|
BFD.
|
||||||
|
|
||||||
2010-08-20 Maciej W. Rozycki <macro@codesourcery.com>
|
2010-08-20 Maciej W. Rozycki <macro@codesourcery.com>
|
||||||
|
|
||||||
* elf32-m68k.c (bfd_elf_m68k_set_target_options): Don't set GOT
|
* elf32-m68k.c (bfd_elf_m68k_set_target_options): Don't set GOT
|
||||||
|
|
|
@ -3929,47 +3929,48 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
Elf_Internal_Shdr *symtab_hdr;
|
Elf_Internal_Shdr *symtab_hdr;
|
||||||
struct elf_link_hash_entry **sym_hashes;
|
struct elf_link_hash_entry **sym_hashes;
|
||||||
Elf_Internal_Rela *rel, *relend;
|
Elf_Internal_Rela *rel, *relend;
|
||||||
bfd *dynobj;
|
bfd *dynobj = NULL;
|
||||||
bfd_vma *local_got_offsets;
|
bfd_vma *local_got_offsets;
|
||||||
asection *sgot;
|
asection *sgot = NULL;
|
||||||
asection *sgotplt;
|
asection *sgotplt = NULL;
|
||||||
asection *splt;
|
asection *splt = NULL;
|
||||||
asection *sreloc;
|
asection *sreloc = NULL;
|
||||||
asection *srelgot;
|
asection *srelgot = NULL;
|
||||||
bfd_boolean is_vxworks_tls;
|
bfd_boolean is_vxworks_tls;
|
||||||
unsigned isec_segment, got_segment, plt_segment, check_segment[2];
|
unsigned isec_segment, got_segment, plt_segment, check_segment[2];
|
||||||
|
bfd_boolean fdpic_p = FALSE;
|
||||||
|
|
||||||
BFD_ASSERT (is_sh_elf (input_bfd));
|
BFD_ASSERT (is_sh_elf (input_bfd));
|
||||||
|
|
||||||
htab = sh_elf_hash_table (info);
|
htab = sh_elf_hash_table (info);
|
||||||
if (htab == NULL)
|
if (htab != NULL)
|
||||||
return FALSE;
|
{
|
||||||
|
dynobj = htab->root.dynobj;
|
||||||
|
sgot = htab->sgot;
|
||||||
|
sgotplt = htab->sgotplt;
|
||||||
|
splt = htab->splt;
|
||||||
|
fdpic_p = htab->fdpic_p;
|
||||||
|
}
|
||||||
symtab_hdr = &elf_symtab_hdr (input_bfd);
|
symtab_hdr = &elf_symtab_hdr (input_bfd);
|
||||||
sym_hashes = elf_sym_hashes (input_bfd);
|
sym_hashes = elf_sym_hashes (input_bfd);
|
||||||
dynobj = htab->root.dynobj;
|
|
||||||
local_got_offsets = elf_local_got_offsets (input_bfd);
|
local_got_offsets = elf_local_got_offsets (input_bfd);
|
||||||
|
|
||||||
isec_segment = sh_elf_osec_to_segment (output_bfd,
|
isec_segment = sh_elf_osec_to_segment (output_bfd,
|
||||||
input_section->output_section);
|
input_section->output_section);
|
||||||
if (htab->fdpic_p && htab->sgot)
|
if (fdpic_p && sgot)
|
||||||
got_segment = sh_elf_osec_to_segment (output_bfd,
|
got_segment = sh_elf_osec_to_segment (output_bfd,
|
||||||
htab->sgot->output_section);
|
sgot->output_section);
|
||||||
else
|
else
|
||||||
got_segment = -1;
|
got_segment = -1;
|
||||||
if (htab->fdpic_p && htab->splt)
|
if (fdpic_p && splt)
|
||||||
plt_segment = sh_elf_osec_to_segment (output_bfd,
|
plt_segment = sh_elf_osec_to_segment (output_bfd,
|
||||||
htab->splt->output_section);
|
splt->output_section);
|
||||||
else
|
else
|
||||||
plt_segment = -1;
|
plt_segment = -1;
|
||||||
|
|
||||||
sgot = htab->sgot;
|
|
||||||
sgotplt = htab->sgotplt;
|
|
||||||
splt = htab->splt;
|
|
||||||
sreloc = NULL;
|
|
||||||
srelgot = NULL;
|
|
||||||
/* We have to handle relocations in vxworks .tls_vars sections
|
/* We have to handle relocations in vxworks .tls_vars sections
|
||||||
specially, because the dynamic loader is 'weird'. */
|
specially, because the dynamic loader is 'weird'. */
|
||||||
is_vxworks_tls = (htab->vxworks_p && info->shared
|
is_vxworks_tls = (htab && htab->vxworks_p && info->shared
|
||||||
&& !strcmp (input_section->output_section->name,
|
&& !strcmp (input_section->output_section->name,
|
||||||
".tls_vars"));
|
".tls_vars"));
|
||||||
|
|
||||||
|
@ -4147,7 +4148,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
{
|
{
|
||||||
bfd_boolean dyn;
|
bfd_boolean dyn;
|
||||||
|
|
||||||
dyn = htab->root.dynamic_sections_created;
|
dyn = htab ? htab->root.dynamic_sections_created : FALSE;
|
||||||
sec = h->root.u.def.section;
|
sec = h->root.u.def.section;
|
||||||
/* In these cases, we don't need the relocation value.
|
/* In these cases, we don't need the relocation value.
|
||||||
We check specially because in some obscure cases
|
We check specially because in some obscure cases
|
||||||
|
@ -4461,7 +4462,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
outrel.r_addend = addend;
|
outrel.r_addend = addend;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (htab->fdpic_p
|
else if (fdpic_p
|
||||||
&& (h == NULL
|
&& (h == NULL
|
||||||
|| ((info->symbolic || h->dynindx == -1)
|
|| ((info->symbolic || h->dynindx == -1)
|
||||||
&& h->def_regular)))
|
&& h->def_regular)))
|
||||||
|
@ -4515,12 +4516,14 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
if (! relocate)
|
if (! relocate)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (htab->fdpic_p && !info->shared
|
else if (fdpic_p && !info->shared
|
||||||
&& r_type == R_SH_DIR32
|
&& r_type == R_SH_DIR32
|
||||||
&& (input_section->flags & SEC_ALLOC) != 0)
|
&& (input_section->flags & SEC_ALLOC) != 0)
|
||||||
{
|
{
|
||||||
bfd_vma offset;
|
bfd_vma offset;
|
||||||
|
|
||||||
|
BFD_ASSERT (htab);
|
||||||
|
|
||||||
if (sh_elf_osec_readonly_p (output_bfd,
|
if (sh_elf_osec_readonly_p (output_bfd,
|
||||||
input_section->output_section))
|
input_section->output_section))
|
||||||
{
|
{
|
||||||
|
@ -4569,6 +4572,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
/* Relocation is to the entry for this symbol in the global
|
/* Relocation is to the entry for this symbol in the global
|
||||||
offset table extension for the procedure linkage table. */
|
offset table extension for the procedure linkage table. */
|
||||||
|
|
||||||
|
BFD_ASSERT (htab);
|
||||||
BFD_ASSERT (sgotplt != NULL);
|
BFD_ASSERT (sgotplt != NULL);
|
||||||
relocation = (sgotplt->output_offset
|
relocation = (sgotplt->output_offset
|
||||||
+ (get_plt_index (htab->plt_info, h->plt.offset)
|
+ (get_plt_index (htab->plt_info, h->plt.offset)
|
||||||
|
@ -4594,6 +4598,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
/* Relocation is to the entry for this symbol in the global
|
/* Relocation is to the entry for this symbol in the global
|
||||||
offset table. */
|
offset table. */
|
||||||
|
|
||||||
|
BFD_ASSERT (htab);
|
||||||
BFD_ASSERT (sgot != NULL);
|
BFD_ASSERT (sgot != NULL);
|
||||||
check_segment[0] = check_segment[1] = -1;
|
check_segment[0] = check_segment[1] = -1;
|
||||||
|
|
||||||
|
@ -4652,7 +4657,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
|
|
||||||
/* If we initialize the GOT entry here with a valid
|
/* If we initialize the GOT entry here with a valid
|
||||||
symbol address, also add a fixup. */
|
symbol address, also add a fixup. */
|
||||||
if (htab->fdpic_p && !info->shared
|
if (fdpic_p && !info->shared
|
||||||
&& sh_elf_hash_entry (h)->got_type == GOT_NORMAL
|
&& sh_elf_hash_entry (h)->got_type == GOT_NORMAL
|
||||||
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||||
|| h->root.type != bfd_link_hash_undefweak))
|
|| h->root.type != bfd_link_hash_undefweak))
|
||||||
|
@ -4713,7 +4718,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
outrel.r_offset = (sgot->output_section->vma
|
outrel.r_offset = (sgot->output_section->vma
|
||||||
+ sgot->output_offset
|
+ sgot->output_offset
|
||||||
+ off);
|
+ off);
|
||||||
if (htab->fdpic_p)
|
if (fdpic_p)
|
||||||
{
|
{
|
||||||
int dynindx
|
int dynindx
|
||||||
= elf_section_data (sec->output_section)->dynindx;
|
= elf_section_data (sec->output_section)->dynindx;
|
||||||
|
@ -4730,7 +4735,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
|
loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
|
||||||
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
|
||||||
}
|
}
|
||||||
else if (htab->fdpic_p
|
else if (fdpic_p
|
||||||
&& (sh_elf_local_got_type (input_bfd) [r_symndx]
|
&& (sh_elf_local_got_type (input_bfd) [r_symndx]
|
||||||
== GOT_NORMAL))
|
== GOT_NORMAL))
|
||||||
sh_elf_add_rofixup (output_bfd, htab->srofixup,
|
sh_elf_add_rofixup (output_bfd, htab->srofixup,
|
||||||
|
@ -4775,6 +4780,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
we place at the start of the .got.plt section. This is the same
|
we place at the start of the .got.plt section. This is the same
|
||||||
as the start of the output .got section, unless there are function
|
as the start of the output .got section, unless there are function
|
||||||
descriptors in front of it. */
|
descriptors in front of it. */
|
||||||
|
BFD_ASSERT (htab);
|
||||||
BFD_ASSERT (sgotplt != NULL);
|
BFD_ASSERT (sgotplt != NULL);
|
||||||
check_segment[0] = got_segment;
|
check_segment[0] = got_segment;
|
||||||
relocation -= sgotplt->output_section->vma + sgotplt->output_offset
|
relocation -= sgotplt->output_section->vma + sgotplt->output_offset
|
||||||
|
@ -4875,6 +4881,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
bfd_vma reloc_offset;
|
bfd_vma reloc_offset;
|
||||||
int reloc_type = R_SH_FUNCDESC;
|
int reloc_type = R_SH_FUNCDESC;
|
||||||
|
|
||||||
|
BFD_ASSERT (htab);
|
||||||
|
|
||||||
check_segment[0] = check_segment[1] = -1;
|
check_segment[0] = check_segment[1] = -1;
|
||||||
|
|
||||||
/* FIXME: See what FRV does for global symbols in the
|
/* FIXME: See what FRV does for global symbols in the
|
||||||
|
@ -4892,7 +4900,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reloc_section = htab->sgot;
|
reloc_section = sgot;
|
||||||
|
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
reloc_offset = h->got.offset;
|
reloc_offset = h->got.offset;
|
||||||
|
@ -5087,6 +5095,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
executable and --export-dynamic. If such symbols get
|
executable and --export-dynamic. If such symbols get
|
||||||
ld.so-allocated descriptors we can not use R_SH_GOTOFFFUNCDESC
|
ld.so-allocated descriptors we can not use R_SH_GOTOFFFUNCDESC
|
||||||
for them. */
|
for them. */
|
||||||
|
BFD_ASSERT (htab);
|
||||||
|
|
||||||
check_segment[0] = check_segment[1] = -1;
|
check_segment[0] = check_segment[1] = -1;
|
||||||
relocation = 0;
|
relocation = 0;
|
||||||
|
@ -5139,8 +5148,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
relocation = htab->sfuncdesc->output_offset + (offset & ~1);
|
relocation = htab->sfuncdesc->output_offset + (offset & ~1);
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation -= htab->root.hgot->root.u.def.value
|
relocation -= (htab->root.hgot->root.u.def.value
|
||||||
+ htab->sgotplt->output_offset;
|
+ sgotplt->output_offset);
|
||||||
#ifdef GOT_BIAS
|
#ifdef GOT_BIAS
|
||||||
relocation -= GOT_BIAS;
|
relocation -= GOT_BIAS;
|
||||||
#endif
|
#endif
|
||||||
|
@ -5175,6 +5184,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
|
|
||||||
case R_SH_TLS_GD_32:
|
case R_SH_TLS_GD_32:
|
||||||
case R_SH_TLS_IE_32:
|
case R_SH_TLS_IE_32:
|
||||||
|
BFD_ASSERT (htab);
|
||||||
check_segment[0] = check_segment[1] = -1;
|
check_segment[0] = check_segment[1] = -1;
|
||||||
r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
|
r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
|
||||||
got_type = GOT_UNKNOWN;
|
got_type = GOT_UNKNOWN;
|
||||||
|
@ -5425,6 +5435,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
goto final_link_relocate;
|
goto final_link_relocate;
|
||||||
|
|
||||||
case R_SH_TLS_LD_32:
|
case R_SH_TLS_LD_32:
|
||||||
|
BFD_ASSERT (htab);
|
||||||
check_segment[0] = check_segment[1] = -1;
|
check_segment[0] = check_segment[1] = -1;
|
||||||
if (! info->shared)
|
if (! info->shared)
|
||||||
{
|
{
|
||||||
|
@ -5558,7 +5569,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation_done:
|
relocation_done:
|
||||||
if (htab->fdpic_p && check_segment[0] != (unsigned) -1
|
if (fdpic_p && check_segment[0] != (unsigned) -1
|
||||||
&& check_segment[0] != check_segment[1])
|
&& check_segment[0] != check_segment[1])
|
||||||
{
|
{
|
||||||
/* We don't want duplicate errors for undefined symbols. */
|
/* We don't want duplicate errors for undefined symbols. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue