OSDN Git Service

2001-05-03 David O'Brien <obrien@FreeBSD.org>
[pf3gnuchains/gcc-fork.git] / gcc / collect2.c
index fcfdb34..83ed200 100644 (file)
@@ -1,7 +1,7 @@
 /* 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 Free Software Foundation, Inc.
+   1999, 2000, 2001 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).
@@ -29,6 +29,9 @@ Boston, MA 02111-1307, USA.  */
 #include "config.h"
 #include "system.h"
 #include <signal.h>
+#if ! defined( SIGCHLD ) && defined( SIGCLD )
+#  define SIGCHLD SIGCLD
+#endif
 
 #ifdef vfork /* Autoconf may define this to fork for us. */
 # define VFORK_STRING "fork"
@@ -289,6 +292,9 @@ static void scan_prog_file  PARAMS ((const char *, enum pass));
 #ifdef SCAN_LIBRARIES
 static void scan_libraries     PARAMS ((const char *));
 #endif
+#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
+static int is_in_args          PARAMS ((const char *, const char **, const char **));
+#endif
 #ifdef COLLECT_EXPORT_LIST
 static int is_in_list          PARAMS ((const char *, struct id *));
 static void write_aix_file     PARAMS ((FILE *, struct id *));
@@ -586,21 +592,9 @@ is_ctor_dtor (s)
   register const char *orig_s = s;
 
   static struct names special[] = {
-#ifdef NO_DOLLAR_IN_LABEL
-#ifdef NO_DOT_IN_LABEL
     { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
     { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
     { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
-#else
-    { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
-    { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
-    { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
-#endif
-#else
-    { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
-    { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
-    { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
-#endif
     { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
     { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
@@ -661,8 +655,8 @@ find_a_file (pprefix, name)
   if (debug)
     fprintf (stderr, "Looking for '%s'\n", name);
   
-#ifdef EXECUTABLE_SUFFIX
-  len += strlen (EXECUTABLE_SUFFIX);
+#ifdef HOST_EXECUTABLE_SUFFIX
+  len += strlen (HOST_EXECUTABLE_SUFFIX);
 #endif
 
   temp = xmalloc (len);
@@ -685,11 +679,11 @@ find_a_file (pprefix, name)
          return temp;
        }
 
-#ifdef EXECUTABLE_SUFFIX
+#ifdef HOST_EXECUTABLE_SUFFIX
        /* Some systems have a suffix for executable files.
           So try appending that.  */
       strcpy (temp, name);
-       strcat (temp, EXECUTABLE_SUFFIX);
+       strcat (temp, HOST_EXECUTABLE_SUFFIX);
        
        if (access (temp, X_OK) == 0)
          return temp;
@@ -711,10 +705,10 @@ find_a_file (pprefix, name)
            && access (temp, X_OK) == 0)
          return temp;
 
-#ifdef EXECUTABLE_SUFFIX
+#ifdef HOST_EXECUTABLE_SUFFIX
        /* Some systems have a suffix for executable files.
           So try appending that.  */
-       strcat (temp, EXECUTABLE_SUFFIX);
+       strcat (temp, HOST_EXECUTABLE_SUFFIX);
        
        if (stat (temp, &st) >= 0
            && ! S_ISDIR (st.st_mode)
@@ -850,7 +844,6 @@ main (argc, argv)
   FILE *outf;
 #ifdef COLLECT_EXPORT_LIST
   FILE *exportf;
-  FILE *importf;
 #endif
   const char *ld_file_name;
   const char *p;
@@ -870,6 +863,12 @@ main (argc, argv)
   COLLECT2_HOST_INITIALIZATION;
 #endif
 
+#ifdef SIGCHLD
+  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
+     receive the signal.  A different setting is inheritable */
+  signal (SIGCHLD, SIG_DFL);
+#endif
+
 /* LC_CTYPE determines the character set used by the terminal so it has be set
    to output messages correctly.  */
 
@@ -916,7 +915,7 @@ main (argc, argv)
   obstack_begin (&permanent_obstack, 0);
   temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
 
-  current_demangling_style = gnu_demangling;
+  current_demangling_style = auto_demangling;
   p = getenv ("COLLECT_GCC_OPTIONS");
   while (p && *p)
     {
@@ -1181,6 +1180,13 @@ main (argc, argv)
                    case 'L':
              add_prefix (&cmdline_lib_dirs, arg+2);
              break;
+#else 
+#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
+           case 'L':
+             if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
+               --ld1;
+             break;
+#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
 #endif
 
            case 'o':
@@ -1219,7 +1225,8 @@ main (argc, argv)
        }
       else if ((p = strrchr (arg, '.')) != (char *) 0
               && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
-                  || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0))
+                  || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
+                  || strcmp (p, ".obj") == 0))
        {
          if (first_file)
            {
@@ -1272,9 +1279,8 @@ main (argc, argv)
 
   if (exports.first)
     {
-      char *buf = xmalloc (strlen (export_file) + 5);
-
-      sprintf (buf, "-bE:%s", export_file);
+      char *buf = concat ("-bE:", export_file, NULL);
+      
       *ld1++ = buf;
       *ld2++ = buf;
 
@@ -1438,13 +1444,7 @@ main (argc, argv)
   /* Tell the linker that we have initializer and finalizer functions.  */
 #ifdef LD_INIT_SWITCH
 #ifdef COLLECT_EXPORT_LIST
-  {
-    /* option name + functions + colons + NULL */
-    char *buf = xmalloc (strlen (LD_INIT_SWITCH)
-                        + strlen(initname) + strlen(fininame) + 3);
-    sprintf (buf, "%s:%s:%s", LD_INIT_SWITCH, initname, fininame);
-    *ld2++ = buf;
-  }
+  *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
 #else
   *ld2++ = LD_INIT_SWITCH;
   *ld2++ = initname;
@@ -1459,12 +1459,7 @@ main (argc, argv)
       /* If we did not add export flag to link arguments before, add it to
         second link phase now.  No new exports should have been added.  */
       if (! exports.first)
-       {
-         char *buf = xmalloc (strlen (export_file) + 5);
-
-         sprintf (buf, "-bE:%s", export_file);
-         *ld2++ = buf;
-       }
+       *ld2++ = concat ("-bE:", export_file, NULL);
 
       add_to_list (&exports, initname);
       add_to_list (&exports, fininame);
@@ -1771,6 +1766,24 @@ write_list (stream, prefix, list)
     }
 }
 
+#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
+/* Given a STRING, return nonzero if it occurs in the list in range
+   [ARGS_BEGIN,ARGS_END).  */
+
+static int
+is_in_args (string, args_begin, args_end)
+     const char *string;
+     const char **args_begin;
+     const char **args_end;
+{
+  const char **args_pointer;
+  for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
+    if (strcmp (string, *args_pointer) == 0)
+      return 1;
+  return 0;
+}
+#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
+
 #ifdef COLLECT_EXPORT_LIST
 /* This function is really used only on AIX, but may be useful.  */
 static int
@@ -1881,13 +1894,8 @@ write_c_file_stat (stream, name)
     notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
            output_file, prefix);
 
-#define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
-  initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
-  sprintf (initname, INIT_NAME_FORMAT, prefix);
-
-#define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
-  fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
-  sprintf (fininame, FINI_NAME_FORMAT, prefix);
+  initname = concat ("_GLOBAL__FI_", prefix, NULL);
+  fininame = concat ("_GLOBAL__FD_", prefix, NULL);
 
   free (prefix);
 
@@ -2664,13 +2672,16 @@ scan_libraries (prog_name)
 #ifdef OBJECT_FORMAT_COFF
 
 #if defined(EXTENDED_COFF)
+
 #   define GCC_SYMBOLS(X)      (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
 #   define GCC_SYMENT          SYMR
 #   define GCC_OK_SYMBOL(X)    ((X).st == stProc || (X).st == stGlobal)
 #   define GCC_SYMINC(X)       (1)
 #   define GCC_SYMZERO(X)      (SYMHEADER(X).isymMax)
 #   define GCC_CHECK_HDR(X)    (PSYMTAB(X) != 0)
+
 #else
+
 #   define GCC_SYMBOLS(X)      (HEADER(ldptr).f_nsyms)
 #   define GCC_SYMENT          SYMENT
 #   define GCC_OK_SYMBOL(X) \
@@ -2683,14 +2694,21 @@ scan_libraries (prog_name)
      (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
 #   define GCC_SYMINC(X)       ((X).n_numaux+1)
 #   define GCC_SYMZERO(X)      0
+
+/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
+#ifdef _AIX51
+#   define GCC_CHECK_HDR(X) \
+     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
+      || (HEADER (X).f_magic == 0767 && aix64_flag))
+#else
 #   define GCC_CHECK_HDR(X) \
      ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
       || (HEADER (X).f_magic == 0757 && aix64_flag))
 #endif
 
-extern char *ldgetname PARAMS ((LDFILE *, GCC_SYMENT *));
-extern int ldtbread PARAMS ((LDFILE *, long, GCC_SYMENT *));
-extern int ldclose PARAMS ((LDFILE *));
+#endif
+
+extern char *ldgetname ();
 
 /* COFF version to scan the name list of the loaded program for
    the symbols g++ uses for static constructors and destructors.
@@ -2915,12 +2933,18 @@ if (debug) fprintf (stderr, "found: %s\n", lib_buf);
 static const char *aix_std_libs[] = {
   "/unix",
   "/lib/libc.a",
+  "/lib/libm.a",
   "/lib/libc_r.a",
+  "/lib/libm_r.a",
   "/usr/lib/libc.a",
+  "/usr/lib/libm.a",
   "/usr/lib/libc_r.a",
+  "/usr/lib/libm_r.a",
   "/usr/lib/threads/libc.a",
   "/usr/ccs/lib/libc.a",
+  "/usr/ccs/lib/libm.a",
   "/usr/ccs/lib/libc_r.a",
+  "/usr/ccs/lib/libm_r.a",
   NULL
 };