Index: bfd/elf32-sh.c |
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c |
index 780a3bf6b0fd898b52b0a04dfa0631633db848c5..cbd00aa64043de5eef249b8d78a7f622f8d0fdd9 100644 |
--- a/bfd/elf32-sh.c |
+++ b/bfd/elf32-sh.c |
@@ -1,6 +1,7 @@ |
/* Renesas / SuperH SH specific support for 32-bit ELF |
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |
- 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. |
+ 2006, 2007, 2008, 2009, 2010, 2011, 2012 |
+ Free Software Foundation, Inc. |
Contributed by Ian Lance Taylor, Cygnus Support. |
This file is part of BFD, the Binary File Descriptor library. |
@@ -2405,7 +2406,7 @@ struct elf_sh_link_hash_entry |
and thus require fixups or relocations. */ |
bfd_signed_vma abs_funcdesc_refcount; |
- enum { |
+ enum got_type { |
GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE, GOT_FUNCDESC |
} got_type; |
}; |
@@ -2621,39 +2622,39 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info) |
if (htab == NULL) |
return FALSE; |
- htab->sgot = bfd_get_section_by_name (dynobj, ".got"); |
- htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); |
- htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); |
+ htab->sgot = bfd_get_linker_section (dynobj, ".got"); |
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt"); |
+ htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got"); |
if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot) |
abort (); |
- htab->sfuncdesc = bfd_make_section_with_flags (dynobj, ".got.funcdesc", |
- (SEC_ALLOC | SEC_LOAD |
- | SEC_HAS_CONTENTS |
- | SEC_IN_MEMORY |
- | SEC_LINKER_CREATED)); |
+ htab->sfuncdesc = bfd_make_section_anyway_with_flags (dynobj, ".got.funcdesc", |
+ (SEC_ALLOC | SEC_LOAD |
+ | SEC_HAS_CONTENTS |
+ | SEC_IN_MEMORY |
+ | SEC_LINKER_CREATED)); |
if (htab->sfuncdesc == NULL |
|| ! bfd_set_section_alignment (dynobj, htab->sfuncdesc, 2)) |
return FALSE; |
- htab->srelfuncdesc = bfd_make_section_with_flags (dynobj, |
- ".rela.got.funcdesc", |
- (SEC_ALLOC | SEC_LOAD |
- | SEC_HAS_CONTENTS |
- | SEC_IN_MEMORY |
- | SEC_LINKER_CREATED |
- | SEC_READONLY)); |
+ htab->srelfuncdesc = bfd_make_section_anyway_with_flags (dynobj, |
+ ".rela.got.funcdesc", |
+ (SEC_ALLOC | SEC_LOAD |
+ | SEC_HAS_CONTENTS |
+ | SEC_IN_MEMORY |
+ | SEC_LINKER_CREATED |
+ | SEC_READONLY)); |
if (htab->srelfuncdesc == NULL |
|| ! bfd_set_section_alignment (dynobj, htab->srelfuncdesc, 2)) |
return FALSE; |
/* Also create .rofixup. */ |
- htab->srofixup = bfd_make_section_with_flags (dynobj, ".rofixup", |
- (SEC_ALLOC | SEC_LOAD |
- | SEC_HAS_CONTENTS |
- | SEC_IN_MEMORY |
- | SEC_LINKER_CREATED |
- | SEC_READONLY)); |
+ htab->srofixup = bfd_make_section_anyway_with_flags (dynobj, ".rofixup", |
+ (SEC_ALLOC | SEC_LOAD |
+ | SEC_HAS_CONTENTS |
+ | SEC_IN_MEMORY |
+ | SEC_LINKER_CREATED |
+ | SEC_READONLY)); |
if (htab->srofixup == NULL |
|| ! bfd_set_section_alignment (dynobj, htab->srofixup, 2)) |
return FALSE; |
@@ -2707,7 +2708,7 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
if (bed->plt_readonly) |
pltflags |= SEC_READONLY; |
- s = bfd_make_section_with_flags (abfd, ".plt", pltflags); |
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags); |
htab->splt = s; |
if (s == NULL |
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) |
@@ -2736,9 +2737,10 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
return FALSE; |
} |
- s = bfd_make_section_with_flags (abfd, |
- bed->default_use_rela_p ? ".rela.plt" : ".rel.plt", |
- flags | SEC_READONLY); |
+ s = bfd_make_section_anyway_with_flags (abfd, |
+ bed->default_use_rela_p |
+ ? ".rela.plt" : ".rel.plt", |
+ flags | SEC_READONLY); |
htab->srelplt = s; |
if (s == NULL |
|| ! bfd_set_section_alignment (abfd, s, ptralign)) |
@@ -2748,32 +2750,6 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
&& !create_got_section (abfd, info)) |
return FALSE; |
- { |
- const char *secname; |
- char *relname; |
- flagword secflags; |
- asection *sec; |
- |
- for (sec = abfd->sections; sec; sec = sec->next) |
- { |
- secflags = bfd_get_section_flags (abfd, sec); |
- if ((secflags & (SEC_DATA | SEC_LINKER_CREATED)) |
- || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS)) |
- continue; |
- secname = bfd_get_section_name (abfd, sec); |
- relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6); |
- strcpy (relname, ".rela"); |
- strcat (relname, secname); |
- if (bfd_get_section_by_name (abfd, secname)) |
- continue; |
- s = bfd_make_section_with_flags (abfd, relname, |
- flags | SEC_READONLY); |
- if (s == NULL |
- || ! bfd_set_section_alignment (abfd, s, ptralign)) |
- return FALSE; |
- } |
- } |
- |
if (bed->want_dynbss) |
{ |
/* The .dynbss section is a place to put symbols which are defined |
@@ -2782,8 +2758,8 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
image and use a R_*_COPY reloc to tell the dynamic linker to |
initialize them at run time. The linker script puts the .dynbss |
section into the .bss section of the final image. */ |
- s = bfd_make_section_with_flags (abfd, ".dynbss", |
- SEC_ALLOC | SEC_LINKER_CREATED); |
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynbss", |
+ SEC_ALLOC | SEC_LINKER_CREATED); |
htab->sdynbss = s; |
if (s == NULL) |
return FALSE; |
@@ -2801,10 +2777,10 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
copy relocs. */ |
if (! info->shared) |
{ |
- s = bfd_make_section_with_flags (abfd, |
- (bed->default_use_rela_p |
- ? ".rela.bss" : ".rel.bss"), |
- flags | SEC_READONLY); |
+ s = bfd_make_section_anyway_with_flags (abfd, |
+ (bed->default_use_rela_p |
+ ? ".rela.bss" : ".rel.bss"), |
+ flags | SEC_READONLY); |
htab->srelbss = s; |
if (s == NULL |
|| ! bfd_set_section_alignment (abfd, s, ptralign)) |
@@ -2926,13 +2902,6 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info, |
return TRUE; |
} |
- if (h->size == 0) |
- { |
- (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), |
- h->root.root.string); |
- return TRUE; |
- } |
- |
/* We must allocate the symbol in our .dynbss section, which will |
become part of the .bss section of the executable. There will be |
an entry for this symbol in the .dynsym section. The dynamic |
@@ -2950,7 +2919,7 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info, |
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_ALLOC) != 0 && h->size != 0) |
{ |
asection *srel; |
@@ -3084,7 +3053,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) |
{ |
asection *s; |
bfd_boolean dyn; |
- int got_type = sh_elf_hash_entry (h)->got_type; |
+ enum got_type got_type = sh_elf_hash_entry (h)->got_type; |
/* Make sure this symbol is output as a dynamic symbol. |
Undefined weak syms won't yet be marked as dynamic. */ |
@@ -3110,6 +3079,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) |
&& (got_type == GOT_NORMAL || got_type == GOT_FUNCDESC)) |
htab->srofixup->size += 4; |
} |
+ /* No dynamic relocations required when IE->LE conversion happens. */ |
+ else if (got_type == GOT_TLS_IE && !h->def_dynamic && !info->shared) |
+ ; |
/* R_SH_TLS_IE_32 needs one dynamic relocation if dynamic, |
R_SH_TLS_GD needs one if local symbol and two if global. */ |
else if ((got_type == GOT_TLS_GD && h->dynindx == -1) |
@@ -3446,7 +3418,7 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, |
/* Set the contents of the .interp section to the interpreter. */ |
if (info->executable) |
{ |
- s = bfd_get_section_by_name (dynobj, ".interp"); |
+ s = bfd_get_linker_section (dynobj, ".interp"); |
BFD_ASSERT (s != NULL); |
s->size = sizeof ELF_DYNAMIC_INTERPRETER; |
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
@@ -3788,8 +3760,10 @@ sh_elf_got_offset (struct elf_sh_link_hash_table *htab) |
static unsigned |
sh_elf_osec_to_segment (bfd *output_bfd, asection *osec) |
{ |
- Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section (output_bfd, |
- osec); |
+ Elf_Internal_Phdr *p = NULL; |
+ |
+ if (output_bfd->xvec->flavour == bfd_target_elf_flavour) |
+ p = _bfd_elf_find_segment_containing_section (output_bfd, osec); |
/* FIXME: Nothing ever says what this index is relative to. The kernel |
supplies data in terms of the number of load segments but this is |
@@ -3802,7 +3776,8 @@ sh_elf_osec_readonly_p (bfd *output_bfd, asection *osec) |
{ |
unsigned seg = sh_elf_osec_to_segment (output_bfd, osec); |
- return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W); |
+ return (seg != (unsigned) -1 |
+ && ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W)); |
} |
/* Generate the initial contents of a local function descriptor, along |
@@ -3980,7 +3955,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
bfd_reloc_status_type r; |
int seen_stt_datalabel = 0; |
bfd_vma off; |
- int got_type; |
+ enum got_type got_type; |
const char *symname = NULL; |
r_symndx = ELF32_R_SYM (rel->r_info); |
@@ -4048,7 +4023,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
_("Unexpected STO_SH5_ISA32 on local symbol is not handled"), |
input_bfd, input_section, rel->r_offset)); |
- if (sec != NULL && elf_discarded_section (sec)) |
+ if (sec != NULL && discarded_section (sec)) |
/* Handled below. */ |
; |
else if (info->relocatable) |
@@ -4240,9 +4215,9 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
} |
} |
- if (sec != NULL && elf_discarded_section (sec)) |
+ if (sec != NULL && discarded_section (sec)) |
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
- rel, relend, howto, contents); |
+ rel, 1, relend, howto, 0, contents); |
if (info->relocatable) |
continue; |
@@ -4698,8 +4673,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
if (srelgot == NULL) |
{ |
- srelgot = bfd_get_section_by_name (dynobj, |
- ".rela.got"); |
+ srelgot = bfd_get_linker_section (dynobj, |
+ ".rela.got"); |
BFD_ASSERT (srelgot != NULL); |
} |
@@ -5020,7 +4995,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
if (srelgot == NULL) |
{ |
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); |
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got"); |
BFD_ASSERT (srelgot != NULL); |
} |
@@ -5310,7 +5285,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, |
if (srelgot == NULL) |
{ |
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); |
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got"); |
BFD_ASSERT (srelgot != NULL); |
} |
@@ -6093,7 +6068,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, |
const Elf_Internal_Rela *rel_end; |
asection *sreloc; |
unsigned int r_type; |
- int got_type, old_got_type; |
+ enum got_type got_type, old_got_type; |
sreloc = NULL; |
@@ -7167,8 +7142,7 @@ sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, |
&& (h->root.type == bfd_link_hash_defined |
|| h->root.type == bfd_link_hash_defweak)); |
- s = bfd_get_section_by_name (h->root.u.def.section->owner, |
- ".rela.bss"); |
+ s = bfd_get_linker_section (htab->root.dynobj, ".rela.bss"); |
BFD_ASSERT (s != NULL); |
rel.r_offset = (h->root.u.def.value |
@@ -7204,7 +7178,7 @@ sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) |
return FALSE; |
sgotplt = htab->sgotplt; |
- sdyn = bfd_get_section_by_name (htab->root.dynobj, ".dynamic"); |
+ sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic"); |
if (htab->root.dynamic_sections_created) |
{ |