* elf32-sh.c (sh_elf_relocate_section): Handle non-ELF output

BFD.
This commit is contained in:
Maciej W. Rozycki 2010-08-20 21:15:03 +00:00
parent d898aefbfa
commit e0af1f531c
2 changed files with 45 additions and 29 deletions

View file

@ -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

View file

@ -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. */