]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/collect2.c
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / collect2.c
index 6d074a79e9184a6781498f1342e1ab3272dfbb73..cf04a58ba4dd9d36be2df4c20d1aaf3eec6c0424 100644 (file)
@@ -1,6 +1,6 @@
 /* Collect static initialization info into data structures that can be
    traversed by C++ initialization and finalization routines.
-   Copyright (C) 1992-2020 Free Software Foundation, Inc.
+   Copyright (C) 1992-2021 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).
@@ -301,7 +301,6 @@ const char tool_name[] = "collect2";
 
 static symkind is_ctor_dtor (const char *);
 
-static void handler (int);
 static void maybe_unlink_list (char **);
 static void add_to_list (struct head *, const char *);
 static int extract_init_priority (const char *);
@@ -408,14 +407,6 @@ collect_atexit (void)
   tool_cleanup (false);
 }
 
-static void
-handler (int signo)
-{
-  tool_cleanup (true);
-
-  signal (signo, SIG_DFL);
-  raise (signo);
-}
 /* Notify user of a non-error, without translating the format string.  */
 void
 notice_translated (const char *cmsgid, ...)
@@ -644,7 +635,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
 
       /* Run the LTO back end.  */
       pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH,
-                            at_file_supplied);
+                            at_file_supplied, "lto_args");
       {
        int c;
        FILE *stream;
@@ -727,7 +718,8 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
 
       /* Run the linker again, this time replacing the object files
          optimized by the LTO with the temporary file generated by the LTO.  */
-      fork_execute ("ld", out_lto_ld_argv, HAVE_GNU_LD && at_file_supplied);
+      fork_execute ("ld", out_lto_ld_argv, HAVE_GNU_LD && at_file_supplied,
+                   "ld_args");
       /* We assume that temp files were created, and therefore we need to take
          that into account (maybe run dsymutil).  */
       post_ld_pass (/*temp_file*/true);
@@ -739,7 +731,8 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
     {
       /* Our caller is relying on us to do the link
          even though there is no LTO back end work to be done.  */
-      fork_execute ("ld", lto_ld_argv, HAVE_GNU_LD && at_file_supplied);
+      fork_execute ("ld", lto_ld_argv, HAVE_GNU_LD && at_file_supplied,
+                   "ld_args");
       /* No LTO objects were found, so no new temp file.  */
       post_ld_pass (/*temp_file*/false);
     }
@@ -750,13 +743,13 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
    LD_ARGV is an array of arguments for the linker.  */
 
 static void
-do_link (char **ld_argv)
+do_link (char **ld_argv, const char *atsuffix)
 {
   struct pex_obj *pex;
   const char *prog = "ld";
   pex = collect_execute (prog, ld_argv, NULL, NULL,
                         PEX_LAST | PEX_SEARCH,
-                        HAVE_GNU_LD && at_file_supplied);
+                        HAVE_GNU_LD && at_file_supplied, atsuffix);
   int ret = collect_wait (prog, pex);
   if (ret)
     {
@@ -905,11 +898,7 @@ main (int argc, char **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
+  setup_signals ();
 
   /* Unlock the stdio streams.  */
   unlock_std_streams ();
@@ -954,7 +943,7 @@ main (int argc, char **argv)
       {
        if (! strcmp (argv[i], "-debug"))
          debug = true;
-       else if (!strncmp (argv[i], "-fno-lto", 8))
+       else if (startswith (argv[i], "-fno-lto"))
          lto_mode = LTO_MODE_NONE;
         else if (! strcmp (argv[i], "-plugin"))
          {
@@ -968,33 +957,33 @@ main (int argc, char **argv)
          selected_linker = USE_GOLD_LD;
        else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
          selected_linker = USE_LLD_LD;
-       else if (strncmp (argv[i], "-o", 2) == 0)
+       else if (startswith (argv[i], "-o"))
          {
            /* Parse the output filename if it's given so that we can make
               meaningful temp filenames.  */
-           if (argv[i][2] == '\0')
-             output_file = argv[i+1];
-           else
+           if (argv[i][2] != '\0')
              output_file = &argv[i][2];
+           else if (argv[i+1] != NULL)
+             output_file = argv[++i];
          }
 
 #ifdef COLLECT_EXPORT_LIST
        /* These flags are position independent, although their order
           is important - subsequent flags override earlier ones. */
        else if (strcmp (argv[i], "-b64") == 0)
-           aix64_flag = 1;
+         aix64_flag = 1;
        /* -bexport:filename always needs the :filename */
-       else if (strncmp (argv[i], "-bE:", 4) == 0
-             || strncmp (argv[i], "-bexport:", 9) == 0)
-           export_flag = 1;
+       else if (startswith (argv[i], "-bE:")
+                || startswith (argv[i], "-bexport:"))
+         export_flag = 1;
        else if (strcmp (argv[i], "-brtl") == 0
              || strcmp (argv[i], "-bsvr4") == 0
              || strcmp (argv[i], "-G") == 0)
-           aixrtl_flag = 1;
+         aixrtl_flag = 1;
        else if (strcmp (argv[i], "-bnortl") == 0)
-           aixrtl_flag = 0;
+         aixrtl_flag = 0;
        else if (strcmp (argv[i], "-blazy") == 0)
-           aixlazy_flag = 1;
+         aixlazy_flag = 1;
 #endif
       }
 
@@ -1014,13 +1003,19 @@ main (int argc, char **argv)
        const char *q = extract_string (&p);
        if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
          num_c_args++;
-       if (strncmp (q, "-flto-partition=none", 20) == 0)
+       if (startswith (q, "-flto-partition=none"))
          no_partition = true;
-       else if (strncmp (q, "-fno-lto", 8) == 0)
+       else if (startswith (q, "-fno-lto"))
          lto_mode = LTO_MODE_NONE;
-       else if (strncmp (q, "-save-temps", 11) == 0)
+       else if (startswith (q, "-save-temps"))
          /* FIXME: Honour =obj.  */
          save_temps = true;
+       else if (strcmp (q, "-dumpdir") == 0)
+         dumppfx = xstrdup (extract_string (&p));
+       else if (strcmp (q, "-o") == 0
+                || strcmp (q, "-B") == 0
+                || strcmp (q, "-isystem") == 0)
+         (void) extract_string (&p);
     }
     obstack_free (&temporary_obstack, temporary_firstobj);
 
@@ -1043,27 +1038,6 @@ main (int argc, char **argv)
   if (argc < 2)
     fatal_error (input_location, "no arguments");
 
-#ifdef SIGQUIT
-  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
-    signal (SIGQUIT, handler);
-#endif
-  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
-    signal (SIGINT, handler);
-#ifdef SIGALRM
-  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
-    signal (SIGALRM, handler);
-#endif
-#ifdef SIGHUP
-  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
-    signal (SIGHUP, handler);
-#endif
-  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
-    signal (SIGSEGV, handler);
-#ifdef SIGBUS
-  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
-    signal (SIGBUS, handler);
-#endif
-
   /* Extract COMPILER_PATH and PATH into our prefix list.  */
   prefix_from_env ("COMPILER_PATH", &cpath);
   prefix_from_env ("PATH", &path);
@@ -1240,9 +1214,13 @@ main (int argc, char **argv)
              *c_ptr++ = xstrdup (q);
            }
        }
+      else if (strcmp (q, "-o") == 0
+              || strcmp (q, "-dumpdir") == 0
+              || strcmp (q, "-isystem") == 0)
+       (void) extract_string (&p);
 #ifdef COLLECT_EXPORT_LIST
       /* Detect any invocation with -fvisibility.  */
-      if (strncmp (q, "-fvisibility", 12) == 0)
+      if (startswith (q, "-fvisibility"))
        visibility_flag = 1;
 #endif
     }
@@ -1291,7 +1269,7 @@ main (int argc, char **argv)
              break;
 
             case 'f':
-             if (strncmp (arg, "-flto", 5) == 0)
+             if (startswith (arg, "-flto"))
                {
 #ifdef ENABLE_LTO
                  /* Do not pass LTO flag to the linker. */
@@ -1303,13 +1281,13 @@ main (int argc, char **argv)
 #endif
                }
              else if (!use_collect_ld
-                      && strncmp (arg, "-fuse-ld=", 9) == 0)
+                      && startswith (arg, "-fuse-ld="))
                {
                  /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */
                  ld1--;
                  ld2--;
                }
-             else if (strncmp (arg, "-fno-lto", 8) == 0)
+             else if (startswith (arg, "-fno-lto"))
                {
                  /* Do not pass -fno-lto to the linker. */
                  ld1--;
@@ -1414,10 +1392,10 @@ main (int argc, char **argv)
 #endif
 
            case 'o':
-             if (arg[2] == '\0')
-               output_file = *ld1++ = *ld2++ = *++argv;
-             else
+             if (arg[2] != '\0')
                output_file = &arg[2];
+             else if (argv[1])
+               output_file = *ld1++ = *ld2++ = *++argv;
              break;
 
            case 'r':
@@ -1450,7 +1428,7 @@ main (int argc, char **argv)
                  ld2--;
 #endif
                }
-             else if (strncmp (arg, "--demangle", 10) == 0)
+             else if (startswith (arg, "--demangle"))
                {
 #ifndef HAVE_LD_DEMANGLE
                  no_demangle = 0;
@@ -1467,7 +1445,7 @@ main (int argc, char **argv)
                  ld2--;
 #endif
                }
-             else if (strncmp (arg, "--sysroot=", 10) == 0)
+             else if (startswith (arg, "--sysroot="))
                target_system_root = arg + 10;
              else if (strcmp (arg, "--version") == 0)
                verbose = true;
@@ -1646,7 +1624,7 @@ main (int argc, char **argv)
        functions from precise cross reference insertions by the compiler.  */
 
     if (early_exit || ld1_filter != SCAN_NOTHING)
-      do_link (ld1_argv);
+      do_link (ld1_argv, "ld1_args");
 
     if (early_exit)
       {
@@ -1707,7 +1685,7 @@ main (int argc, char **argv)
       /* Do link without additional code generation now if we didn't
         do it earlier for scanning purposes.  */
       if (ld1_filter == SCAN_NOTHING)
-       do_link (ld1_argv);
+       do_link (ld1_argv, "ld1_args");
 
       if (lto_mode)
         maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
@@ -1722,7 +1700,7 @@ main (int argc, char **argv)
          strip_argv[0] = strip_file_name;
          strip_argv[1] = output_file;
          strip_argv[2] = (char *) 0;
-         fork_execute ("strip", real_strip_argv, false);
+         fork_execute ("strip", real_strip_argv, false, NULL);
        }
 
 #ifdef COLLECT_EXPORT_LIST
@@ -1805,10 +1783,10 @@ main (int argc, char **argv)
   /* Assemble the constructor and destructor tables.
      Link the tables in with the rest of the program.  */
 
-  fork_execute ("gcc",  c_argv, at_file_supplied);
+  fork_execute ("gcc",  c_argv, at_file_supplied, "gcc_args");
 #ifdef COLLECT_EXPORT_LIST
   /* On AIX we must call link because of possible templates resolution.  */
-  do_link (ld2_argv);
+  do_link (ld2_argv, "ld2_args");
 
   if (lto_mode)
     maybe_run_lto_and_relink (ld2_argv, object_lst, object, false);
@@ -1818,7 +1796,7 @@ main (int argc, char **argv)
     maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
   else
     {
-      fork_execute ("ld", ld2_argv, HAVE_GNU_LD && at_file_supplied);
+      fork_execute ("ld", ld2_argv, HAVE_GNU_LD && at_file_supplied, "ld_args");
       post_ld_pass (/*temp_file*/false);
     }
 
@@ -2295,13 +2273,9 @@ has_lto_section (void *data, const char *name ATTRIBUTE_UNUSED,
 {
   int *found = (int *) data;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
-              sizeof (LTO_SECTION_NAME_PREFIX) - 1) != 0)
-    {
-      if (strncmp (name, OFFLOAD_SECTION_NAME_PREFIX,
-                  sizeof (OFFLOAD_SECTION_NAME_PREFIX) - 1) != 0)
-        return 1;
-    }
+  if (!startswith (name, LTO_SECTION_NAME_PREFIX)
+      && !startswith (name, OFFLOAD_SECTION_NAME_PREFIX))
+    return 1;
 
   *found = 1;
 
@@ -2607,7 +2581,7 @@ scan_libraries (const char *prog_name)
        continue;
 
       name = p;
-      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
+      if (startswith (name, "not found"))
        fatal_error (input_location, "dynamic dependency %s not found", buf);
 
       /* Find the end of the symbol name.  */
@@ -2771,7 +2745,10 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
       if ((ldptr = ldopen (CONST_CAST (char *, prog_name), ldptr)) != NULL)
        {
          if (! MY_ISCOFF (HEADER (ldptr).f_magic))
-           fatal_error (input_location, "%s: not a COFF file", prog_name);
+           {
+             warning (0, "%s: not a COFF file", prog_name);
+             continue;
+           }
 
          if (GCC_CHECK_HDR (ldptr))
            {
@@ -3029,18 +3006,52 @@ process_args (int *argcp, char **argv) {
 
 static void
 do_dsymutil (const char *output_file) {
-  const char *dsymutil = DSYMUTIL + 1;
+  const char *dsymutil = 0;
   struct pex_obj *pex;
-  char **real_argv = XCNEWVEC (char *, 3);
+  char **real_argv = XCNEWVEC (char *, verbose ? 4 : 3);
   const char ** argv = CONST_CAST2 (const char **, char **,
                                    real_argv);
+/* For cross-builds search the PATH using target-qualified name if we
+   have not already found a suitable dsymutil.  In practice, all modern
+   versions of dsymutil handle all supported archs, however the approach
+   here is consistent with the way other installations work (and one can
+   always symlink a multitarget dsymutil with a target-specific name).  */
+  const char *dsname = "dsymutil";
+#ifdef CROSS_DIRECTORY_STRUCTURE
+  const char *qname = concat (target_machine, "-", dsname, NULL);
+#else
+  const char *qname = dsname;
+#endif
+#ifdef DEFAULT_DSYMUTIL
+  /* Configured default takes priority.  */
+  if (dsymutil == 0 && access (DEFAULT_DSYMUTIL, X_OK) == 0)
+    dsymutil = DEFAULT_DSYMUTIL;
+  if (dsymutil == 0)
+#endif
+#ifdef DSYMUTIL
+  /* Followed by one supplied in the target header, somewhat like the
+     REAL_XX_NAME used elsewhere.  */
+    dsymutil = find_a_file (&cpath, DSYMUTIL, X_OK);
+  if (dsymutil == 0)
+    dsymutil = find_a_file (&path, DSYMUTIL, X_OK);
+  if (dsymutil == 0)
+#endif
+    dsymutil = find_a_file (&cpath, dsname, X_OK);
+  if (dsymutil == 0)
+    dsymutil = find_a_file (&path, qname, X_OK);
 
   argv[0] = dsymutil;
   argv[1] = output_file;
-  argv[2] = (char *) 0;
+  if (verbose)
+    {
+      argv[2] = "-v";
+      argv[3] = (char *) 0;
+    }
+  else
+    argv[2] = (char *) 0;
 
   pex = collect_execute (dsymutil, real_argv, NULL, NULL,
-                        PEX_LAST | PEX_SEARCH, false);
+                        PEX_LAST | PEX_SEARCH, false, NULL);
   do_wait (dsymutil, pex);
 }