Really remove operands64.d, operands64.s, operands.d and operands.s as
[deliverable/binutils-gdb.git] / bfd / merge.c
index 3efbd43773ee3f61318d2b2064a2b09c13902462..c1795d29112f71c5c8748636919cd71cc9ea33c0 100644 (file)
@@ -1,5 +1,6 @@
 /* SEC_MERGE support.
-   Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
    Written by Jakub Jelinek <jakub@redhat.com>.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -16,7 +17,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /* This file contains support for merging duplicate entities within sections,
    as used in ELF SHF_MERGE.  */
@@ -241,7 +242,8 @@ sec_merge_init (unsigned int entsize, bfd_boolean strings)
   if (table == NULL)
     return NULL;
 
-  if (! bfd_hash_table_init (&table->table, sec_merge_hash_newfunc))
+  if (! bfd_hash_table_init_n (&table->table, sec_merge_hash_newfunc,
+                              sizeof (struct sec_merge_hash_entry), 16699))
     {
       free (table);
       return NULL;
@@ -288,24 +290,27 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
 {
   struct sec_merge_sec_info *secinfo = entry->secinfo;
   asection *sec = secinfo->sec;
-  char *pad = "";
+  char *pad = NULL;
   bfd_size_type off = 0;
   int alignment_power = sec->output_section->alignment_power;
 
   if (alignment_power)
-    pad = bfd_zmalloc ((bfd_size_type) 1 << alignment_power);
+    {
+      pad = bfd_zmalloc ((bfd_size_type) 1 << alignment_power);
+      if (pad == NULL)
+       return FALSE;
+    }
 
   for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
     {
-      register const char *str;
-      register size_t len;
+      const char *str;
+      bfd_size_type len;
 
-      len = off & (entry->alignment - 1);
-      if (len)
+      len = -off & (entry->alignment - 1);
+      if (len != 0)
        {
-         len = entry->alignment - len;
          if (bfd_bwrite (pad, len, abfd) != len)
-           break;
+           goto err;
          off += len;
        }
 
@@ -313,15 +318,25 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
       len = entry->len;
 
       if (bfd_bwrite (str, len, abfd) != len)
-       break;
+       goto err;
 
       off += len;
     }
 
-  if (alignment_power)
+  /* Trailing alignment needed?  */
+  off = sec->size - off;
+  if (off != 0
+      && bfd_bwrite (pad, off, abfd) != off)
+    goto err;
+
+  if (pad != NULL)
     free (pad);
+  return TRUE;
 
-  return entry == NULL || entry->secinfo != secinfo;
+ err:
+  if (pad != NULL)
+    free (pad);
+  return FALSE;
 }
 
 /* Register a SEC_MERGE section as a candidate for merging.
@@ -656,6 +671,11 @@ alloc_failure:
        }
     }
   secinfo->sec->size = size;
+  if (secinfo->sec->alignment_power != 0)
+    {
+      bfd_size_type align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
+      secinfo->sec->size = (secinfo->sec->size + align - 1) & -align;
+    }
 
   /* And now adjust the rest, removing them from the chain (but not hashtable)
      at the same time.  */
@@ -678,8 +698,10 @@ alloc_failure:
    with _bfd_merge_section.  */
 
 bfd_boolean
-_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info,
-                    void *xsinfo, void (*remove_hook) (bfd *, asection *))
+_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED,
+                    struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                    void *xsinfo,
+                    void (*remove_hook) (bfd *, asection *))
 {
   struct sec_merge_info *sinfo;
 
@@ -744,7 +766,7 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info,
           the hash table at all.  */
        for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
          if (secinfo->first_str == NULL)
-           _bfd_strip_section_from_output (info, secinfo->sec);
+           secinfo->sec->flags |= SEC_EXCLUDE;
     }
 
   return TRUE;
This page took 0.027372 seconds and 4 git commands to generate.