2000-06-05 Michael Matz <matz@ifh.de>
[deliverable/binutils-gdb.git] / ld / ldwrite.c
index be1465d378cf9d4f4f84c37878162477b27f4938..b56119a39ac124ae410cca6183afc2371c2d3fdb 100644 (file)
@@ -1,5 +1,6 @@
 /* ldwrite.c -- write out the linked file
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
+   Free Software Foundation, Inc.
    Written by Steve Chamberlain sac@cygnus.com
 
 This file is part of GLD, the Gnu Linker.
@@ -21,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "bfd.h"
 #include "sysdep.h"
 #include "bfdlink.h"
+#include "libiberty.h"
 
 #include "ld.h"
 #include "ldexp.h"
@@ -31,9 +33,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "ldmain.h"
 
 static void build_link_order PARAMS ((lang_statement_union_type *));
-static void print_symbol_table PARAMS ((void));
-static void print_file_stuff PARAMS ((lang_input_statement_type *));
-static boolean print_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
+static asection *clone_section PARAMS ((bfd *, asection *, int *));
+static void split_sections PARAMS ((bfd *, struct bfd_link_info *));
 
 /* Build link_order structures for the BFD linker.  */
 
@@ -48,13 +49,14 @@ build_link_order (statement)
        asection *output_section;
        struct bfd_link_order *link_order;
        bfd_vma value;
+       boolean big_endian = false;
 
        output_section = statement->data_statement.output_section;
        ASSERT (output_section->owner == output_bfd);
 
        link_order = bfd_new_link_order (output_bfd, output_section);
        if (link_order == NULL)
-         einfo ("%P%F: bfd_new_link_order failed");
+         einfo (_("%P%F: bfd_new_link_order failed\n"));
 
        link_order->type = bfd_data_link_order;
        link_order->offset = statement->data_statement.output_vma;
@@ -62,11 +64,101 @@ build_link_order (statement)
 
        value = statement->data_statement.value;
 
+       /* If the endianness of the output BFD is not known, then we
+          base the endianness of the data on the first input file.
+          By convention, the bfd_put routines for an unknown
+          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;
+       else if (bfd_little_endian (output_bfd))
+         big_endian = false;
+       else
+         {
+           boolean swap;
+
+           swap = false;
+           if (command_line.endian == ENDIAN_BIG)
+             big_endian = true;
+           else if (command_line.endian == ENDIAN_LITTLE)
+             {
+               big_endian = false;
+               swap = true;
+             }
+           else if (command_line.endian == ENDIAN_UNSET)
+             {
+               big_endian = true;
+               {
+                 LANG_FOR_EACH_INPUT_STATEMENT (s)
+                   {
+                     if (s->the_bfd != NULL)
+                       {
+                         if (bfd_little_endian (s->the_bfd))
+                           {
+                             big_endian = false;
+                             swap = true;
+                           }
+                         break;
+                       }
+                   }
+               }
+             }
+
+           if (swap)
+             {
+               bfd_byte buffer[8];
+
+               switch (statement->data_statement.type)
+                 {
+                 case QUAD:
+                 case SQUAD:
+                   if (sizeof (bfd_vma) >= QUAD_SIZE)
+                     {
+                       bfd_putl64 (value, buffer);
+                       value = bfd_getb64 (buffer);
+                       break;
+                     }
+                   /* Fall through.  */
+                 case LONG:
+                   bfd_putl32 (value, buffer);
+                   value = bfd_getb32 (buffer);
+                   break;
+                 case SHORT:
+                   bfd_putl16 (value, buffer);
+                   value = bfd_getb16 (buffer);
+                   break;
+                 case BYTE:
+                   break;
+                 default:
+                   abort ();
+                 }
+             }
+         }
+
        ASSERT (output_section->owner == output_bfd);
        switch (statement->data_statement.type)
          {
          case QUAD:
-           bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+         case SQUAD:
+           if (sizeof (bfd_vma) >= QUAD_SIZE)
+             bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+           else
+             {
+               bfd_vma high;
+
+               if (statement->data_statement.type == QUAD)
+                 high = 0;
+               else if ((value & 0x80000000) == 0)
+                 high = 0;
+               else
+                 high = (bfd_vma) -1;
+               bfd_put_32 (output_bfd, high,
+                           (link_order->u.data.contents
+                            + (big_endian ? 0 : 4)));
+               bfd_put_32 (output_bfd, value,
+                           (link_order->u.data.contents
+                            + (big_endian ? 4 : 0)));
+             }
            link_order->size = QUAD_SIZE;
            break;
          case LONG:
@@ -100,7 +192,7 @@ build_link_order (statement)
 
        link_order = bfd_new_link_order (output_bfd, output_section);
        if (link_order == NULL)
-         einfo ("%P%F: bfd_new_link_order failed");
+         einfo (_("%P%F: bfd_new_link_order failed\n"));
 
        link_order->offset = rs->output_vma;
        link_order->size = bfd_get_reloc_size (rs->howto);
@@ -112,9 +204,8 @@ build_link_order (statement)
        link_order->u.reloc.p->reloc = rs->reloc;
        link_order->u.reloc.p->addend = rs->addend_value;
 
-       if (rs->section != (asection *) NULL)
+       if (rs->name == NULL)
          {
-           ASSERT (rs->name == (const char *) NULL);
            link_order->type = bfd_section_reloc_link_order;
            if (rs->section->owner == output_bfd)
              link_order->u.reloc.p->u.section = rs->section;
@@ -126,7 +217,6 @@ build_link_order (statement)
          }
        else
          {
-           ASSERT (rs->name != (const char *) NULL);
            link_order->type = bfd_symbol_reloc_link_order;
            link_order->u.reloc.p->u.name = rs->name;
          }
@@ -223,7 +313,7 @@ clone_section (abfd, s, count)
      chars of base section name and a digit suffix */
   do
     {
-      int i;
+      unsigned int i;
       char b[6];
       for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
        b[i] = s->name[i];
@@ -232,7 +322,7 @@ clone_section (abfd, s, count)
     }
   while (bfd_get_section_by_name (abfd, sname));
 
-  n = bfd_make_section_anyway (abfd, strdup (sname));
+  n = bfd_make_section_anyway (abfd, xstrdup (sname));
 
   /* Create a symbol of the same name */
 
@@ -253,7 +343,7 @@ clone_section (abfd, s, count)
   n->output_section = n;
   n->orelocation = 0;
   n->reloc_count = 0;
-  n->alignment_power = 1;
+  n->alignment_power = s->alignment_power;
   return n;
 }
 
@@ -272,7 +362,7 @@ ds (s)
        }
       else
        {
-         printf ("%8x something else\n", l->offset);
+         printf (_("%8x something else\n"), l->offset);
        }
       l = l->next;
     }
@@ -312,8 +402,7 @@ sanity_check (abfd)
 #define dump(a, b, c)
 #endif
 
-
-void 
+static void 
 split_sections (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -434,155 +523,8 @@ ldwrite ()
         out.  */
 
       if (bfd_get_error () != bfd_error_no_error)
-       einfo ("%F%P: final link failed: %E\n", output_bfd);
+       einfo (_("%F%P: final link failed: %E\n"), output_bfd);
       else
        xexit(1);
     }
-
-  if (config.map_file)
-    {
-      print_symbol_table ();
-      lang_map ();
-    }
-}
-
-/* Print the symbol table.  */
-
-static void
-print_symbol_table ()
-{
-  fprintf (config.map_file, "**FILES**\n\n");
-  lang_for_each_file (print_file_stuff);
-
-  fprintf (config.map_file, "**GLOBAL SYMBOLS**\n\n");
-  fprintf (config.map_file, "offset    section    offset   symbol\n");
-  bfd_link_hash_traverse (link_info.hash, print_symbol, (PTR) NULL);
-}
-
-/* Print information about a file.  */
-
-static void
-print_file_stuff (f)
-     lang_input_statement_type *f;
-{
-  fprintf (config.map_file, "  %s\n", f->filename);
-  if (f->just_syms_flag)
-    {
-      fprintf (config.map_file, " symbols only\n");
-    }
-  else
-    {
-      asection *s;
-      if (true)
-       {
-         for (s = f->the_bfd->sections;
-              s != (asection *) NULL;
-              s = s->next)
-           {
-#ifdef WINDOWS_NT
-              /* Don't include any information that goes into the '.junk'
-                 section.  This includes the code view .debug$ data and
-                 stuff from .drectve sections */
-              if (strcmp (s->name, ".drectve") == 0 ||
-                  strncmp (s->name, ".debug$", 7) == 0)
-                continue;
-#endif
-             print_address (s->output_offset);
-             if (s->reloc_done)
-               {
-                 fprintf (config.map_file, " %08x 2**%2ud %s\n",
-                          (unsigned) bfd_get_section_size_after_reloc (s),
-                          s->alignment_power, s->name);
-               }
-
-             else
-               {
-                 fprintf (config.map_file, " %08x 2**%2ud %s\n",
-                          (unsigned) bfd_get_section_size_before_reloc (s),
-                          s->alignment_power, s->name);
-               }
-           }
-       }
-      else
-       {
-         for (s = f->the_bfd->sections;
-              s != (asection *) NULL;
-              s = s->next)
-           {
-             fprintf (config.map_file, "%s ", s->name);
-             print_address (s->output_offset);
-             fprintf (config.map_file, "(%x)",
-                      (unsigned) bfd_get_section_size_after_reloc (s));
-           }
-         fprintf (config.map_file, "hex \n");
-       }
-    }
-  print_nl ();
-}
-
-/* Print a symbol.  */
-
-/*ARGSUSED*/
-static boolean
-print_symbol (p, ignore)
-     struct bfd_link_hash_entry *p;
-     PTR ignore;
-{
-  while (p->type == bfd_link_hash_indirect
-        || p->type == bfd_link_hash_warning)
-    p = p->u.i.link;
-
-  switch (p->type)
-    {
-    case bfd_link_hash_new:
-      abort ();
-
-    case bfd_link_hash_undefined:
-      fprintf (config.map_file, "undefined                     ");
-      fprintf (config.map_file, "%s ", p->root.string);
-      print_nl ();
-      break;
-
-    case bfd_link_hash_undefweak:
-      fprintf (config.map_file, "weak                          ");
-      fprintf (config.map_file, "%s ", p->root.string);
-      print_nl ();
-      break;
-
-    case bfd_link_hash_defined:
-    case bfd_link_hash_defweak:
-      {
-       asection *defsec = p->u.def.section;
-
-       print_address (p->u.def.value);
-       if (defsec)
-         {
-           fprintf (config.map_file, "  %-10s",
-                    bfd_section_name (output_bfd, defsec));
-           print_space ();
-           print_address (p->u.def.value + defsec->vma);
-         }
-       else
-         {
-           fprintf (config.map_file, "         .......");
-         }
-       fprintf (config.map_file, " %s", p->root.string);
-       if (p->type == bfd_link_hash_defweak)
-         fprintf (config.map_file, " [weak]");
-      }
-      print_nl ();
-      break;
-
-    case bfd_link_hash_common:
-      fprintf (config.map_file, "common               ");
-      print_address (p->u.c.size);
-      fprintf (config.map_file, " %s ", p->root.string);
-      print_nl ();
-      break;
-
-    default:
-      abort ();
-    }
-
-  return true;
 }
This page took 0.027616 seconds and 4 git commands to generate.