OSDN Git Service

* invoke.texi: Use @gol at ends of lines inside @gccoptlist.
[pf3gnuchains/gcc-fork.git] / gcc / collect2.c
index 83ed200..26548b4 100644 (file)
@@ -1,27 +1,27 @@
 /* Collect static initialization info into data structures that can be
    traversed by C++ initialization and finalization routines.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by Chris Smith (csmith@convex.com).
    Heavily modified by Michael Meissner (meissner@cygnus.com),
    Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 
 /* Build tables of static constructors and destructors and run ld.  */
@@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA.  */
 #  define SIGCHLD SIGCLD
 #endif
 
-#ifdef vfork /* Autoconf may define this to fork for us. */
+#ifdef vfork /* Autoconf may define this to fork for us.  */
 # define VFORK_STRING "fork"
 #else
 # define VFORK_STRING "vfork"
@@ -154,6 +154,15 @@ Boston, MA 02111-1307, USA.  */
 /* This must match tree.h.  */
 #define DEFAULT_INIT_PRIORITY 65535
 
+#ifndef COLLECT_SHARED_INIT_FUNC
+#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
+  fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
+#endif
+#ifndef COLLECT_SHARED_FINI_FUNC
+#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
+  fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
+#endif
+
 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
 #define SCAN_LIBRARIES
 #endif
@@ -163,6 +172,10 @@ int do_collecting = 1;
 #else
 int do_collecting = 0;
 #endif
+
+/* Nonzero if we should suppress the automatic demangling of identifiers
+   in linker error messages.  Set from COLLECT_NO_DEMANGLE.  */
+int no_demangle;
 \f
 /* Linked lists of constructor and destructor names.  */
 
@@ -254,13 +267,13 @@ struct path_prefix
 };
 
 #ifdef COLLECT_EXPORT_LIST
-/* Lists to keep libraries to be scanned for global constructors/destructors. */
+/* Lists to keep libraries to be scanned for global constructors/destructors.  */
 static struct head libs;                    /* list of libraries */
 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
                                          &libpath_lib_dirs, NULL};
-static const char *libexts[3] = {"a", "so", NULL};  /* possible library extentions */
+static const char *const libexts[3] = {"a", "so", NULL};  /* possible library extensions */
 #endif
 
 static void handler            PARAMS ((int));
@@ -296,15 +309,18 @@ static void scan_libraries        PARAMS ((const char *));
 static int is_in_args          PARAMS ((const char *, const char **, const char **));
 #endif
 #ifdef COLLECT_EXPORT_LIST
+#if 0
 static int is_in_list          PARAMS ((const char *, struct id *));
+#endif
 static void write_aix_file     PARAMS ((FILE *, struct id *));
 static char *resolve_lib_name  PARAMS ((const char *));
 static int ignore_library      PARAMS ((const char *));
 #endif
 static char *extract_string    PARAMS ((const char **));
 \f
-#ifdef NO_DUP2
-int
+#ifndef HAVE_DUP2
+static int dup2 PARAMS ((int, int));
+static int
 dup2 (oldfd, newfd)
      int oldfd;
      int newfd;
@@ -323,7 +339,7 @@ dup2 (oldfd, newfd)
 
   return fd;
 }
-#endif
+#endif /* ! HAVE_DUP2 */
 \f
 /* Delete tempfiles and exit function.  */
 
@@ -359,19 +375,11 @@ collect_exit (status)
 void
 notice VPARAMS ((const char *msgid, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
   vfprintf (stderr, _(msgid), ap);
-  va_end (ap);
+  VA_CLOSE (ap);
 }
 
 /* Die when sys call fails.  */
@@ -379,22 +387,15 @@ notice VPARAMS ((const char *msgid, ...))
 void
 fatal_perror VPARAMS ((const char * msgid, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
   int e = errno;
-  va_list ap;
-
-  VA_START (ap, msgid);
 
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
   fprintf (stderr, "collect2: ");
   vfprintf (stderr, _(msgid), ap);
   fprintf (stderr, ": %s\n", xstrerror (e));
-  va_end (ap);
+  VA_CLOSE (ap);
 
   collect_exit (FATAL_EXIT_CODE);
 }
@@ -404,21 +405,13 @@ fatal_perror VPARAMS ((const char * msgid, ...))
 void
 fatal VPARAMS ((const char * msgid, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
-  va_list ap;
-  
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
   
   fprintf (stderr, "collect2: ");
   vfprintf (stderr, _(msgid), ap);
   fprintf (stderr, "\n");
-  va_end (ap);
+  VA_CLOSE (ap);
 
   collect_exit (FATAL_EXIT_CODE);
 }
@@ -428,21 +421,13 @@ fatal VPARAMS ((const char * msgid, ...))
 void
 error VPARAMS ((const char * msgid, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  const char * msgid;
-#endif
-  va_list ap;
-  VA_START (ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
   fprintf (stderr, "collect2: ");
   vfprintf (stderr, _(msgid), ap);
   fprintf (stderr, "\n");
-  va_end(ap);
+  VA_CLOSE(ap);
 }
 
 /* In case obstack is linked in, and abort is defined to fancy_abort,
@@ -522,7 +507,6 @@ dump_file (name)
      const char *name;
 {
   FILE *stream = fopen (name, "r");
-  int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
 
   if (stream == 0)
     return;
@@ -530,7 +514,7 @@ dump_file (name)
     {
       int c;
       while (c = getc (stream),
-            c != EOF && (ISALNUM (c) || c == '_' || c == '$' || c == '.'))
+            c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
        obstack_1grow (&temporary_obstack, c);
       if (obstack_object_size (&temporary_obstack) > 0)
        {
@@ -548,7 +532,7 @@ dump_file (name)
          if (no_demangle)
            result = 0;
          else
-           result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
+           result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
 
          if (result)
            {
@@ -556,7 +540,7 @@ dump_file (name)
              fputs (result, stderr);
 
              diff = strlen (word) - strlen (result);
-             while (diff > 0)
+             while (diff > 0 && c == ' ')
                --diff, putc (' ', stderr);
              while (diff < 0 && c == ' ')
                ++diff, c = getc (stream);
@@ -585,13 +569,14 @@ static int
 is_ctor_dtor (s)
      const char *s;
 {
-  struct names { const char *name; int len; int ret; int two_underscores; };
+  struct names { const char *const name; const int len; const int ret;
+    const int two_underscores; };
 
-  register struct names *p;
-  register int ch;
-  register const char *orig_s = s;
+  const struct names *p;
+  int ch;
+  const char *orig_s = s;
 
-  static struct names special[] = {
+  static const struct names special[] = {
     { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
     { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
     { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
@@ -824,22 +809,48 @@ main (argc, argv)
      int argc;
      char *argv[];
 {
-  const char *ld_suffix        = "ld";
-  const char *full_ld_suffix   = ld_suffix;
-  const char *real_ld_suffix   = "real-ld";
-  const char *collect_ld_suffix = "collect-ld";
-  const char *nm_suffix        = "nm";
-  const char *full_nm_suffix   = nm_suffix;
-  const char *gnm_suffix       = "gnm";
-  const char *full_gnm_suffix  = gnm_suffix;
+  static const char *const ld_suffix   = "ld";
+  static const char *const real_ld_suffix = "real-ld";
+  static const char *const collect_ld_suffix = "collect-ld";
+  static const char *const nm_suffix   = "nm";
+  static const char *const gnm_suffix  = "gnm";
+#ifdef LDD_SUFFIX
+  static const char *const ldd_suffix  = LDD_SUFFIX;
+#endif
+  static const char *const strip_suffix = "strip";
+  static const char *const gstrip_suffix = "gstrip";
+
+#ifdef CROSS_COMPILE
+  /* If we look for a program in the compiler directories, we just use
+     the short name, since these directories are already system-specific.
+     But it we look for a program in the system directories, we need to
+     qualify the program name with the target machine.  */
+
+  const char *const full_ld_suffix =
+    concat(target_machine, "-", ld_suffix, NULL);
+  const char *const full_nm_suffix =
+    concat (target_machine, "-", nm_suffix, NULL);
+  const char *const full_gnm_suffix =
+    concat (target_machine, "-", gnm_suffix, NULL);
+#ifdef LDD_SUFFIX
+  const char *const full_ldd_suffix =
+    concat (target_machine, "-", ldd_suffix, NULL);
+#endif
+  const char *const full_strip_suffix =
+    concat (target_machine, "-", strip_suffix, NULL);
+  const char *const full_gstrip_suffix =
+    concat (target_machine, "-", gstrip_suffix, NULL);
+#else
+  const char *const full_ld_suffix     = ld_suffix;
+  const char *const full_nm_suffix     = nm_suffix;
+  const char *const full_gnm_suffix    = gnm_suffix;
 #ifdef LDD_SUFFIX
-  const char *ldd_suffix       = LDD_SUFFIX;
-  const char *full_ldd_suffix  = ldd_suffix;
+  const char *const full_ldd_suffix    = ldd_suffix;
 #endif
-  const char *strip_suffix     = "strip";
-  const char *full_strip_suffix = strip_suffix;
-  const char *gstrip_suffix    = "gstrip";
-  const char *full_gstrip_suffix = gstrip_suffix;
+  const char *const full_strip_suffix  = strip_suffix;
+  const char *const full_gstrip_suffix = gstrip_suffix;
+#endif /* CROSS_COMPILE */
+
   const char *arg;
   FILE *outf;
 #ifdef COLLECT_EXPORT_LIST
@@ -858,8 +869,13 @@ main (argc, argv)
   int first_file;
   int num_c_args       = argc+9;
 
+  no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
+
+  /* Suppress demangling by the real linker, which may be broken.  */
+  putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
+
 #if defined (COLLECT2_HOST_INITIALIZATION)
-  /* Perform system dependent initialization, if neccessary.  */
+  /* Perform system dependent initialization, if necessary.  */
   COLLECT2_HOST_INITIALIZATION;
 #endif
 
@@ -869,18 +885,7 @@ main (argc, argv)
   signal (SIGCHLD, SIG_DFL);
 #endif
 
-/* LC_CTYPE determines the character set used by the terminal so it has be set
-   to output messages correctly.  */
-
-#ifdef HAVE_LC_MESSAGES
-  setlocale (LC_CTYPE, "");
-  setlocale (LC_MESSAGES, "");
-#else
-  setlocale (LC_ALL, "");
-#endif
-
-  (void) bindtextdomain (PACKAGE, localedir);
-  (void) textdomain (PACKAGE);
+  gcc_init_libintl ();
 
   /* Do not invoke xcalloc before this point, since locale needs to be
      set first, in case a diagnostic is issued.  */
@@ -959,31 +964,6 @@ main (argc, argv)
   prefix_from_env ("COMPILER_PATH", &cpath);
   prefix_from_env ("PATH", &path);
 
-#ifdef CROSS_COMPILE
-  /* If we look for a program in the compiler directories, we just use
-     the short name, since these directories are already system-specific.
-     But it we look for a program in the system directories, we need to
-     qualify the program name with the target machine.  */
-
-  full_ld_suffix = concat(target_machine, "-", ld_suffix, NULL);
-
-#if 0
-  full_gld_suffix = concat (target_machine, "-", gld_suffix, NULL);
-#endif
-
-  full_nm_suffix = concat (target_machine, "-", nm_suffix, NULL);
-
-  full_gnm_suffix = concat (target_machine, "-", gnm_suffix, NULL);
-  
-#ifdef LDD_SUFFIX
-  full_ldd_suffix = concat (target_machine, "-", ldd_suffix, NULL);
-#endif
-
-  full_strip_suffix = concat (target_machine, "-", strip_suffix, NULL);
-  
-  full_gstrip_suffix = concat (target_machine, "-", gstrip_suffix, NULL);
-#endif /* CROSS_COMPILE */
-
   /* Try to discover a valid linker/nm/strip to use.  */
 
   /* Maybe we know the right file to use (if not cross).  */
@@ -1100,7 +1080,7 @@ main (argc, argv)
        *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
       if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
        *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
-      if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
+      if (strcmp (q, "-shared") == 0)
        shared_obj = 1;
       if (*q == '-' && q[1] == 'B')
        {
@@ -1427,7 +1407,7 @@ main (argc, argv)
       return 0;
     }
 
-  /* Sort ctor and dtor lists by priority. */
+  /* Sort ctor and dtor lists by priority.  */
   sort_ids (&constructors);
   sort_ids (&destructors);
 
@@ -1624,7 +1604,7 @@ collect_execute (prog, argv, redir)
       dup2 (stdout_save, STDOUT_FILENO);
       dup2 (stderr_save, STDERR_FILENO);
 
-      /* Close reponse file.  */
+      /* Close response file.  */
       close (redir_handle);
     }
 
@@ -1703,7 +1683,7 @@ extract_init_priority (name)
     ++pos;
   pos += 10; /* strlen ("GLOBAL__X_") */
 
-  /* Extract init_p number from ctor/dtor name. */
+  /* Extract init_p number from ctor/dtor name.  */
   pri = atoi (name + pos);
   return pri ? pri : DEFAULT_INIT_PRIORITY;
 }
@@ -1786,6 +1766,7 @@ is_in_args (string, args_begin, args_end)
 
 #ifdef COLLECT_EXPORT_LIST
 /* This function is really used only on AIX, but may be useful.  */
+#if 0
 static int
 is_in_list (prefix, list)
      const char *prefix;
@@ -1799,6 +1780,7 @@ is_in_list (prefix, list)
     return 0;
 }
 #endif
+#endif /* COLLECT_EXPORT_LIST */
 
 /* Added for debugging purpose.  */
 #ifdef COLLECT_EXPORT_LIST
@@ -1971,8 +1953,8 @@ write_c_file_stat (stream, name)
 
   if (shared_obj)
     {
-      fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
-      fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
+      COLLECT_SHARED_INIT_FUNC(stream, initname);
+      COLLECT_SHARED_FINI_FUNC(stream, fininame);
     }
 }
 
@@ -2342,7 +2324,7 @@ libcompare (d1, d2)
       /* It has a valid numeric extension, prefer this one.  */
       if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
        return 1;
-      /* It has a invalid numeric extension, must prefer the other one.  */
+      /* It has an invalid numeric extension, must prefer the other one.  */
       else
        return -1;
     }
@@ -2351,7 +2333,7 @@ libcompare (d1, d2)
       /* It has a valid numeric extension, prefer this one.  */
       if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
        return -1;
-      /* It has a invalid numeric extension, must prefer the other one.  */
+      /* It has an invalid numeric extension, must prefer the other one.  */
       else
        return 1;
     }
@@ -2879,7 +2861,7 @@ scan_prog_file (prog_name, which_pass)
   (void) ldclose(ldptr);
 #endif
 }
-
+#endif /* OBJECT_FORMAT_COFF */
 
 #ifdef COLLECT_EXPORT_LIST
 /* Given a library name without "lib" prefix, this function
@@ -2924,13 +2906,13 @@ if (debug) fprintf (stderr, "found: %s\n", lib_buf);
   if (debug)
     fprintf (stderr, "not found\n");
   else
-    fatal ("Library lib%s not found", name);
+    fatal ("library lib%s not found", name);
   return (NULL);
 }
 
 /* Array of standard AIX libraries which should not
    be scanned for ctors/dtors.  */
-static const char *aix_std_libs[] = {
+static const char *const aix_std_libs[] = {
   "/unix",
   "/lib/libc.a",
   "/lib/libm.a",
@@ -2949,19 +2931,17 @@ static const char *aix_std_libs[] = {
 };
 
 /* This function checks the filename and returns 1
-   if this name matches the location of a standard AIX library. */
+   if this name matches the location of a standard AIX library.  */
 static int
 ignore_library (name)
      const char *name;
 {
-  const char **p = &aix_std_libs[0];
+  const char *const *p = &aix_std_libs[0];
   while (*p++ != NULL)
     if (! strcmp (name, *p)) return 1;
   return 0;
 }
-#endif
-
-#endif /* OBJECT_FORMAT_COFF */
+#endif /* COLLECT_EXPORT_LIST */
 
 \f
 /*