| 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)
|
| {
|
|
|