]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/collect2.c
*** empty log message ***
[gcc.git] / gcc / collect2.c
index 3c6bc8968b6ad96b1a8a4719e9a807553d64b981..a3da8bc2b52605470a03dff0a349fb23833e07ac 100644 (file)
@@ -34,7 +34,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <signal.h>
 #include <sys/file.h>
 #include <sys/stat.h>
+#ifdef NO_WAIT_H
 #include <sys/wait.h>
+#endif
 
 #ifndef errno
 extern int errno;
@@ -168,6 +170,7 @@ extern char *version_string;
 
 static int vflag;                      /* true if -v */
 static int rflag;                      /* true if -r */
+static int strip_flag;                 /* true if -s */
 
 static int debug;                      /* true if -debug */
 
@@ -176,13 +179,13 @@ static char *temp_filename;               /* Base of temp filenames */
 static char *c_file;                   /* <xxx>.c for constructor/destructor list. */
 static char *o_file;                   /* <xxx>.o for constructor/destructor list. */
 static char *nm_file_name;             /* pathname of nm */
+static char *strip_file_name;          /* pathname of strip */
 
 static struct head constructors;       /* list of constructors found */
 static struct head destructors;                /* list of destructors found */
 
 extern char *getenv ();
 extern char *mktemp ();
-extern int   vfork ();
 static void  add_to_list ();
 static void  scan_prog_file ();
 static void  fork_execute ();
@@ -446,7 +449,7 @@ main (argc, argv)
       {
        char *q = p;
        while (*q && *q != ' ') q++;
-       if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
+       if (*p == '-' && p[1] == 'm')
          num_c_args++;
 
        if (*q) q++;
@@ -465,7 +468,7 @@ main (argc, argv)
   signal (SIGSEGV, handler);
   signal (SIGBUS,  handler);
 
-  /* Try to discover a valid linker/assembler/nm to use.  */
+  /* Try to discover a valid linker/assembler/nm/strip to use.  */
   len = strlen (argv[0]);
   prefix = (char *)0;
   if (len >= sizeof ("ld")-1)
@@ -519,10 +522,13 @@ main (argc, argv)
     clen = sizeof (STANDARD_EXEC_PREFIX) - 1;
 #endif
 
+  /* Allocate enough string space for the longest possible pathnames.  */
   ld_file_name = xcalloc (len + sizeof ("real-ld"), 1);
   nm_file_name = xcalloc (len + sizeof ("gnm"), 1);
+  strip_file_name = xcalloc (len + sizeof ("gstrip"), 1);
 
-  memcpy (ld_file_name, prefix, len);
+  /* Determine the full path name of the ld program to use.  */
+  bcopy (prefix, ld_file_name, len);
   strcpy (ld_file_name + len, "real-ld");
   if (access (ld_file_name, X_OK) < 0)
     {
@@ -533,16 +539,18 @@ main (argc, argv)
 #ifdef REAL_LD_FILE_NAME
          ld_file_name = REAL_LD_FILE_NAME;
 #else
-         ld_file_name = (access ("/usr/bin/ld", X_OK) == 0) ? "/usr/bin/ld" : "/bin/ld";
+         ld_file_name = (access ("/usr/bin/ld", X_OK) == 0
+                         ? "/usr/bin/ld" : "/bin/ld");
 #endif
        }
     }
 
+  /* Determine the full path name of the C compiler to use.  */
   c_file_name = getenv ("COLLECT_GCC");
   if (c_file_name == 0 || c_file_name[0] != '/')
     {
       c_file_name = xcalloc (clen + sizeof ("gcc"), 1);
-      memcpy (c_file_name, prefix, len);
+      bcopy (prefix, c_file_name, len);
       strcpy (c_file_name + len, "gcc");
       if (access (c_file_name, X_OK) < 0)
        {
@@ -564,7 +572,8 @@ main (argc, argv)
        }
     }
 
-  memcpy (nm_file_name, prefix, len);
+  /* Determine the full path name of the nm to use.  */
+  bcopy (prefix, nm_file_name, len);
   strcpy (nm_file_name + len, "nm");
   if (access (nm_file_name, X_OK) < 0)
     {
@@ -575,7 +584,26 @@ main (argc, argv)
 #ifdef REAL_NM_FILE_NAME
          nm_file_name = REAL_NM_FILE_NAME;
 #else
-         nm_file_name = (access ("/usr/bin/nm", X_OK) == 0) ? "/usr/bin/nm" : "/bin/nm";
+         nm_file_name = (access ("/usr/bin/nm", X_OK) == 0
+                         ? "/usr/bin/nm" : "/bin/nm");
+#endif
+       }
+    }
+
+  /* Determine the full pathname of the strip to use.  */
+  bcopy (prefix, strip_file_name, len);
+  strcpy (strip_file_name + len, "strip");
+  if (access (strip_file_name, X_OK) < 0)
+    {
+      strcpy (strip_file_name + len, "gstrip");
+      if (access (strip_file_name, X_OK) < 0)
+       {
+         free (strip_file_name);
+#ifdef REAL_STRIP_FILE_NAME
+         strip_file_name = REAL_STRIP_FILE_NAME;
+#else
+         strip_file_name = (access ("/usr/bin/strip", X_OK) == 0
+                            ? "/usr/bin/strip" : "/bin/strip");
 #endif
        }
     }
@@ -630,6 +658,17 @@ main (argc, argv)
                rflag = 1;
              break;
 
+           case 's':
+             if (arg[2] == '\0')
+               {
+                 /* We must strip after the nm run, otherwise C++ linking
+                    won't work.  Thus we strip in the second ld run, or
+                    else with strip if there is no second ld run.  */
+                 strip_flag = 1;
+                 ld1--;
+               }
+             break;
+
            case 'v':
              if (arg[2] == '\0')
                vflag = 1;
@@ -720,7 +759,18 @@ main (argc, argv)
     }
 
   if (constructors.number == 0 && destructors.number == 0)
-    return 0;
+    {
+      /* Strip now if it was requested on the command line.  */
+      if (strip_flag)
+       {
+         char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
+         strip_argv[0] = "strip";
+         strip_argv[1] = outfile;
+         strip_argv[2] = (char *) 0;
+         fork_execute (strip_file_name, strip_argv);
+       }
+      return 0;
+    }
 
   outf = fopen (c_file, "w");
   if (outf == (FILE *)0)
@@ -916,14 +966,14 @@ write_c_file (stream, name)
 
   fprintf (stream, "typedef void entry_pt();\n\n");
     
-  write_list_with_asm (stream, "entry_pt ", constructors.first);
+  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
     
   fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
   fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
   write_list (stream, "\t", constructors.first);
   fprintf (stream, "\t0\n};\n\n");
 
-  write_list_with_asm (stream, "entry_pt ", destructors.first);
+  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
 
   fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
   fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
@@ -1087,20 +1137,22 @@ scan_prog_file (prog_name, which_pass)
 #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).sc == scText)
-#   define GCC_SYMINC(X) (1)
-#   define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
+#   define GCC_SYMBOLS(X)      (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
+#   define GCC_SYMENT          SYMR
+#   define GCC_OK_SYMBOL(X)    ((X).st == stProc && (X).sc == scText)
+#   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_SYMBOLS(X)      (HEADER(ldptr).f_nsyms)
+#   define GCC_SYMENT          SYMENT
 #   define GCC_OK_SYMBOL(X) \
      (((X).n_sclass == C_EXT) && \
         (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
          ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
-#   define GCC_SYMINC(X) ((X).n_numaux+1)
-#   define GCC_SYMZERO(X) 0
+#   define GCC_SYMINC(X)       ((X).n_numaux+1)
+#   define GCC_SYMZERO(X)      0
+#   define GCC_CHECK_HDR(X)    (1)
 #endif
 
 extern char *ldgetname ();
@@ -1131,54 +1183,57 @@ scan_prog_file (prog_name, which_pass)
   if (!ISCOFF (HEADER(ldptr).f_magic))
     fatal ("%s: not a COFF file", prog_name);
 
-  sym_count = GCC_SYMBOLS (ldptr);
-  sym_index = GCC_SYMZERO (ldptr);
-  while (sym_index < sym_count)
+  if (GCC_CHECK_HDR (ldptr))
     {
-      GCC_SYMENT symbol;
+      sym_count = GCC_SYMBOLS (ldptr);
+      sym_index = GCC_SYMZERO (ldptr);
+      while (sym_index < sym_count)
+       {
+         GCC_SYMENT symbol;
 
-      if (ldtbread (ldptr, sym_index, &symbol) <= 0)
-       break;
-      sym_index += GCC_SYMINC (symbol);
+         if (ldtbread (ldptr, sym_index, &symbol) <= 0)
+           break;
+         sym_index += GCC_SYMINC (symbol);
 
-      if (GCC_OK_SYMBOL (symbol))
-       {
-         char *name;
+         if (GCC_OK_SYMBOL (symbol))
+           {
+             char *name;
 
-         if ((name = ldgetname (ldptr, &symbol)) == NULL)
-           continue;           /* should never happen */
+             if ((name = ldgetname (ldptr, &symbol)) == NULL)
+               continue;               /* should never happen */
 
 #ifdef _AIX
-         /* All AIX function names begin with a dot. */
-         if (*name++ != '.')
-           continue;
+             /* All AIX function names begin with a dot. */
+             if (*name++ != '.')
+               continue;
 #endif
 
-         switch (is_ctor_dtor (name))
-           {
-           case 1:
-             add_to_list (&constructors, name);
-             break;
+             switch (is_ctor_dtor (name))
+               {
+               case 1:
+                 add_to_list (&constructors, name);
+                 break;
 
-           case 2:
-             add_to_list (&destructors, name);
-             break;
+               case 2:
+                 add_to_list (&destructors, name);
+                 break;
 
-           default:            /* not a constructor or destructor */
-             continue;
-           }
+               default:                /* not a constructor or destructor */
+                 continue;
+               }
 
 #if !defined(EXTENDED_COFF)
-         if (debug)
-           fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
-                    symbol.n_scnum, symbol.n_sclass,
-                    (symbol.n_type ? "0" : ""), symbol.n_type,
-                    name);
+             if (debug)
+               fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
+                        symbol.n_scnum, symbol.n_sclass,
+                        (symbol.n_type ? "0" : ""), symbol.n_type,
+                        name);
 #else
-         if (debug)
-           fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
-                    symbol.iss, symbol.value, symbol.index, name);
+             if (debug)
+               fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
+                        symbol.iss, symbol.value, symbol.index, name);
 #endif
+           }
        }
     }
 
@@ -1329,7 +1384,7 @@ scan_prog_file (prog_name, which_pass)
       if (rw)
        {
          load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
-         memcpy (ptr, load_hdr, load_hdr->hdr.ldci_cmd_size);
+         bcopy (load_hdr, ptr, load_hdr->hdr.ldci_cmd_size);
          load_hdr = ptr;
 
          /* null out old command map, because we will rewrite at the end.  */
@@ -1512,7 +1567,7 @@ scan_prog_file (prog_name, which_pass)
          if (debug)
            print_load_command (load_hdr, offset, i);
 
-         memcpy (obj + offset, load_hdr, size);
+         bcopy (load_hdr, obj + offset, size);
          offset += size;
        }
     }
This page took 0.037002 seconds and 5 git commands to generate.