daily update
[deliverable/binutils-gdb.git] / ld / ldwrite.c
index e559825cd3e65b5a04fa02b09b6473b51f463c24..e4bec32cac8b6e1433895a3513691f12643570d0 100644 (file)
@@ -1,5 +1,5 @@
 /* ldwrite.c -- write out the linked file
-   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000
+   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003
    Free Software Foundation, Inc.
    Written by Steve Chamberlain sac@cygnus.com
 
@@ -23,24 +23,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "sysdep.h"
 #include "bfdlink.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 
 #include "ld.h"
 #include "ldexp.h"
 #include "ldlang.h"
 #include "ldwrite.h"
 #include "ldmisc.h"
-#include "ldgram.h"
+#include <ldgram.h>
 #include "ldmain.h"
 
-static void build_link_order PARAMS ((lang_statement_union_type *));
-static asection *clone_section PARAMS ((bfd *, asection *, const char *, int *));
-static void split_sections PARAMS ((bfd *, struct bfd_link_info *));
-
 /* Build link_order structures for the BFD linker.  */
 
 static void
-build_link_order (statement)
-     lang_statement_union_type *statement;
+build_link_order (lang_statement_union_type *statement)
 {
   switch (statement->header.type)
     {
@@ -49,7 +45,7 @@ build_link_order (statement)
        asection *output_section;
        struct bfd_link_order *link_order;
        bfd_vma value;
-       boolean big_endian = false;
+       bfd_boolean big_endian = FALSE;
 
        output_section = statement->data_statement.output_section;
        ASSERT (output_section->owner == output_bfd);
@@ -60,7 +56,7 @@ build_link_order (statement)
 
        link_order->type = bfd_data_link_order;
        link_order->offset = statement->data_statement.output_vma;
-       link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
+       link_order->u.data.contents = xmalloc (QUAD_SIZE);
 
        value = statement->data_statement.value;
 
@@ -70,24 +66,24 @@ build_link_order (statement)
           endianness are big endian, so we must swap here if the
           input file is little endian.  */
        if (bfd_big_endian (output_bfd))
-         big_endian = true;
+         big_endian = TRUE;
        else if (bfd_little_endian (output_bfd))
-         big_endian = false;
+         big_endian = FALSE;
        else
          {
-           boolean swap;
+           bfd_boolean swap;
 
-           swap = false;
+           swap = FALSE;
            if (command_line.endian == ENDIAN_BIG)
-             big_endian = true;
+             big_endian = TRUE;
            else if (command_line.endian == ENDIAN_LITTLE)
              {
-               big_endian = false;
-               swap = true;
+               big_endian = FALSE;
+               swap = TRUE;
              }
            else if (command_line.endian == ENDIAN_UNSET)
              {
-               big_endian = true;
+               big_endian = TRUE;
                {
                  LANG_FOR_EACH_INPUT_STATEMENT (s)
                    {
@@ -95,8 +91,8 @@ build_link_order (statement)
                        {
                          if (bfd_little_endian (s->the_bfd))
                            {
-                             big_endian = false;
-                             swap = true;
+                             big_endian = FALSE;
+                             swap = TRUE;
                            }
                          break;
                        }
@@ -197,9 +193,7 @@ build_link_order (statement)
        link_order->offset = rs->output_vma;
        link_order->size = bfd_get_reloc_size (rs->howto);
 
-       link_order->u.reloc.p =
-         ((struct bfd_link_order_reloc *)
-          xmalloc (sizeof (struct bfd_link_order_reloc)));
+       link_order->u.reloc.p = xmalloc (sizeof (struct bfd_link_order_reloc));
 
        link_order->u.reloc.p->reloc = rs->reloc;
        link_order->u.reloc.p->addend = rs->addend_value;
@@ -226,14 +220,16 @@ build_link_order (statement)
     case lang_input_section_enum:
       /* Create a new link_order in the output section with this
         attached */
-      if (statement->input_section.ifile->just_syms_flag == false)
+      if (!statement->input_section.ifile->just_syms_flag)
        {
          asection *i = statement->input_section.section;
          asection *output_section = i->output_section;
 
          ASSERT (output_section->owner == output_bfd);
 
-         if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
+         if ((output_section->flags & SEC_HAS_CONTENTS) != 0
+             || ((output_section->flags & SEC_LOAD) != 0
+                 && (output_section->flags & SEC_THREAD_LOCAL)))
            {
              struct bfd_link_order *link_order;
 
@@ -243,9 +239,10 @@ build_link_order (statement)
                {
                  /* We've got a never load section inside one which
                     is going to be output, we'll change it into a
-                    fill link_order */
-                 link_order->type = bfd_fill_link_order;
-                 link_order->u.fill.value = 0;
+                    fill.  */
+                 link_order->type = bfd_data_link_order;
+                 link_order->u.data.contents = "";
+                 link_order->u.data.size = 1;
                }
              else
                {
@@ -274,10 +271,11 @@ build_link_order (statement)
        if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
          {
            link_order = bfd_new_link_order (output_bfd, output_section);
-           link_order->type = bfd_fill_link_order;
+           link_order->type = bfd_data_link_order;
            link_order->size = statement->padding_statement.size;
            link_order->offset = statement->padding_statement.output_offset;
-           link_order->u.fill.value = statement->padding_statement.fill;
+           link_order->u.data.contents = statement->padding_statement.fill->data;
+           link_order->u.data.size = statement->padding_statement.fill->size;
          }
       }
       break;
@@ -288,9 +286,24 @@ build_link_order (statement)
     }
 }
 
-/* Call BFD to write out the linked file.  */
+/* Return true if NAME is the name of an unsplittable section. These
+   are the stabs strings, dwarf strings.  */
 
-/**********************************************************************/
+static bfd_boolean
+unsplittable_name (const char *name)
+{
+  if (strncmp (name, ".stab", 5) == 0)
+    {
+      /* There are several stab like string sections. We pattern match on
+        ".stab...str"  */
+      unsigned len = strlen (name);
+      if (strcmp (&name[len-3], "str") == 0)
+       return TRUE;
+    }
+  else if (strcmp (name, "$GDB_STRINGS$") == 0)
+    return TRUE;
+  return FALSE;
+}
 
 /* Wander around the input sections, make sure that
    we'll never try and create an output section with more relocs
@@ -298,31 +311,53 @@ build_link_order (statement)
    creating new output sections with all the right bits.  */
 #define TESTIT 1
 static asection *
-clone_section (abfd, s, name, count)
-     bfd *abfd;
-     asection *s;
-     const char *name;
-     int *count;
+clone_section (bfd *abfd, asection *s, const char *name, int *count)
 {
-  char templ[6];
+  char *tname;
   char *sname;
+  unsigned int len;    
   asection *n;
   struct bfd_link_hash_entry *h;
 
-  /* Invent a section name from the first five chars of the base
-     section name and a digit suffix.  */
-  strncpy (templ, name, sizeof (templ) - 1);
-  templ[sizeof (templ) - 1] = '\0';
-  if ((sname = bfd_get_unique_section_name (abfd, templ, count)) == NULL
+  /* Invent a section name from the section name and a dotted numeric
+     suffix.   */
+  len = strlen (name);
+  tname = xmalloc (len + 1);
+  memcpy (tname, name, len + 1);
+  /* Remove a dotted number suffix, from a previous split link. */
+  while (len && ISDIGIT (tname[len-1]))
+    len--;
+  if (len > 1 && tname[len-1] == '.')
+    /* It was a dotted number. */
+    tname[len-1] = 0;
+
+  /* We want to use the whole of the original section name for the
+     split name, but coff can be restricted to 8 character names.  */
+  if (bfd_family_coff (abfd) && strlen (tname) > 5)
+    {
+      /* Some section names cannot be truncated, as the name is
+        used to locate some other section.  */
+      if (strncmp (name, ".stab", 5) == 0
+         || strcmp (name, "$GDB_SYMBOLS$") == 0)
+       {
+         einfo (_ ("%F%P: cannot create split section name for %s\n"), name);
+         /* Silence gcc warnings.  einfo exits, so we never reach here.  */
+         return NULL;
+       }
+      tname[5] = 0;
+    }
+  
+  if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL
       || (n = bfd_make_section_anyway (abfd, sname)) == NULL
       || (h = bfd_link_hash_lookup (link_info.hash,
-                                   sname, true, true, false)) == NULL)
+                                   sname, TRUE, TRUE, FALSE)) == NULL)
     {
       einfo (_("%F%P: clone section failed: %E\n"));
       /* Silence gcc warnings.  einfo exits, so we never reach here.  */
       return NULL;
     }
-
+  free (tname);
+  
   /* Set up section symbol.  */
   h->type = bfd_link_hash_defined;
   h->u.def.value = 0;
@@ -344,8 +379,7 @@ clone_section (abfd, s, name, count)
 
 #if TESTING
 static void
-ds (s)
-     asection *s;
+ds (asection *s)
 {
   struct bfd_link_order *l = s->link_order_head;
   printf ("vma %x size %x\n", s->vma, s->_raw_size);
@@ -364,10 +398,7 @@ ds (s)
   printf ("\n");
 }
 
-dump (s, a1, a2)
-     char *s;
-     asection *a1;
-     asection *a2;
+dump (char *s, asection *a1, asection *a2)
 {
   printf ("%s\n", s);
   ds (a1);
@@ -375,8 +406,7 @@ dump (s, a1, a2)
 }
 
 static void
-sanity_check (abfd)
-     bfd *abfd;
+sanity_check (bfd *abfd)
 {
   asection *s;
   for (s = abfd->sections; s; s = s->next)
@@ -399,9 +429,7 @@ sanity_check (abfd)
 #endif
 
 static void
-split_sections (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+split_sections (bfd *abfd, struct bfd_link_info *info)
 {
   asection *original_sec;
   int nsecs = abfd->section_count;
@@ -437,7 +465,7 @@ split_sections (abfd, info)
                  || info->strip == strip_some)
                thislines = sec->lineno_count;
 
-             if (info->relocateable)
+             if (info->relocatable)
                thisrelocs = sec->reloc_count;
 
              if (sec->_cooked_size != 0)
@@ -446,7 +474,7 @@ split_sections (abfd, info)
                thissize = sec->_raw_size;
 
            }
-         else if (info->relocateable
+         else if (info->relocatable
                   && (p->type == bfd_section_reloc_link_order
                       || p->type == bfd_symbol_reloc_link_order))
            thisrelocs++;
@@ -454,7 +482,8 @@ split_sections (abfd, info)
          if (l != NULL
              && (thisrelocs + relocs >= config.split_by_reloc
                  || thislines + lines >= config.split_by_reloc
-                 || thissize + sec_size >= config.split_by_file))
+                 || (thissize + sec_size >= config.split_by_file))
+             && !unsplittable_name (cursor->name))
            {
              /* Create a new section and put this link order and the
                 following link orders into it.  */
@@ -520,10 +549,10 @@ split_sections (abfd, info)
   sanity_check (abfd);
 }
 
-/**********************************************************************/
+/* Call BFD to write out the linked file.  */
 
 void
-ldwrite ()
+ldwrite (void)
 {
   /* Reset error indicator, which can typically something like invalid
      format from opening up the .o files.  */
This page took 0.02724 seconds and 4 git commands to generate.