daily update
[deliverable/binutils-gdb.git] / bfd / elf32-sh.c
index ca2c4af9058d8c518ffac0768df8fab084ee17ad..df4affd682d3beea5c6f7af73b47a44715da4a03 100644 (file)
@@ -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)
@@ -4208,7 +4183,11 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                                 STT_DATALABEL on the way to it.  */
                              | ((h->other & STO_SH5_ISA32) != 0
                                 && ! seen_stt_datalabel));
-             else if (!info->relocatable)
+             else if (!info->relocatable
+                      && (_bfd_elf_section_offset (output_bfd, info,
+                                                   input_section,
+                                                   rel->r_offset)
+                          != (bfd_vma) -1))
                {
                  (*_bfd_error_handler)
                    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
@@ -4236,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;
@@ -4694,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);
                        }
 
@@ -5016,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);
                  }
 
@@ -5306,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);
                }
 
@@ -6089,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;
 
@@ -7163,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
@@ -7179,7 +7157,7 @@ sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  On VxWorks,
      _GLOBAL_OFFSET_TABLE_ is not absolute: it is relative to the
      ".got" section.  */
-  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+  if (h == htab->root.hdynamic
       || (!htab->vxworks_p && h == htab->root.hgot))
     sym->st_shndx = SHN_ABS;
 
@@ -7200,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)
     {
This page took 0.029086 seconds and 4 git commands to generate.