gas/
[deliverable/binutils-gdb.git] / bfd / elf32-cr16.c
index 84d95509268f1e65fc98075c55540f64c5d49b1f..46769f55b55e86b8f6b23f7b8d24a8cefc7764eb 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for National Semiconductor's CR16 ELF
-   Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright 2007, 2008, 2009, 2010, 2012 Free Software Foundation, Inc.
    Written by M R Swami Reddy.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -32,7 +32,8 @@
    linking with -Bsymbolic.  We store the information in a field
    extending the regular ELF linker hash table.  */
 
-struct elf32_cr16_link_hash_entry {
+struct elf32_cr16_link_hash_entry
+{
   /* The basic elf link hash table entry.  */
   struct elf_link_hash_entry root;
 
@@ -66,35 +67,6 @@ struct elf32_cr16_link_hash_entry {
   bfd_vma value;
 };
 
-/* We derive a hash table from the main elf linker hash table so
-   we can store state variables and a secondary hash table without
-   resorting to global variables.  */
-struct elf32_cr16_link_hash_table {
-  /* The main hash table.  */
-  struct elf_link_hash_table root;
-
-  /* A hash table for static functions.  We could derive a new hash table
-     instead of using the full elf32_cr16_link_hash_table if we wanted
-     to save some memory.  */
-  struct elf32_cr16_link_hash_table *static_hash_table;
-
-  /* Random linker state flags.  */
-#define CR16_HASH_ENTRIES_INITIALIZED 0x1
-  char flags;
-};
-
-/* For CR16 linker hash table.  */
-
-/* Get the CR16 ELF linker hash table from a link_info structure.  */
-
-#define elf32_cr16_hash_table(p) \
-  ((struct elf32_cr16_link_hash_table *) ((p)->hash))
-
-#define elf32_cr16_link_hash_traverse(table, func, info)                    \
- (elf_link_hash_traverse                                                    \
-  (&(table)->root,                                                          \
-   (bfd_boolean (*) ((struct elf_link_hash_entry *, void *))) (func), (info)))
-
 /* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type.  */
 
 struct cr16_reloc_map
@@ -613,7 +585,7 @@ _bfd_cr16_elf_create_got_section (bfd * abfd, struct bfd_link_info * info)
   int ptralign;
 
   /* This function may be called more than once.  */
-  if (bfd_get_section_by_name (abfd, ".got") != NULL)
+  if (bfd_get_linker_section (abfd, ".got") != NULL)
     return TRUE;
 
   switch (bed->s->arch_size)
@@ -634,14 +606,14 @@ _bfd_cr16_elf_create_got_section (bfd * abfd, struct bfd_link_info * info)
   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
            | SEC_LINKER_CREATED);
 
-  s = bfd_make_section_with_flags (abfd, ".got", flags);
+  s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
   if (s == NULL
       || ! bfd_set_section_alignment (abfd, s, ptralign))
     return FALSE;
 
   if (bed->want_got_plt)
     {
-      s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
+      s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
       if (s == NULL
           || ! bfd_set_section_alignment (abfd, s, ptralign))
         return FALSE;
@@ -780,24 +752,22 @@ cr16_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
 
           if (sgot == NULL)
             {
-              sgot = bfd_get_section_by_name (dynobj, ".got");
+              sgot = bfd_get_linker_section (dynobj, ".got");
               BFD_ASSERT (sgot != NULL);
             }
 
           if (srelgot == NULL
               && (h != NULL || info->executable))
             {
-              srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+              srelgot = bfd_get_linker_section (dynobj, ".rela.got");
               if (srelgot == NULL)
-                {
-                  srelgot = bfd_make_section_with_flags (dynobj,
-                                                         ".rela.got",
-                                                         (SEC_ALLOC
-                                                          | SEC_LOAD
-                                                          | SEC_HAS_CONTENTS
-                                                          | SEC_IN_MEMORY
-                                                          | SEC_LINKER_CREATED
-                                                          | SEC_READONLY));
+                { 
+                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+                                   | SEC_IN_MEMORY | SEC_LINKER_CREATED
+                                   | SEC_READONLY);
+                 srelgot = bfd_make_section_anyway_with_flags (dynobj,
+                                                               ".rela.got",
+                                                               flags);
                   if (srelgot == NULL
                       || ! bfd_set_section_alignment (dynobj, srelgot, 2))
                     goto fail;
@@ -890,10 +860,8 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
   bfd_byte *hit_data = contents + offset;
   bfd_vma reloc_bits, check, Rvalue1;
   bfd *      dynobj;
-  bfd_vma *  local_got_offsets;
 
   dynobj = elf_hash_table (info)->dynobj;
-  local_got_offsets = elf_local_got_offsets (input_bfd);
 
   switch (r_type)
     {
@@ -1077,7 +1045,7 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
           }
         else if (r_type == R_CR16_GOT_REGREL20) 
           {
-            asection * sgot = bfd_get_section_by_name (dynobj, ".got");
+            asection * sgot = bfd_get_linker_section (dynobj, ".got");
 
             if (h != NULL)
               {
@@ -1126,7 +1094,7 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
         else if (r_type == R_CR16_GOTC_REGREL20)
           {
              asection * sgot;
-             sgot = bfd_get_section_by_name (dynobj, ".got");
+             sgot = bfd_get_linker_section (dynobj, ".got");
 
              if (h != NULL)
                {
@@ -1290,7 +1258,6 @@ elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
   unsigned int sec_shndx;
   bfd_byte *contents;
   Elf_Internal_Rela *irel, *irelend;
-  Elf_Internal_Rela *irelalign;
   bfd_vma toaddr;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymend;
@@ -1303,9 +1270,6 @@ elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
 
   contents = elf_section_data (sec)->this_hdr.contents;
 
-  /* The deletion must stop at the next ALIGN reloc for an aligment
-     power larger than the number of bytes we are deleting.  */
-  irelalign = NULL;
   toaddr = sec->size;
 
   irel = elf_section_data (sec)->relocs;
@@ -1465,16 +1429,9 @@ elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                                    unresolved_reloc, warned);
         }
 
-      if (sec != NULL && elf_discarded_section (sec))
-       {
-         /* For relocs against symbols from removed linkonce sections,
-            or sections discarded by a linker script, we just want the
-            section contents zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
         continue;
@@ -1700,40 +1657,23 @@ elf32_cr16_link_hash_newfunc (struct bfd_hash_entry *entry,
 static struct bfd_link_hash_table *
 elf32_cr16_link_hash_table_create (bfd *abfd)
 {
-  struct elf32_cr16_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf32_cr16_link_hash_table);
+  struct elf_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct elf_link_hash_table);
 
-  ret = (struct elf32_cr16_link_hash_table *) bfd_malloc (amt);
-  if (ret == (struct elf32_cr16_link_hash_table *) NULL)
+  ret = (struct elf_link_hash_table *) bfd_malloc (amt);
+  if (ret == (struct elf_link_hash_table *) NULL)
     return NULL;
 
-  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+  if (!_bfd_elf_link_hash_table_init (ret, abfd,
                                       elf32_cr16_link_hash_newfunc,
-                                      sizeof (struct elf32_cr16_link_hash_entry)))
-    {
-      free (ret);
-      return NULL;
-    }
-
-  ret->flags = 0;
-  amt = sizeof (struct elf_link_hash_table);
-  ret->static_hash_table
-    = (struct elf32_cr16_link_hash_table *) bfd_malloc (amt);
-  if (ret->static_hash_table == NULL)
+                                      sizeof (struct elf32_cr16_link_hash_entry),
+                                     GENERIC_ELF_DATA))
     {
       free (ret);
       return NULL;
     }
 
-  if (!_bfd_elf_link_hash_table_init (&ret->static_hash_table->root, abfd,
-                                      elf32_cr16_link_hash_newfunc,
-                                      sizeof (struct elf32_cr16_link_hash_entry)))
-    {
-      free (ret->static_hash_table);
-      free (ret);
-      return NULL;
-    }
-  return &ret->root.root;
+  return &ret->root;
 }
 
 /* Free an cr16 ELF linker hash table.  */
@@ -1741,11 +1681,9 @@ elf32_cr16_link_hash_table_create (bfd *abfd)
 static void
 elf32_cr16_link_hash_table_free (struct bfd_link_hash_table *hash)
 {
-  struct elf32_cr16_link_hash_table *ret
-    = (struct elf32_cr16_link_hash_table *) hash;
+  struct elf_link_hash_table *ret
+    = (struct elf_link_hash_table *) hash;
 
-  _bfd_generic_link_hash_table_free
-    ((struct bfd_link_hash_table *) ret->static_hash_table);
   _bfd_generic_link_hash_table_free
     ((struct bfd_link_hash_table *) ret);
 }
@@ -2338,10 +2276,10 @@ _bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
            | SEC_LINKER_CREATED);
 
-  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);
   if (s == NULL
       || ! bfd_set_section_alignment (abfd, s, ptralign))
     return FALSE;
@@ -2349,32 +2287,6 @@ _bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   if (! _bfd_cr16_elf_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 (strlen (secname) + 6);
-        strcpy (relname, ".rela");
-        strcat (relname, secname);
-
-        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
@@ -2383,8 +2295,8 @@ _bfd_cr16_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);
       if (s == NULL)
         return FALSE;
 
@@ -2401,10 +2313,10 @@ _bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
          copy relocs.  */
       if (! info->executable)
         {
-          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);
           if (s == NULL
               || ! bfd_set_section_alignment (abfd, s, ptralign))
             return FALSE;
@@ -2466,13 +2378,13 @@ _bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
       /* We also need to make an entry in the .got.plt section, which
          will be placed in the .got section by the linker script.  */
 
-      s = bfd_get_section_by_name (dynobj, ".got.plt");
+      s = bfd_get_linker_section (dynobj, ".got.plt");
       BFD_ASSERT (s != NULL);
       s->size += 4;
 
       /* We also need to make an entry in the .rela.plt section.  */
 
-      s = bfd_get_section_by_name (dynobj, ".rela.plt");
+      s = bfd_get_linker_section (dynobj, ".rela.plt");
       BFD_ASSERT (s != NULL);
       s->size += sizeof (Elf32_External_Rela);
 
@@ -2506,13 +2418,6 @@ _bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
   if (!h->non_got_ref)
     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
@@ -2523,18 +2428,18 @@ _bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
 
-  s = bfd_get_section_by_name (dynobj, ".dynbss");
+  s = bfd_get_linker_section (dynobj, ".dynbss");
   BFD_ASSERT (s != NULL);
 
   /* We must generate a R_CR16_COPY reloc to tell the dynamic linker to
      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;
 
-      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+      srel = bfd_get_linker_section (dynobj, ".rela.bss");
       BFD_ASSERT (srel != NULL);
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
@@ -2564,7 +2469,7 @@ _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
       if (info->executable)
         {
 #if 0
-          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;
@@ -2578,7 +2483,7 @@ _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
          not actually use these entries.  Reset the size of .rela.got,
          which will cause it to get stripped from the output file
          below.  */
-      s = bfd_get_section_by_name (dynobj, ".rela.got");
+      s = bfd_get_linker_section (dynobj, ".rela.got");
       if (s != NULL)
         s->size = 0;
     }
@@ -2733,8 +2638,8 @@ _bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
 
       /* This symbol has an entry in the global offset table.  Set it up.  */
 
-      sgot = bfd_get_section_by_name (dynobj, ".got");
-      srel = bfd_get_section_by_name (dynobj, ".rela.got");
+      sgot = bfd_get_linker_section (dynobj, ".got");
+      srel = bfd_get_linker_section (dynobj, ".rela.got");
       BFD_ASSERT (sgot != NULL && srel != NULL);
 
       rel.r_offset = (sgot->output_section->vma
@@ -2778,8 +2683,7 @@ _bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
                   && (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 (dynobj, ".rela.bss");
       BFD_ASSERT (s != NULL);
 
       rel.r_offset = (h->root.u.def.value
@@ -2794,7 +2698,7 @@ _bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
     }
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
-  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+  if (h == elf_hash_table (info)->hdynamic
       || h == elf_hash_table (info)->hgot)
     sym->st_shndx = SHN_ABS;
 
@@ -2813,9 +2717,9 @@ _bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
 
   dynobj = elf_hash_table (info)->dynobj;
 
-  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+  sgot = bfd_get_linker_section (dynobj, ".got.plt");
   BFD_ASSERT (sgot != NULL);
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
This page took 0.030284 seconds and 4 git commands to generate.