add MAINTAINERS files
[binutils-gdb.git] / ld / ldmain.c
index 96f32799e4d40da5f4745f758615cc07c0997f0c..660ea94265aba28de81df46e14433913006959b2 100644 (file)
@@ -1,5 +1,6 @@
 /* Main program of GNU linker.
-   Copyright (C) 1991, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
+   Free Software Foundation, Inc.
    Written by Steve Chamberlain steve@cygnus.com
 
 This file is part of GLD, the Gnu Linker.
@@ -26,6 +27,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "libiberty.h"
 #include "progress.h"
 #include "bfdlink.h"
+#include "filenames.h"
 
 #include "ld.h"
 #include "ldmain.h"
@@ -82,6 +84,9 @@ boolean version_printed;
 /* Nonzero means link in every member of an archive.  */
 boolean whole_archive;
 
+/* True if we should demangle symbol names.  */
+boolean demangling;
+
 args_type command_line;
 
 ld_config_type config;
@@ -113,7 +118,7 @@ static boolean warning_callback PARAMS ((struct bfd_link_info *,
 static void warning_find_reloc PARAMS ((bfd *, asection *, PTR));
 static boolean undefined_symbol PARAMS ((struct bfd_link_info *,
                                         const char *, bfd *,
-                                        asection *, bfd_vma));
+                                        asection *, bfd_vma, boolean));
 static boolean reloc_overflow PARAMS ((struct bfd_link_info *, const char *,
                                       const char *, bfd_vma,
                                       bfd *, asection *, bfd_vma));
@@ -162,7 +167,7 @@ main (argc, argv)
   char *emulation;
   long start_time = get_run_time ();
 
-#ifdef HAVE_SETLOCALE
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   setlocale (LC_MESSAGES, "");
 #endif
   bindtextdomain (PACKAGE, LOCALEDIR);
@@ -199,14 +204,24 @@ main (argc, argv)
   command_line.interpreter = NULL;
   command_line.rpath = NULL;
   command_line.warn_mismatch = true;
+  command_line.check_section_addresses = true;
+
+  /* We initialize DEMANGLING based on the environment variable
+     COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
+     output of the linker, unless COLLECT_NO_DEMANGLE is set in the
+     environment.  Acting the same way here lets us provide the same
+     interface by default.  */
+  demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;
 
   link_info.callbacks = &link_callbacks;
   link_info.relocateable = false;
+  link_info.emitrelocations = false;
   link_info.shared = false;
   link_info.symbolic = false;
   link_info.static_link = false;
   link_info.traditional_format = false;
   link_info.optimize = false;
+  link_info.no_undefined = false;
   link_info.strip = strip_none;
   link_info.discard = discard_none;
   link_info.keep_memory = true;
@@ -217,7 +232,12 @@ main (argc, argv)
   link_info.notice_all = false;
   link_info.notice_hash = NULL;
   link_info.wrap_hash = NULL;
-  
+  link_info.mpc860c0 = 0;
+  /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
+     and _fini symbols.  We are compatible.  */
+  link_info.init_function = "_init";
+  link_info.fini_function = "_fini";
+
   ldfile_add_arch ("");
 
   config.make_executable = true;
@@ -240,15 +260,14 @@ main (argc, argv)
     {
       if (command_line.gc_sections)
        einfo ("%P%F: --gc-sections and -r may not be used together\n");
-      if (command_line.relax)
+      if (link_info.mpc860c0)
+       einfo (_("%P%F: -r and --mpc860c0 may not be used together\n"));
+      else if (command_line.relax)
        einfo (_("%P%F: --relax and -r may not be used together\n"));
       if (link_info.shared)
        einfo (_("%P%F: -r and -shared may not be used together\n"));
     }
 
-  if (command_line.gc_sections && config.dynamic_link)
-    einfo("%P%F: --gc-sections may only be performed for static links\n");
-
   /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols).  I
      don't see how else this can be handled, since in this case we
      must preserve all externally visible symbols.  */
@@ -329,15 +348,17 @@ main (argc, argv)
   /* Print error messages for any missing symbols, for any warning
      symbols, and possibly multiple definitions */
 
-
-  if (config.text_read_only)
+  if (! link_info.relocateable)
     {
-      /* Look for a text section and mark the readonly attribute in it */
-      asection *found = bfd_get_section_by_name (output_bfd, ".text");
-
+      /* Look for a text section and switch the readonly attribute in it.  */
+      asection * found = bfd_get_section_by_name (output_bfd, ".text");
+    
       if (found != (asection *) NULL)
        {
-         found->flags |= SEC_READONLY;
+         if (config.text_read_only)
+           found->flags |= SEC_READONLY;
+         else
+           found->flags &= ~SEC_READONLY;
        }
     }
 
@@ -424,7 +445,6 @@ main (argc, argv)
 
   if (config.stats)
     {
-      extern char **environ;
 #ifdef HAVE_SBRK
       char *lim = (char *) sbrk (0);
 #endif
@@ -551,6 +571,14 @@ set_scripts_dir ()
 
   /* Look for "ldscripts" in the dir where our binary is.  */
   end = strrchr (program_name, '/');
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  {
+    /* We could have \foo\bar, or /foo\bar.  */
+    char *bslash = strrchr (program_name, '\\');
+    if (end == NULL || (bslash != NULL && bslash > end))
+      end = bslash;
+  }
+#endif
 
   if (end == NULL)
     {
@@ -689,7 +717,7 @@ add_keepsyms_file (filename)
 /*ARGSUSED*/
 static boolean
 add_archive_element (info, abfd, name)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      bfd *abfd;
      const char *name;
 {
@@ -804,7 +832,7 @@ add_archive_element (info, abfd, name)
 /*ARGSUSED*/
 static boolean
 multiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      const char *name;
      bfd *obfd;
      asection *osec;
@@ -841,7 +869,7 @@ multiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval)
 /*ARGSUSED*/
 static boolean
 multiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      const char *name;
      bfd *obfd;
      enum bfd_link_hash_type otype;
@@ -908,7 +936,7 @@ multiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize)
 /*ARGSUSED*/
 static boolean
 add_to_set (info, h, reloc, abfd, section, value)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      struct bfd_link_hash_entry *h;
      bfd_reloc_code_real_type reloc;
      bfd *abfd;
@@ -1007,7 +1035,7 @@ struct warning_callback_info
 /*ARGSUSED*/
 static boolean
 warning_callback (info, warning, symbol, abfd, section, address)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      const char *warning;
      const char *symbol;
      bfd *abfd;
@@ -1128,12 +1156,13 @@ warning_find_reloc (abfd, sec, iarg)
 
 /*ARGSUSED*/
 static boolean
-undefined_symbol (info, name, abfd, section, address)
-     struct bfd_link_info *info;
+undefined_symbol (info, name, abfd, section, address, fatal)
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      const char *name;
      bfd *abfd;
      asection *section;
      bfd_vma address;
+     boolean fatal ATTRIBUTE_UNUSED;
 {
   static char *error_name;
   static unsigned int error_count;
@@ -1177,8 +1206,12 @@ undefined_symbol (info, name, abfd, section, address)
   if (section != NULL)
     {
       if (error_count < MAX_ERRORS_IN_A_ROW)
-       einfo (_("%X%C: undefined reference to `%T'\n"),
-              abfd, section, address, name);
+       {
+         einfo (_("%C: undefined reference to `%T'\n"),
+                abfd, section, address, name);
+         if (fatal)
+           einfo ("%X");
+       }
       else if (error_count == MAX_ERRORS_IN_A_ROW)
        einfo (_("%D: more undefined references to `%T' follow\n"),
               abfd, section, address, name);
@@ -1186,8 +1219,12 @@ undefined_symbol (info, name, abfd, section, address)
   else
     {
       if (error_count < MAX_ERRORS_IN_A_ROW)
-       einfo (_("%X%B: undefined reference to `%T'\n"),
-              abfd, name);
+       {
+         einfo (_("%B: undefined reference to `%T'\n"),
+                abfd, name);
+         if (fatal)
+           einfo ("%X");
+       }
       else if (error_count == MAX_ERRORS_IN_A_ROW)
        einfo (_("%B: more undefined references to `%T' follow\n"),
               abfd, name);
@@ -1201,7 +1238,7 @@ undefined_symbol (info, name, abfd, section, address)
 /*ARGSUSED*/
 static boolean
 reloc_overflow (info, name, reloc_name, addend, abfd, section, address)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      const char *name;
      const char *reloc_name;
      bfd_vma addend;
@@ -1225,7 +1262,7 @@ reloc_overflow (info, name, reloc_name, addend, abfd, section, address)
 /*ARGSUSED*/
 static boolean
 reloc_dangerous (info, message, abfd, section, address)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      const char *message;
      bfd *abfd;
      asection *section;
@@ -1245,7 +1282,7 @@ reloc_dangerous (info, message, abfd, section, address)
 /*ARGSUSED*/
 static boolean
 unattached_reloc (info, name, abfd, section, address)
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      const char *name;
      bfd *abfd;
      asection *section;