| 1 | 
         684 | 
         jeremybenn | 
         /* Wrapper to call lto.  Used by collect2 and the linker plugin.
  | 
      
      
         | 2 | 
          | 
          | 
            Copyright (C) 2009, 2010 Free Software Foundation, Inc.
  | 
      
      
         | 3 | 
          | 
          | 
          
  | 
      
      
         | 4 | 
          | 
          | 
            Factored out of collect2 by Rafael Espindola <espindola@google.com>
  | 
      
      
         | 5 | 
          | 
          | 
          
  | 
      
      
         | 6 | 
          | 
          | 
         This file is part of GCC.
  | 
      
      
         | 7 | 
          | 
          | 
          
  | 
      
      
         | 8 | 
          | 
          | 
         GCC is free software; you can redistribute it and/or modify it under
  | 
      
      
         | 9 | 
          | 
          | 
         the terms of the GNU General Public License as published by the Free
  | 
      
      
         | 10 | 
          | 
          | 
         Software Foundation; either version 3, or (at your option) any later
  | 
      
      
         | 11 | 
          | 
          | 
         version.
  | 
      
      
         | 12 | 
          | 
          | 
          
  | 
      
      
         | 13 | 
          | 
          | 
         GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  | 
      
      
         | 14 | 
          | 
          | 
         WARRANTY; without even the implied warranty of MERCHANTABILITY or
  | 
      
      
         | 15 | 
          | 
          | 
         FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  | 
      
      
         | 16 | 
          | 
          | 
         for more details.
  | 
      
      
         | 17 | 
          | 
          | 
          
  | 
      
      
         | 18 | 
          | 
          | 
         You should have received a copy of the GNU General Public License
  | 
      
      
         | 19 | 
          | 
          | 
         along with GCC; see the file COPYING3.  If not see
  | 
      
      
         | 20 | 
          | 
          | 
         <http://www.gnu.org/licenses/>.  */
  | 
      
      
         | 21 | 
          | 
          | 
          
  | 
      
      
         | 22 | 
          | 
          | 
          
  | 
      
      
         | 23 | 
          | 
          | 
         /* This program is passed a gcc, a list of gcc arguments and a list of
  | 
      
      
         | 24 | 
          | 
          | 
            object files containing IL. It scans the argument list to check if
  | 
      
      
         | 25 | 
          | 
          | 
            we are in whopr mode or not modifies the arguments and needed and
  | 
      
      
         | 26 | 
          | 
          | 
            prints a list of output files on stdout.
  | 
      
      
         | 27 | 
          | 
          | 
          
  | 
      
      
         | 28 | 
          | 
          | 
            Example:
  | 
      
      
         | 29 | 
          | 
          | 
          
  | 
      
      
         | 30 | 
          | 
          | 
            $ lto-wrapper gcc/xgcc -B gcc a.o b.o -o test -flto
  | 
      
      
         | 31 | 
          | 
          | 
          
  | 
      
      
         | 32 | 
          | 
          | 
            The above will print something like
  | 
      
      
         | 33 | 
          | 
          | 
            /tmp/ccwbQ8B2.lto.o
  | 
      
      
         | 34 | 
          | 
          | 
          
  | 
      
      
         | 35 | 
          | 
          | 
            If WHOPR is used instead, more than one file might be produced
  | 
      
      
         | 36 | 
          | 
          | 
            ./ccXj2DTk.lto.ltrans.o
  | 
      
      
         | 37 | 
          | 
          | 
            ./ccCJuXGv.lto.ltrans.o
  | 
      
      
         | 38 | 
          | 
          | 
         */
  | 
      
      
         | 39 | 
          | 
          | 
          
  | 
      
      
         | 40 | 
          | 
          | 
         #include "config.h"
  | 
      
      
         | 41 | 
          | 
          | 
         #include "system.h"
  | 
      
      
         | 42 | 
          | 
          | 
         #include "coretypes.h"
  | 
      
      
         | 43 | 
          | 
          | 
         #include "intl.h"
  | 
      
      
         | 44 | 
          | 
          | 
         #include "diagnostic.h"
  | 
      
      
         | 45 | 
          | 
          | 
         #include "obstack.h"
  | 
      
      
         | 46 | 
          | 
          | 
         #include "opts.h"
  | 
      
      
         | 47 | 
          | 
          | 
         #include "options.h"
  | 
      
      
         | 48 | 
          | 
          | 
         #include "simple-object.h"
  | 
      
      
         | 49 | 
          | 
          | 
          
  | 
      
      
         | 50 | 
          | 
          | 
         /* From lto-streamer.h which we cannot include with -fkeep-inline-functions.
  | 
      
      
         | 51 | 
          | 
          | 
            ???  Split out a lto-streamer-core.h.  */
  | 
      
      
         | 52 | 
          | 
          | 
          
  | 
      
      
         | 53 | 
          | 
          | 
         #define LTO_SECTION_NAME_PREFIX         ".gnu.lto_"
  | 
      
      
         | 54 | 
          | 
          | 
          
  | 
      
      
         | 55 | 
          | 
          | 
         /* End of lto-streamer.h copy.  */
  | 
      
      
         | 56 | 
          | 
          | 
          
  | 
      
      
         | 57 | 
          | 
          | 
         int debug;                              /* true if -save-temps.  */
  | 
      
      
         | 58 | 
          | 
          | 
         int verbose;                            /* true if -v.  */
  | 
      
      
         | 59 | 
          | 
          | 
          
  | 
      
      
         | 60 | 
          | 
          | 
         enum lto_mode_d {
  | 
      
      
         | 61 | 
          | 
          | 
           LTO_MODE_NONE,                        /* Not doing LTO.  */
  | 
      
      
         | 62 | 
          | 
          | 
           LTO_MODE_LTO,                         /* Normal LTO.  */
  | 
      
      
         | 63 | 
          | 
          | 
           LTO_MODE_WHOPR                        /* WHOPR.  */
  | 
      
      
         | 64 | 
          | 
          | 
         };
  | 
      
      
         | 65 | 
          | 
          | 
          
  | 
      
      
         | 66 | 
          | 
          | 
         /* Current LTO mode.  */
  | 
      
      
         | 67 | 
          | 
          | 
         static enum lto_mode_d lto_mode = LTO_MODE_NONE;
  | 
      
      
         | 68 | 
          | 
          | 
          
  | 
      
      
         | 69 | 
          | 
          | 
         static char *ltrans_output_file;
  | 
      
      
         | 70 | 
          | 
          | 
         static char *flto_out;
  | 
      
      
         | 71 | 
          | 
          | 
         static char *args_name;
  | 
      
      
         | 72 | 
          | 
          | 
         static unsigned int nr;
  | 
      
      
         | 73 | 
          | 
          | 
         static char **input_names;
  | 
      
      
         | 74 | 
          | 
          | 
         static char **output_names;
  | 
      
      
         | 75 | 
          | 
          | 
         static char *makefile;
  | 
      
      
         | 76 | 
          | 
          | 
          
  | 
      
      
         | 77 | 
          | 
          | 
         static void maybe_unlink_file (const char *);
  | 
      
      
         | 78 | 
          | 
          | 
          
  | 
      
      
         | 79 | 
          | 
          | 
          /* Delete tempfiles.  */
  | 
      
      
         | 80 | 
          | 
          | 
          
  | 
      
      
         | 81 | 
          | 
          | 
         static void
  | 
      
      
         | 82 | 
          | 
          | 
         lto_wrapper_cleanup (void)
  | 
      
      
         | 83 | 
          | 
          | 
         {
  | 
      
      
         | 84 | 
          | 
          | 
           static bool cleanup_done = false;
  | 
      
      
         | 85 | 
          | 
          | 
           unsigned int i;
  | 
      
      
         | 86 | 
          | 
          | 
          
  | 
      
      
         | 87 | 
          | 
          | 
           if (cleanup_done)
  | 
      
      
         | 88 | 
          | 
          | 
             return;
  | 
      
      
         | 89 | 
          | 
          | 
          
  | 
      
      
         | 90 | 
          | 
          | 
           /* Setting cleanup_done prevents an infinite loop if one of the
  | 
      
      
         | 91 | 
          | 
          | 
              calls to maybe_unlink_file fails. */
  | 
      
      
         | 92 | 
          | 
          | 
           cleanup_done = true;
  | 
      
      
         | 93 | 
          | 
          | 
          
  | 
      
      
         | 94 | 
          | 
          | 
           if (ltrans_output_file)
  | 
      
      
         | 95 | 
          | 
          | 
             maybe_unlink_file (ltrans_output_file);
  | 
      
      
         | 96 | 
          | 
          | 
           if (flto_out)
  | 
      
      
         | 97 | 
          | 
          | 
             maybe_unlink_file (flto_out);
  | 
      
      
         | 98 | 
          | 
          | 
           if (args_name)
  | 
      
      
         | 99 | 
          | 
          | 
             maybe_unlink_file (args_name);
  | 
      
      
         | 100 | 
          | 
          | 
           if (makefile)
  | 
      
      
         | 101 | 
          | 
          | 
             maybe_unlink_file (makefile);
  | 
      
      
         | 102 | 
          | 
          | 
           for (i = 0; i < nr; ++i)
  | 
      
      
         | 103 | 
          | 
          | 
             {
  | 
      
      
         | 104 | 
          | 
          | 
               maybe_unlink_file (input_names[i]);
  | 
      
      
         | 105 | 
          | 
          | 
               if (output_names[i])
  | 
      
      
         | 106 | 
          | 
          | 
                 maybe_unlink_file (output_names[i]);
  | 
      
      
         | 107 | 
          | 
          | 
             }
  | 
      
      
         | 108 | 
          | 
          | 
         }
  | 
      
      
         | 109 | 
          | 
          | 
          
  | 
      
      
         | 110 | 
          | 
          | 
         static void
  | 
      
      
         | 111 | 
          | 
          | 
         fatal_signal (int signum)
  | 
      
      
         | 112 | 
          | 
          | 
         {
  | 
      
      
         | 113 | 
          | 
          | 
           signal (signum, SIG_DFL);
  | 
      
      
         | 114 | 
          | 
          | 
           lto_wrapper_cleanup ();
  | 
      
      
         | 115 | 
          | 
          | 
           /* Get the same signal again, this time not handled,
  | 
      
      
         | 116 | 
          | 
          | 
              so its normal effect occurs.  */
  | 
      
      
         | 117 | 
          | 
          | 
           kill (getpid (), signum);
  | 
      
      
         | 118 | 
          | 
          | 
         }
  | 
      
      
         | 119 | 
          | 
          | 
          
  | 
      
      
         | 120 | 
          | 
          | 
         /* Just die. CMSGID is the error message. */
  | 
      
      
         | 121 | 
          | 
          | 
          
  | 
      
      
         | 122 | 
          | 
          | 
         static void __attribute__ ((format (printf, 1, 2)))
  | 
      
      
         | 123 | 
          | 
          | 
         fatal (const char * cmsgid, ...)
  | 
      
      
         | 124 | 
          | 
          | 
         {
  | 
      
      
         | 125 | 
          | 
          | 
           va_list ap;
  | 
      
      
         | 126 | 
          | 
          | 
          
  | 
      
      
         | 127 | 
          | 
          | 
           va_start (ap, cmsgid);
  | 
      
      
         | 128 | 
          | 
          | 
           fprintf (stderr, "lto-wrapper: ");
  | 
      
      
         | 129 | 
          | 
          | 
           vfprintf (stderr, _(cmsgid), ap);
  | 
      
      
         | 130 | 
          | 
          | 
           fprintf (stderr, "\n");
  | 
      
      
         | 131 | 
          | 
          | 
           va_end (ap);
  | 
      
      
         | 132 | 
          | 
          | 
          
  | 
      
      
         | 133 | 
          | 
          | 
           lto_wrapper_cleanup ();
  | 
      
      
         | 134 | 
          | 
          | 
           exit (FATAL_EXIT_CODE);
  | 
      
      
         | 135 | 
          | 
          | 
         }
  | 
      
      
         | 136 | 
          | 
          | 
          
  | 
      
      
         | 137 | 
          | 
          | 
          
  | 
      
      
         | 138 | 
          | 
          | 
         /* Die when sys call fails. CMSGID is the error message.  */
  | 
      
      
         | 139 | 
          | 
          | 
          
  | 
      
      
         | 140 | 
          | 
          | 
         static void __attribute__ ((format (printf, 1, 2)))
  | 
      
      
         | 141 | 
          | 
          | 
         fatal_perror (const char *cmsgid, ...)
  | 
      
      
         | 142 | 
          | 
          | 
         {
  | 
      
      
         | 143 | 
          | 
          | 
           int e = errno;
  | 
      
      
         | 144 | 
          | 
          | 
           va_list ap;
  | 
      
      
         | 145 | 
          | 
          | 
          
  | 
      
      
         | 146 | 
          | 
          | 
           va_start (ap, cmsgid);
  | 
      
      
         | 147 | 
          | 
          | 
           fprintf (stderr, "lto-wrapper: ");
  | 
      
      
         | 148 | 
          | 
          | 
           vfprintf (stderr, _(cmsgid), ap);
  | 
      
      
         | 149 | 
          | 
          | 
           fprintf (stderr, ": %s\n", xstrerror (e));
  | 
      
      
         | 150 | 
          | 
          | 
           va_end (ap);
  | 
      
      
         | 151 | 
          | 
          | 
          
  | 
      
      
         | 152 | 
          | 
          | 
           lto_wrapper_cleanup ();
  | 
      
      
         | 153 | 
          | 
          | 
           exit (FATAL_EXIT_CODE);
  | 
      
      
         | 154 | 
          | 
          | 
         }
  | 
      
      
         | 155 | 
          | 
          | 
          
  | 
      
      
         | 156 | 
          | 
          | 
          
  | 
      
      
         | 157 | 
          | 
          | 
         /* Execute a program, and wait for the reply. ARGV are the arguments. The
  | 
      
      
         | 158 | 
          | 
          | 
            last one must be NULL. */
  | 
      
      
         | 159 | 
          | 
          | 
          
  | 
      
      
         | 160 | 
          | 
          | 
         static struct pex_obj *
  | 
      
      
         | 161 | 
          | 
          | 
         collect_execute (char **argv)
  | 
      
      
         | 162 | 
          | 
          | 
         {
  | 
      
      
         | 163 | 
          | 
          | 
           struct pex_obj *pex;
  | 
      
      
         | 164 | 
          | 
          | 
           const char *errmsg;
  | 
      
      
         | 165 | 
          | 
          | 
           int err;
  | 
      
      
         | 166 | 
          | 
          | 
          
  | 
      
      
         | 167 | 
          | 
          | 
           if (verbose)
  | 
      
      
         | 168 | 
          | 
          | 
             {
  | 
      
      
         | 169 | 
          | 
          | 
               char **p_argv;
  | 
      
      
         | 170 | 
          | 
          | 
               const char *str;
  | 
      
      
         | 171 | 
          | 
          | 
          
  | 
      
      
         | 172 | 
          | 
          | 
               for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++)
  | 
      
      
         | 173 | 
          | 
          | 
                 fprintf (stderr, " %s", str);
  | 
      
      
         | 174 | 
          | 
          | 
          
  | 
      
      
         | 175 | 
          | 
          | 
               fprintf (stderr, "\n");
  | 
      
      
         | 176 | 
          | 
          | 
             }
  | 
      
      
         | 177 | 
          | 
          | 
          
  | 
      
      
         | 178 | 
          | 
          | 
           fflush (stdout);
  | 
      
      
         | 179 | 
          | 
          | 
           fflush (stderr);
  | 
      
      
         | 180 | 
          | 
          | 
          
  | 
      
      
         | 181 | 
          | 
          | 
           pex = pex_init (0, "lto-wrapper", NULL);
  | 
      
      
         | 182 | 
          | 
          | 
           if (pex == NULL)
  | 
      
      
         | 183 | 
          | 
          | 
             fatal_perror ("pex_init failed");
  | 
      
      
         | 184 | 
          | 
          | 
          
  | 
      
      
         | 185 | 
          | 
          | 
           /* Do not use PEX_LAST here, we use our stdout for communicating with
  | 
      
      
         | 186 | 
          | 
          | 
              collect2 or the linker-plugin.  Any output from the sub-process
  | 
      
      
         | 187 | 
          | 
          | 
              will confuse that.  */
  | 
      
      
         | 188 | 
          | 
          | 
           errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
  | 
      
      
         | 189 | 
          | 
          | 
                             NULL, &err);
  | 
      
      
         | 190 | 
          | 
          | 
           if (errmsg != NULL)
  | 
      
      
         | 191 | 
          | 
          | 
             {
  | 
      
      
         | 192 | 
          | 
          | 
               if (err != 0)
  | 
      
      
         | 193 | 
          | 
          | 
                 {
  | 
      
      
         | 194 | 
          | 
          | 
                   errno = err;
  | 
      
      
         | 195 | 
          | 
          | 
                   fatal_perror (errmsg);
  | 
      
      
         | 196 | 
          | 
          | 
                 }
  | 
      
      
         | 197 | 
          | 
          | 
               else
  | 
      
      
         | 198 | 
          | 
          | 
                 fatal (errmsg);
  | 
      
      
         | 199 | 
          | 
          | 
             }
  | 
      
      
         | 200 | 
          | 
          | 
          
  | 
      
      
         | 201 | 
          | 
          | 
           return pex;
  | 
      
      
         | 202 | 
          | 
          | 
         }
  | 
      
      
         | 203 | 
          | 
          | 
          
  | 
      
      
         | 204 | 
          | 
          | 
          
  | 
      
      
         | 205 | 
          | 
          | 
         /* Wait for a process to finish, and exit if a nonzero status is found.
  | 
      
      
         | 206 | 
          | 
          | 
            PROG is the program name. PEX is the process we should wait for. */
  | 
      
      
         | 207 | 
          | 
          | 
          
  | 
      
      
         | 208 | 
          | 
          | 
         static int
  | 
      
      
         | 209 | 
          | 
          | 
         collect_wait (const char *prog, struct pex_obj *pex)
  | 
      
      
         | 210 | 
          | 
          | 
         {
  | 
      
      
         | 211 | 
          | 
          | 
           int status;
  | 
      
      
         | 212 | 
          | 
          | 
          
  | 
      
      
         | 213 | 
          | 
          | 
           if (!pex_get_status (pex, 1, &status))
  | 
      
      
         | 214 | 
          | 
          | 
             fatal_perror ("can't get program status");
  | 
      
      
         | 215 | 
          | 
          | 
           pex_free (pex);
  | 
      
      
         | 216 | 
          | 
          | 
          
  | 
      
      
         | 217 | 
          | 
          | 
           if (status)
  | 
      
      
         | 218 | 
          | 
          | 
             {
  | 
      
      
         | 219 | 
          | 
          | 
               if (WIFSIGNALED (status))
  | 
      
      
         | 220 | 
          | 
          | 
                 {
  | 
      
      
         | 221 | 
          | 
          | 
                   int sig = WTERMSIG (status);
  | 
      
      
         | 222 | 
          | 
          | 
                   if (WCOREDUMP (status))
  | 
      
      
         | 223 | 
          | 
          | 
                     fatal ("%s terminated with signal %d [%s], core dumped",
  | 
      
      
         | 224 | 
          | 
          | 
                            prog, sig, strsignal (sig));
  | 
      
      
         | 225 | 
          | 
          | 
                   else
  | 
      
      
         | 226 | 
          | 
          | 
                     fatal ("%s terminated with signal %d [%s]",
  | 
      
      
         | 227 | 
          | 
          | 
                            prog, sig, strsignal (sig));
  | 
      
      
         | 228 | 
          | 
          | 
                 }
  | 
      
      
         | 229 | 
          | 
          | 
          
  | 
      
      
         | 230 | 
          | 
          | 
               if (WIFEXITED (status))
  | 
      
      
         | 231 | 
          | 
          | 
                 fatal ("%s returned %d exit status", prog, WEXITSTATUS (status));
  | 
      
      
         | 232 | 
          | 
          | 
             }
  | 
      
      
         | 233 | 
          | 
          | 
          
  | 
      
      
         | 234 | 
          | 
          | 
           return 0;
  | 
      
      
         | 235 | 
          | 
          | 
         }
  | 
      
      
         | 236 | 
          | 
          | 
          
  | 
      
      
         | 237 | 
          | 
          | 
          
  | 
      
      
         | 238 | 
          | 
          | 
         /* Unlink a temporary LTRANS file unless requested otherwise.  */
  | 
      
      
         | 239 | 
          | 
          | 
          
  | 
      
      
         | 240 | 
          | 
          | 
         static void
  | 
      
      
         | 241 | 
          | 
          | 
         maybe_unlink_file (const char *file)
  | 
      
      
         | 242 | 
          | 
          | 
         {
  | 
      
      
         | 243 | 
          | 
          | 
           if (! debug)
  | 
      
      
         | 244 | 
          | 
          | 
             {
  | 
      
      
         | 245 | 
          | 
          | 
               if (unlink_if_ordinary (file)
  | 
      
      
         | 246 | 
          | 
          | 
                   && errno != ENOENT)
  | 
      
      
         | 247 | 
          | 
          | 
                 fatal_perror ("deleting LTRANS file %s", file);
  | 
      
      
         | 248 | 
          | 
          | 
             }
  | 
      
      
         | 249 | 
          | 
          | 
           else
  | 
      
      
         | 250 | 
          | 
          | 
             fprintf (stderr, "[Leaving LTRANS %s]\n", file);
  | 
      
      
         | 251 | 
          | 
          | 
         }
  | 
      
      
         | 252 | 
          | 
          | 
          
  | 
      
      
         | 253 | 
          | 
          | 
          
  | 
      
      
         | 254 | 
          | 
          | 
         /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish.  */
  | 
      
      
         | 255 | 
          | 
          | 
          
  | 
      
      
         | 256 | 
          | 
          | 
         static void
  | 
      
      
         | 257 | 
          | 
          | 
         fork_execute (char **argv)
  | 
      
      
         | 258 | 
          | 
          | 
         {
  | 
      
      
         | 259 | 
          | 
          | 
           struct pex_obj *pex;
  | 
      
      
         | 260 | 
          | 
          | 
           char *new_argv[3];
  | 
      
      
         | 261 | 
          | 
          | 
           char *at_args;
  | 
      
      
         | 262 | 
          | 
          | 
           FILE *args;
  | 
      
      
         | 263 | 
          | 
          | 
           int status;
  | 
      
      
         | 264 | 
          | 
          | 
          
  | 
      
      
         | 265 | 
          | 
          | 
           args_name = make_temp_file (".args");
  | 
      
      
         | 266 | 
          | 
          | 
           at_args = concat ("@", args_name, NULL);
  | 
      
      
         | 267 | 
          | 
          | 
           args = fopen (args_name, "w");
  | 
      
      
         | 268 | 
          | 
          | 
           if (args == NULL)
  | 
      
      
         | 269 | 
          | 
          | 
             fatal ("failed to open %s", args_name);
  | 
      
      
         | 270 | 
          | 
          | 
          
  | 
      
      
         | 271 | 
          | 
          | 
           status = writeargv (&argv[1], args);
  | 
      
      
         | 272 | 
          | 
          | 
          
  | 
      
      
         | 273 | 
          | 
          | 
           if (status)
  | 
      
      
         | 274 | 
          | 
          | 
             fatal ("could not write to temporary file %s",  args_name);
  | 
      
      
         | 275 | 
          | 
          | 
          
  | 
      
      
         | 276 | 
          | 
          | 
           fclose (args);
  | 
      
      
         | 277 | 
          | 
          | 
          
  | 
      
      
         | 278 | 
          | 
          | 
           new_argv[0] = argv[0];
  | 
      
      
         | 279 | 
          | 
          | 
           new_argv[1] = at_args;
  | 
      
      
         | 280 | 
          | 
          | 
           new_argv[2] = NULL;
  | 
      
      
         | 281 | 
          | 
          | 
          
  | 
      
      
         | 282 | 
          | 
          | 
           pex = collect_execute (new_argv);
  | 
      
      
         | 283 | 
          | 
          | 
           collect_wait (new_argv[0], pex);
  | 
      
      
         | 284 | 
          | 
          | 
          
  | 
      
      
         | 285 | 
          | 
          | 
           maybe_unlink_file (args_name);
  | 
      
      
         | 286 | 
          | 
          | 
           args_name = NULL;
  | 
      
      
         | 287 | 
          | 
          | 
           free (at_args);
  | 
      
      
         | 288 | 
          | 
          | 
         }
  | 
      
      
         | 289 | 
          | 
          | 
          
  | 
      
      
         | 290 | 
          | 
          | 
         /* Template of LTRANS dumpbase suffix.  */
  | 
      
      
         | 291 | 
          | 
          | 
         #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
  | 
      
      
         | 292 | 
          | 
          | 
          
  | 
      
      
         | 293 | 
          | 
          | 
         /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
  | 
      
      
         | 294 | 
          | 
          | 
            environment according to LANG_MASK.  */
  | 
      
      
         | 295 | 
          | 
          | 
          
  | 
      
      
         | 296 | 
          | 
          | 
         static void
  | 
      
      
         | 297 | 
          | 
          | 
         get_options_from_collect_gcc_options (const char *collect_gcc,
  | 
      
      
         | 298 | 
          | 
          | 
                                               const char *collect_gcc_options,
  | 
      
      
         | 299 | 
          | 
          | 
                                               unsigned int lang_mask,
  | 
      
      
         | 300 | 
          | 
          | 
                                               struct cl_decoded_option **decoded_options,
  | 
      
      
         | 301 | 
          | 
          | 
                                               unsigned int *decoded_options_count)
  | 
      
      
         | 302 | 
          | 
          | 
         {
  | 
      
      
         | 303 | 
          | 
          | 
           struct obstack argv_obstack;
  | 
      
      
         | 304 | 
          | 
          | 
           char *argv_storage;
  | 
      
      
         | 305 | 
          | 
          | 
           const char **argv;
  | 
      
      
         | 306 | 
          | 
          | 
           int j, k, argc;
  | 
      
      
         | 307 | 
          | 
          | 
          
  | 
      
      
         | 308 | 
          | 
          | 
           argv_storage = xstrdup (collect_gcc_options);
  | 
      
      
         | 309 | 
          | 
          | 
           obstack_init (&argv_obstack);
  | 
      
      
         | 310 | 
          | 
          | 
           obstack_ptr_grow (&argv_obstack, collect_gcc);
  | 
      
      
         | 311 | 
          | 
          | 
          
  | 
      
      
         | 312 | 
          | 
          | 
           for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
  | 
      
      
         | 313 | 
          | 
          | 
             {
  | 
      
      
         | 314 | 
          | 
          | 
               if (argv_storage[j] == '\'')
  | 
      
      
         | 315 | 
          | 
          | 
                 {
  | 
      
      
         | 316 | 
          | 
          | 
                   obstack_ptr_grow (&argv_obstack, &argv_storage[k]);
  | 
      
      
         | 317 | 
          | 
          | 
                   ++j;
  | 
      
      
         | 318 | 
          | 
          | 
                   do
  | 
      
      
         | 319 | 
          | 
          | 
                     {
  | 
      
      
         | 320 | 
          | 
          | 
                       if (argv_storage[j] == '\0')
  | 
      
      
         | 321 | 
          | 
          | 
                         fatal ("malformed COLLECT_GCC_OPTIONS");
  | 
      
      
         | 322 | 
          | 
          | 
                       else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
  | 
      
      
         | 323 | 
          | 
          | 
                         {
  | 
      
      
         | 324 | 
          | 
          | 
                           argv_storage[k++] = '\'';
  | 
      
      
         | 325 | 
          | 
          | 
                           j += 4;
  | 
      
      
         | 326 | 
          | 
          | 
                         }
  | 
      
      
         | 327 | 
          | 
          | 
                       else if (argv_storage[j] == '\'')
  | 
      
      
         | 328 | 
          | 
          | 
                         break;
  | 
      
      
         | 329 | 
          | 
          | 
                       else
  | 
      
      
         | 330 | 
          | 
          | 
                         argv_storage[k++] = argv_storage[j++];
  | 
      
      
         | 331 | 
          | 
          | 
                     }
  | 
      
      
         | 332 | 
          | 
          | 
                   while (1);
  | 
      
      
         | 333 | 
          | 
          | 
                   argv_storage[k++] = '\0';
  | 
      
      
         | 334 | 
          | 
          | 
                 }
  | 
      
      
         | 335 | 
          | 
          | 
             }
  | 
      
      
         | 336 | 
          | 
          | 
          
  | 
      
      
         | 337 | 
          | 
          | 
           obstack_ptr_grow (&argv_obstack, NULL);
  | 
      
      
         | 338 | 
          | 
          | 
           argc = obstack_object_size (&argv_obstack) / sizeof (void *) - 1;
  | 
      
      
         | 339 | 
          | 
          | 
           argv = XOBFINISH (&argv_obstack, const char **);
  | 
      
      
         | 340 | 
          | 
          | 
          
  | 
      
      
         | 341 | 
          | 
          | 
           decode_cmdline_options_to_array (argc, (const char **)argv,
  | 
      
      
         | 342 | 
          | 
          | 
                                            lang_mask,
  | 
      
      
         | 343 | 
          | 
          | 
                                            decoded_options, decoded_options_count);
  | 
      
      
         | 344 | 
          | 
          | 
           obstack_free (&argv_obstack, NULL);
  | 
      
      
         | 345 | 
          | 
          | 
         }
  | 
      
      
         | 346 | 
          | 
          | 
          
  | 
      
      
         | 347 | 
          | 
          | 
         /* Append OPTION to the options array DECODED_OPTIONS with size
  | 
      
      
         | 348 | 
          | 
          | 
            DECODED_OPTIONS_COUNT.  */
  | 
      
      
         | 349 | 
          | 
          | 
          
  | 
      
      
         | 350 | 
          | 
          | 
         static void
  | 
      
      
         | 351 | 
          | 
          | 
         append_option (struct cl_decoded_option **decoded_options,
  | 
      
      
         | 352 | 
          | 
          | 
                        unsigned int *decoded_options_count,
  | 
      
      
         | 353 | 
          | 
          | 
                        struct cl_decoded_option *option)
  | 
      
      
         | 354 | 
          | 
          | 
         {
  | 
      
      
         | 355 | 
          | 
          | 
           ++*decoded_options_count;
  | 
      
      
         | 356 | 
          | 
          | 
           *decoded_options
  | 
      
      
         | 357 | 
          | 
          | 
             = (struct cl_decoded_option *)
  | 
      
      
         | 358 | 
          | 
          | 
                 xrealloc (*decoded_options,
  | 
      
      
         | 359 | 
          | 
          | 
                           (*decoded_options_count
  | 
      
      
         | 360 | 
          | 
          | 
                            * sizeof (struct cl_decoded_option)));
  | 
      
      
         | 361 | 
          | 
          | 
           memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
  | 
      
      
         | 362 | 
          | 
          | 
                   sizeof (struct cl_decoded_option));
  | 
      
      
         | 363 | 
          | 
          | 
         }
  | 
      
      
         | 364 | 
          | 
          | 
          
  | 
      
      
         | 365 | 
          | 
          | 
         /* Try to merge and complain about options FDECODED_OPTIONS when applied
  | 
      
      
         | 366 | 
          | 
          | 
            ontop of DECODED_OPTIONS.  */
  | 
      
      
         | 367 | 
          | 
          | 
          
  | 
      
      
         | 368 | 
          | 
          | 
         static void
  | 
      
      
         | 369 | 
          | 
          | 
         merge_and_complain (struct cl_decoded_option **decoded_options,
  | 
      
      
         | 370 | 
          | 
          | 
                             unsigned int *decoded_options_count,
  | 
      
      
         | 371 | 
          | 
          | 
                             struct cl_decoded_option *fdecoded_options,
  | 
      
      
         | 372 | 
          | 
          | 
                             unsigned int fdecoded_options_count)
  | 
      
      
         | 373 | 
          | 
          | 
         {
  | 
      
      
         | 374 | 
          | 
          | 
           unsigned int i, j;
  | 
      
      
         | 375 | 
          | 
          | 
          
  | 
      
      
         | 376 | 
          | 
          | 
           /* ???  Merge options from files.  Most cases can be
  | 
      
      
         | 377 | 
          | 
          | 
              handled by either unioning or intersecting
  | 
      
      
         | 378 | 
          | 
          | 
              (for example -fwrapv is a case for unioning,
  | 
      
      
         | 379 | 
          | 
          | 
              -ffast-math is for intersection).  Most complaints
  | 
      
      
         | 380 | 
          | 
          | 
              about real conflicts between different options can
  | 
      
      
         | 381 | 
          | 
          | 
              be deferred to the compiler proper.  Options that
  | 
      
      
         | 382 | 
          | 
          | 
              we can neither safely handle by intersection nor
  | 
      
      
         | 383 | 
          | 
          | 
              unioning would need to be complained about here.
  | 
      
      
         | 384 | 
          | 
          | 
              Ideally we'd have a flag in the opt files that
  | 
      
      
         | 385 | 
          | 
          | 
              tells whether to union or intersect or reject.
  | 
      
      
         | 386 | 
          | 
          | 
              In absence of that it's unclear what a good default is.
  | 
      
      
         | 387 | 
          | 
          | 
              It's also difficult to get positional handling correct.  */
  | 
      
      
         | 388 | 
          | 
          | 
          
  | 
      
      
         | 389 | 
          | 
          | 
           /* The following does what the old LTO option code did,
  | 
      
      
         | 390 | 
          | 
          | 
              union all target and a selected set of common options.  */
  | 
      
      
         | 391 | 
          | 
          | 
           for (i = 0; i < fdecoded_options_count; ++i)
  | 
      
      
         | 392 | 
          | 
          | 
             {
  | 
      
      
         | 393 | 
          | 
          | 
               struct cl_decoded_option *foption = &fdecoded_options[i];
  | 
      
      
         | 394 | 
          | 
          | 
               switch (foption->opt_index)
  | 
      
      
         | 395 | 
          | 
          | 
                 {
  | 
      
      
         | 396 | 
          | 
          | 
                 default:
  | 
      
      
         | 397 | 
          | 
          | 
                   if (!(cl_options[foption->opt_index].flags & CL_TARGET))
  | 
      
      
         | 398 | 
          | 
          | 
                     break;
  | 
      
      
         | 399 | 
          | 
          | 
          
  | 
      
      
         | 400 | 
          | 
          | 
                   /* Fallthru.  */
  | 
      
      
         | 401 | 
          | 
          | 
                 case OPT_fPIC:
  | 
      
      
         | 402 | 
          | 
          | 
                 case OPT_fpic:
  | 
      
      
         | 403 | 
          | 
          | 
                 case OPT_fpie:
  | 
      
      
         | 404 | 
          | 
          | 
                 case OPT_fcommon:
  | 
      
      
         | 405 | 
          | 
          | 
                 case OPT_fexceptions:
  | 
      
      
         | 406 | 
          | 
          | 
                 case OPT_fgnu_tm:
  | 
      
      
         | 407 | 
          | 
          | 
                   /* Do what the old LTO code did - collect exactly one option
  | 
      
      
         | 408 | 
          | 
          | 
                      setting per OPT code, we pick the first we encounter.
  | 
      
      
         | 409 | 
          | 
          | 
                      ???  This doesn't make too much sense, but when it doesn't
  | 
      
      
         | 410 | 
          | 
          | 
                      then we should complain.  */
  | 
      
      
         | 411 | 
          | 
          | 
                   for (j = 0; j < *decoded_options_count; ++j)
  | 
      
      
         | 412 | 
          | 
          | 
                     if ((*decoded_options)[j].opt_index == foption->opt_index)
  | 
      
      
         | 413 | 
          | 
          | 
                       break;
  | 
      
      
         | 414 | 
          | 
          | 
                   if (j == *decoded_options_count)
  | 
      
      
         | 415 | 
          | 
          | 
                     append_option (decoded_options, decoded_options_count, foption);
  | 
      
      
         | 416 | 
          | 
          | 
                   break;
  | 
      
      
         | 417 | 
          | 
          | 
                 }
  | 
      
      
         | 418 | 
          | 
          | 
             }
  | 
      
      
         | 419 | 
          | 
          | 
         }
  | 
      
      
         | 420 | 
          | 
          | 
          
  | 
      
      
         | 421 | 
          | 
          | 
         /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
  | 
      
      
         | 422 | 
          | 
          | 
          
  | 
      
      
         | 423 | 
          | 
          | 
         static void
  | 
      
      
         | 424 | 
          | 
          | 
         run_gcc (unsigned argc, char *argv[])
  | 
      
      
         | 425 | 
          | 
          | 
         {
  | 
      
      
         | 426 | 
          | 
          | 
           unsigned i, j;
  | 
      
      
         | 427 | 
          | 
          | 
           const char **new_argv;
  | 
      
      
         | 428 | 
          | 
          | 
           const char **argv_ptr;
  | 
      
      
         | 429 | 
          | 
          | 
           char *list_option_full = NULL;
  | 
      
      
         | 430 | 
          | 
          | 
           const char *linker_output = NULL;
  | 
      
      
         | 431 | 
          | 
          | 
           const char *collect_gcc, *collect_gcc_options;
  | 
      
      
         | 432 | 
          | 
          | 
           int parallel = 0;
  | 
      
      
         | 433 | 
          | 
          | 
           int jobserver = 0;
  | 
      
      
         | 434 | 
          | 
          | 
           bool no_partition = false;
  | 
      
      
         | 435 | 
          | 
          | 
           struct cl_decoded_option *fdecoded_options = NULL;
  | 
      
      
         | 436 | 
          | 
          | 
           unsigned int fdecoded_options_count = 0;
  | 
      
      
         | 437 | 
          | 
          | 
           struct cl_decoded_option *decoded_options;
  | 
      
      
         | 438 | 
          | 
          | 
           unsigned int decoded_options_count;
  | 
      
      
         | 439 | 
          | 
          | 
           struct obstack argv_obstack;
  | 
      
      
         | 440 | 
          | 
          | 
           int new_head_argc;
  | 
      
      
         | 441 | 
          | 
          | 
          
  | 
      
      
         | 442 | 
          | 
          | 
           /* Get the driver and options.  */
  | 
      
      
         | 443 | 
          | 
          | 
           collect_gcc = getenv ("COLLECT_GCC");
  | 
      
      
         | 444 | 
          | 
          | 
           if (!collect_gcc)
  | 
      
      
         | 445 | 
          | 
          | 
             fatal ("environment variable COLLECT_GCC must be set");
  | 
      
      
         | 446 | 
          | 
          | 
           collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
  | 
      
      
         | 447 | 
          | 
          | 
           if (!collect_gcc_options)
  | 
      
      
         | 448 | 
          | 
          | 
             fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
  | 
      
      
         | 449 | 
          | 
          | 
           get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
  | 
      
      
         | 450 | 
          | 
          | 
                                                 CL_LANG_ALL,
  | 
      
      
         | 451 | 
          | 
          | 
                                                 &decoded_options,
  | 
      
      
         | 452 | 
          | 
          | 
                                                 &decoded_options_count);
  | 
      
      
         | 453 | 
          | 
          | 
          
  | 
      
      
         | 454 | 
          | 
          | 
           /* Look at saved options in the IL files.  */
  | 
      
      
         | 455 | 
          | 
          | 
           for (i = 1; i < argc; ++i)
  | 
      
      
         | 456 | 
          | 
          | 
             {
  | 
      
      
         | 457 | 
          | 
          | 
               char *data, *p;
  | 
      
      
         | 458 | 
          | 
          | 
               char *fopts;
  | 
      
      
         | 459 | 
          | 
          | 
               int fd;
  | 
      
      
         | 460 | 
          | 
          | 
               const char *errmsg;
  | 
      
      
         | 461 | 
          | 
          | 
               int err;
  | 
      
      
         | 462 | 
          | 
          | 
               off_t file_offset = 0, offset, length;
  | 
      
      
         | 463 | 
          | 
          | 
               long loffset;
  | 
      
      
         | 464 | 
          | 
          | 
               simple_object_read *sobj;
  | 
      
      
         | 465 | 
          | 
          | 
               int consumed;
  | 
      
      
         | 466 | 
          | 
          | 
               struct cl_decoded_option *f2decoded_options;
  | 
      
      
         | 467 | 
          | 
          | 
               unsigned int f2decoded_options_count;
  | 
      
      
         | 468 | 
          | 
          | 
               char *filename = argv[i];
  | 
      
      
         | 469 | 
          | 
          | 
               if ((p = strrchr (argv[i], '@'))
  | 
      
      
         | 470 | 
          | 
          | 
                   && p != argv[i]
  | 
      
      
         | 471 | 
          | 
          | 
                   && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
  | 
      
      
         | 472 | 
          | 
          | 
                   && strlen (p) == (unsigned int) consumed)
  | 
      
      
         | 473 | 
          | 
          | 
                 {
  | 
      
      
         | 474 | 
          | 
          | 
                   filename = XNEWVEC (char, p - argv[i] + 1);
  | 
      
      
         | 475 | 
          | 
          | 
                   memcpy (filename, argv[i], p - argv[i]);
  | 
      
      
         | 476 | 
          | 
          | 
                   filename[p - argv[i]] = '\0';
  | 
      
      
         | 477 | 
          | 
          | 
                   file_offset = (off_t) loffset;
  | 
      
      
         | 478 | 
          | 
          | 
                 }
  | 
      
      
         | 479 | 
          | 
          | 
               fd = open (argv[i], O_RDONLY);
  | 
      
      
         | 480 | 
          | 
          | 
               if (fd == -1)
  | 
      
      
         | 481 | 
          | 
          | 
                 continue;
  | 
      
      
         | 482 | 
          | 
          | 
               sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
  | 
      
      
         | 483 | 
          | 
          | 
                                                &errmsg, &err);
  | 
      
      
         | 484 | 
          | 
          | 
               if (!sobj)
  | 
      
      
         | 485 | 
          | 
          | 
                 {
  | 
      
      
         | 486 | 
          | 
          | 
                   close (fd);
  | 
      
      
         | 487 | 
          | 
          | 
                   continue;
  | 
      
      
         | 488 | 
          | 
          | 
                 }
  | 
      
      
         | 489 | 
          | 
          | 
               if (!simple_object_find_section (sobj, LTO_SECTION_NAME_PREFIX "." "opts",
  | 
      
      
         | 490 | 
          | 
          | 
                                                &offset, &length, &errmsg, &err))
  | 
      
      
         | 491 | 
          | 
          | 
                 {
  | 
      
      
         | 492 | 
          | 
          | 
                   simple_object_release_read (sobj);
  | 
      
      
         | 493 | 
          | 
          | 
                   close (fd);
  | 
      
      
         | 494 | 
          | 
          | 
                   continue;
  | 
      
      
         | 495 | 
          | 
          | 
                 }
  | 
      
      
         | 496 | 
          | 
          | 
               lseek (fd, file_offset + offset, SEEK_SET);
  | 
      
      
         | 497 | 
          | 
          | 
               data = (char *)xmalloc (length);
  | 
      
      
         | 498 | 
          | 
          | 
               read (fd, data, length);
  | 
      
      
         | 499 | 
          | 
          | 
               fopts = data;
  | 
      
      
         | 500 | 
          | 
          | 
               do
  | 
      
      
         | 501 | 
          | 
          | 
                 {
  | 
      
      
         | 502 | 
          | 
          | 
                   get_options_from_collect_gcc_options (collect_gcc,
  | 
      
      
         | 503 | 
          | 
          | 
                                                         fopts, CL_LANG_ALL,
  | 
      
      
         | 504 | 
          | 
          | 
                                                         &f2decoded_options,
  | 
      
      
         | 505 | 
          | 
          | 
                                                         &f2decoded_options_count);
  | 
      
      
         | 506 | 
          | 
          | 
                   if (!fdecoded_options)
  | 
      
      
         | 507 | 
          | 
          | 
                     {
  | 
      
      
         | 508 | 
          | 
          | 
                       fdecoded_options = f2decoded_options;
  | 
      
      
         | 509 | 
          | 
          | 
                       fdecoded_options_count = f2decoded_options_count;
  | 
      
      
         | 510 | 
          | 
          | 
                     }
  | 
      
      
         | 511 | 
          | 
          | 
                   else
  | 
      
      
         | 512 | 
          | 
          | 
                     merge_and_complain (&fdecoded_options,
  | 
      
      
         | 513 | 
          | 
          | 
                                         &fdecoded_options_count,
  | 
      
      
         | 514 | 
          | 
          | 
                                         f2decoded_options, f2decoded_options_count);
  | 
      
      
         | 515 | 
          | 
          | 
          
  | 
      
      
         | 516 | 
          | 
          | 
                   fopts += strlen (fopts) + 1;
  | 
      
      
         | 517 | 
          | 
          | 
                 }
  | 
      
      
         | 518 | 
          | 
          | 
               while (fopts - data < length);
  | 
      
      
         | 519 | 
          | 
          | 
          
  | 
      
      
         | 520 | 
          | 
          | 
               free (data);
  | 
      
      
         | 521 | 
          | 
          | 
               simple_object_release_read (sobj);
  | 
      
      
         | 522 | 
          | 
          | 
               close (fd);
  | 
      
      
         | 523 | 
          | 
          | 
             }
  | 
      
      
         | 524 | 
          | 
          | 
          
  | 
      
      
         | 525 | 
          | 
          | 
           /* Initalize the common arguments for the driver.  */
  | 
      
      
         | 526 | 
          | 
          | 
           obstack_init (&argv_obstack);
  | 
      
      
         | 527 | 
          | 
          | 
           obstack_ptr_grow (&argv_obstack, collect_gcc);
  | 
      
      
         | 528 | 
          | 
          | 
           obstack_ptr_grow (&argv_obstack, "-xlto");
  | 
      
      
         | 529 | 
          | 
          | 
           obstack_ptr_grow (&argv_obstack, "-c");
  | 
      
      
         | 530 | 
          | 
          | 
          
  | 
      
      
         | 531 | 
          | 
          | 
           /* Append compiler driver arguments as far as they were merged.  */
  | 
      
      
         | 532 | 
          | 
          | 
           for (j = 1; j < fdecoded_options_count; ++j)
  | 
      
      
         | 533 | 
          | 
          | 
             {
  | 
      
      
         | 534 | 
          | 
          | 
               struct cl_decoded_option *option = &fdecoded_options[j];
  | 
      
      
         | 535 | 
          | 
          | 
          
  | 
      
      
         | 536 | 
          | 
          | 
               /* File options have been properly filtered by lto-opts.c.  */
  | 
      
      
         | 537 | 
          | 
          | 
               switch (option->opt_index)
  | 
      
      
         | 538 | 
          | 
          | 
                 {
  | 
      
      
         | 539 | 
          | 
          | 
                   /* Drop arguments that we want to take from the link line.  */
  | 
      
      
         | 540 | 
          | 
          | 
                   case OPT_flto_:
  | 
      
      
         | 541 | 
          | 
          | 
                   case OPT_flto:
  | 
      
      
         | 542 | 
          | 
          | 
                   case OPT_flto_partition_none:
  | 
      
      
         | 543 | 
          | 
          | 
                   case OPT_flto_partition_1to1:
  | 
      
      
         | 544 | 
          | 
          | 
                   case OPT_flto_partition_balanced:
  | 
      
      
         | 545 | 
          | 
          | 
                       continue;
  | 
      
      
         | 546 | 
          | 
          | 
          
  | 
      
      
         | 547 | 
          | 
          | 
                   default:
  | 
      
      
         | 548 | 
          | 
          | 
                       break;
  | 
      
      
         | 549 | 
          | 
          | 
                 }
  | 
      
      
         | 550 | 
          | 
          | 
          
  | 
      
      
         | 551 | 
          | 
          | 
               /* For now do what the original LTO option code was doing - pass
  | 
      
      
         | 552 | 
          | 
          | 
                  on any CL_TARGET flag and a few selected others.  */
  | 
      
      
         | 553 | 
          | 
          | 
               switch (option->opt_index)
  | 
      
      
         | 554 | 
          | 
          | 
                 {
  | 
      
      
         | 555 | 
          | 
          | 
                 case OPT_fPIC:
  | 
      
      
         | 556 | 
          | 
          | 
                 case OPT_fpic:
  | 
      
      
         | 557 | 
          | 
          | 
                 case OPT_fpie:
  | 
      
      
         | 558 | 
          | 
          | 
                 case OPT_fcommon:
  | 
      
      
         | 559 | 
          | 
          | 
                 case OPT_fexceptions:
  | 
      
      
         | 560 | 
          | 
          | 
                 case OPT_fgnu_tm:
  | 
      
      
         | 561 | 
          | 
          | 
                   break;
  | 
      
      
         | 562 | 
          | 
          | 
          
  | 
      
      
         | 563 | 
          | 
          | 
                 default:
  | 
      
      
         | 564 | 
          | 
          | 
                   if (!(cl_options[option->opt_index].flags & CL_TARGET))
  | 
      
      
         | 565 | 
          | 
          | 
                     continue;
  | 
      
      
         | 566 | 
          | 
          | 
                 }
  | 
      
      
         | 567 | 
          | 
          | 
          
  | 
      
      
         | 568 | 
          | 
          | 
               /* Pass the option on.  */
  | 
      
      
         | 569 | 
          | 
          | 
               for (i = 0; i < option->canonical_option_num_elements; ++i)
  | 
      
      
         | 570 | 
          | 
          | 
                 obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
  | 
      
      
         | 571 | 
          | 
          | 
             }
  | 
      
      
         | 572 | 
          | 
          | 
          
  | 
      
      
         | 573 | 
          | 
          | 
           /* Append linker driver arguments.  Compiler options from the linker
  | 
      
      
         | 574 | 
          | 
          | 
              driver arguments will override / merge with those from the compiler.  */
  | 
      
      
         | 575 | 
          | 
          | 
           for (j = 1; j < decoded_options_count; ++j)
  | 
      
      
         | 576 | 
          | 
          | 
             {
  | 
      
      
         | 577 | 
          | 
          | 
               struct cl_decoded_option *option = &decoded_options[j];
  | 
      
      
         | 578 | 
          | 
          | 
          
  | 
      
      
         | 579 | 
          | 
          | 
               /* Do not pass on frontend specific flags not suitable for lto.  */
  | 
      
      
         | 580 | 
          | 
          | 
               if (!(cl_options[option->opt_index].flags
  | 
      
      
         | 581 | 
          | 
          | 
                     & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
  | 
      
      
         | 582 | 
          | 
          | 
                 continue;
  | 
      
      
         | 583 | 
          | 
          | 
          
  | 
      
      
         | 584 | 
          | 
          | 
               switch (option->opt_index)
  | 
      
      
         | 585 | 
          | 
          | 
                 {
  | 
      
      
         | 586 | 
          | 
          | 
                 case OPT_o:
  | 
      
      
         | 587 | 
          | 
          | 
                   linker_output = option->arg;
  | 
      
      
         | 588 | 
          | 
          | 
                   /* We generate new intermediate output, drop this arg.  */
  | 
      
      
         | 589 | 
          | 
          | 
                   continue;
  | 
      
      
         | 590 | 
          | 
          | 
          
  | 
      
      
         | 591 | 
          | 
          | 
                 case OPT_save_temps:
  | 
      
      
         | 592 | 
          | 
          | 
                   debug = 1;
  | 
      
      
         | 593 | 
          | 
          | 
                   break;
  | 
      
      
         | 594 | 
          | 
          | 
          
  | 
      
      
         | 595 | 
          | 
          | 
                 case OPT_v:
  | 
      
      
         | 596 | 
          | 
          | 
                   verbose = 1;
  | 
      
      
         | 597 | 
          | 
          | 
                   break;
  | 
      
      
         | 598 | 
          | 
          | 
          
  | 
      
      
         | 599 | 
          | 
          | 
                 case OPT_flto_partition_none:
  | 
      
      
         | 600 | 
          | 
          | 
                   no_partition = true;
  | 
      
      
         | 601 | 
          | 
          | 
                   break;
  | 
      
      
         | 602 | 
          | 
          | 
          
  | 
      
      
         | 603 | 
          | 
          | 
                 case OPT_flto_:
  | 
      
      
         | 604 | 
          | 
          | 
                   if (strcmp (option->arg, "jobserver") == 0)
  | 
      
      
         | 605 | 
          | 
          | 
                     {
  | 
      
      
         | 606 | 
          | 
          | 
                       jobserver = 1;
  | 
      
      
         | 607 | 
          | 
          | 
                       parallel = 1;
  | 
      
      
         | 608 | 
          | 
          | 
                     }
  | 
      
      
         | 609 | 
          | 
          | 
                   else
  | 
      
      
         | 610 | 
          | 
          | 
                     {
  | 
      
      
         | 611 | 
          | 
          | 
                       parallel = atoi (option->arg);
  | 
      
      
         | 612 | 
          | 
          | 
                       if (parallel <= 1)
  | 
      
      
         | 613 | 
          | 
          | 
                         parallel = 0;
  | 
      
      
         | 614 | 
          | 
          | 
                     }
  | 
      
      
         | 615 | 
          | 
          | 
                   /* Fallthru.  */
  | 
      
      
         | 616 | 
          | 
          | 
          
  | 
      
      
         | 617 | 
          | 
          | 
                 case OPT_flto:
  | 
      
      
         | 618 | 
          | 
          | 
                   lto_mode = LTO_MODE_WHOPR;
  | 
      
      
         | 619 | 
          | 
          | 
                   /* We've handled these LTO options, do not pass them on.  */
  | 
      
      
         | 620 | 
          | 
          | 
                   continue;
  | 
      
      
         | 621 | 
          | 
          | 
          
  | 
      
      
         | 622 | 
          | 
          | 
                 default:
  | 
      
      
         | 623 | 
          | 
          | 
                   break;
  | 
      
      
         | 624 | 
          | 
          | 
                 }
  | 
      
      
         | 625 | 
          | 
          | 
          
  | 
      
      
         | 626 | 
          | 
          | 
               /* Pass the option on.  */
  | 
      
      
         | 627 | 
          | 
          | 
               for (i = 0; i < option->canonical_option_num_elements; ++i)
  | 
      
      
         | 628 | 
          | 
          | 
                 obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
  | 
      
      
         | 629 | 
          | 
          | 
             }
  | 
      
      
         | 630 | 
          | 
          | 
          
  | 
      
      
         | 631 | 
          | 
          | 
           if (no_partition)
  | 
      
      
         | 632 | 
          | 
          | 
             {
  | 
      
      
         | 633 | 
          | 
          | 
               lto_mode = LTO_MODE_LTO;
  | 
      
      
         | 634 | 
          | 
          | 
               jobserver = 0;
  | 
      
      
         | 635 | 
          | 
          | 
               parallel = 0;
  | 
      
      
         | 636 | 
          | 
          | 
             }
  | 
      
      
         | 637 | 
          | 
          | 
          
  | 
      
      
         | 638 | 
          | 
          | 
           if (linker_output)
  | 
      
      
         | 639 | 
          | 
          | 
             {
  | 
      
      
         | 640 | 
          | 
          | 
               char *output_dir, *base, *name;
  | 
      
      
         | 641 | 
          | 
          | 
               bool bit_bucket = strcmp (linker_output, HOST_BIT_BUCKET) == 0;
  | 
      
      
         | 642 | 
          | 
          | 
          
  | 
      
      
         | 643 | 
          | 
          | 
               output_dir = xstrdup (linker_output);
  | 
      
      
         | 644 | 
          | 
          | 
               base = output_dir;
  | 
      
      
         | 645 | 
          | 
          | 
               for (name = base; *name; name++)
  | 
      
      
         | 646 | 
          | 
          | 
                 if (IS_DIR_SEPARATOR (*name))
  | 
      
      
         | 647 | 
          | 
          | 
                   base = name + 1;
  | 
      
      
         | 648 | 
          | 
          | 
               *base = '\0';
  | 
      
      
         | 649 | 
          | 
          | 
          
  | 
      
      
         | 650 | 
          | 
          | 
               linker_output = &linker_output[base - output_dir];
  | 
      
      
         | 651 | 
          | 
          | 
               if (*output_dir == '\0')
  | 
      
      
         | 652 | 
          | 
          | 
                 {
  | 
      
      
         | 653 | 
          | 
          | 
                   static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
  | 
      
      
         | 654 | 
          | 
          | 
                   output_dir = current_dir;
  | 
      
      
         | 655 | 
          | 
          | 
                 }
  | 
      
      
         | 656 | 
          | 
          | 
               if (!bit_bucket)
  | 
      
      
         | 657 | 
          | 
          | 
                 {
  | 
      
      
         | 658 | 
          | 
          | 
                   obstack_ptr_grow (&argv_obstack, "-dumpdir");
  | 
      
      
         | 659 | 
          | 
          | 
                   obstack_ptr_grow (&argv_obstack, output_dir);
  | 
      
      
         | 660 | 
          | 
          | 
                 }
  | 
      
      
         | 661 | 
          | 
          | 
          
  | 
      
      
         | 662 | 
          | 
          | 
               obstack_ptr_grow (&argv_obstack, "-dumpbase");
  | 
      
      
         | 663 | 
          | 
          | 
             }
  | 
      
      
         | 664 | 
          | 
          | 
          
  | 
      
      
         | 665 | 
          | 
          | 
           /* Remember at which point we can scrub args to re-use the commons.  */
  | 
      
      
         | 666 | 
          | 
          | 
           new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
  | 
      
      
         | 667 | 
          | 
          | 
          
  | 
      
      
         | 668 | 
          | 
          | 
           if (lto_mode == LTO_MODE_LTO)
  | 
      
      
         | 669 | 
          | 
          | 
             {
  | 
      
      
         | 670 | 
          | 
          | 
               flto_out = make_temp_file (".lto.o");
  | 
      
      
         | 671 | 
          | 
          | 
               if (linker_output)
  | 
      
      
         | 672 | 
          | 
          | 
                 obstack_ptr_grow (&argv_obstack, linker_output);
  | 
      
      
         | 673 | 
          | 
          | 
               obstack_ptr_grow (&argv_obstack, "-o");
  | 
      
      
         | 674 | 
          | 
          | 
               obstack_ptr_grow (&argv_obstack, flto_out);
  | 
      
      
         | 675 | 
          | 
          | 
             }
  | 
      
      
         | 676 | 
          | 
          | 
           else
  | 
      
      
         | 677 | 
          | 
          | 
             {
  | 
      
      
         | 678 | 
          | 
          | 
               const char *list_option = "-fltrans-output-list=";
  | 
      
      
         | 679 | 
          | 
          | 
               size_t list_option_len = strlen (list_option);
  | 
      
      
         | 680 | 
          | 
          | 
               char *tmp;
  | 
      
      
         | 681 | 
          | 
          | 
          
  | 
      
      
         | 682 | 
          | 
          | 
               if (linker_output)
  | 
      
      
         | 683 | 
          | 
          | 
                 {
  | 
      
      
         | 684 | 
          | 
          | 
                   char *dumpbase = (char *) xmalloc (strlen (linker_output)
  | 
      
      
         | 685 | 
          | 
          | 
                                                      + sizeof (".wpa") + 1);
  | 
      
      
         | 686 | 
          | 
          | 
                   strcpy (dumpbase, linker_output);
  | 
      
      
         | 687 | 
          | 
          | 
                   strcat (dumpbase, ".wpa");
  | 
      
      
         | 688 | 
          | 
          | 
                   obstack_ptr_grow (&argv_obstack, dumpbase);
  | 
      
      
         | 689 | 
          | 
          | 
                 }
  | 
      
      
         | 690 | 
          | 
          | 
          
  | 
      
      
         | 691 | 
          | 
          | 
               if (linker_output && debug)
  | 
      
      
         | 692 | 
          | 
          | 
                 {
  | 
      
      
         | 693 | 
          | 
          | 
                   ltrans_output_file = (char *) xmalloc (strlen (linker_output)
  | 
      
      
         | 694 | 
          | 
          | 
                                                          + sizeof (".ltrans.out") + 1);
  | 
      
      
         | 695 | 
          | 
          | 
                   strcpy (ltrans_output_file, linker_output);
  | 
      
      
         | 696 | 
          | 
          | 
                   strcat (ltrans_output_file, ".ltrans.out");
  | 
      
      
         | 697 | 
          | 
          | 
                 }
  | 
      
      
         | 698 | 
          | 
          | 
               else
  | 
      
      
         | 699 | 
          | 
          | 
                 ltrans_output_file = make_temp_file (".ltrans.out");
  | 
      
      
         | 700 | 
          | 
          | 
               list_option_full = (char *) xmalloc (sizeof (char) *
  | 
      
      
         | 701 | 
          | 
          | 
                                  (strlen (ltrans_output_file) + list_option_len + 1));
  | 
      
      
         | 702 | 
          | 
          | 
               tmp = list_option_full;
  | 
      
      
         | 703 | 
          | 
          | 
          
  | 
      
      
         | 704 | 
          | 
          | 
               obstack_ptr_grow (&argv_obstack, tmp);
  | 
      
      
         | 705 | 
          | 
          | 
               strcpy (tmp, list_option);
  | 
      
      
         | 706 | 
          | 
          | 
               tmp += list_option_len;
  | 
      
      
         | 707 | 
          | 
          | 
               strcpy (tmp, ltrans_output_file);
  | 
      
      
         | 708 | 
          | 
          | 
          
  | 
      
      
         | 709 | 
          | 
          | 
               obstack_ptr_grow (&argv_obstack, "-fwpa");
  | 
      
      
         | 710 | 
          | 
          | 
             }
  | 
      
      
         | 711 | 
          | 
          | 
          
  | 
      
      
         | 712 | 
          | 
          | 
           /* Append the input objects and possible preceeding arguments.  */
  | 
      
      
         | 713 | 
          | 
          | 
           for (i = 1; i < argc; ++i)
  | 
      
      
         | 714 | 
          | 
          | 
             obstack_ptr_grow (&argv_obstack, argv[i]);
  | 
      
      
         | 715 | 
          | 
          | 
           obstack_ptr_grow (&argv_obstack, NULL);
  | 
      
      
         | 716 | 
          | 
          | 
          
  | 
      
      
         | 717 | 
          | 
          | 
           new_argv = XOBFINISH (&argv_obstack, const char **);
  | 
      
      
         | 718 | 
          | 
          | 
           argv_ptr = &new_argv[new_head_argc];
  | 
      
      
         | 719 | 
          | 
          | 
           fork_execute (CONST_CAST (char **, new_argv));
  | 
      
      
         | 720 | 
          | 
          | 
          
  | 
      
      
         | 721 | 
          | 
          | 
           if (lto_mode == LTO_MODE_LTO)
  | 
      
      
         | 722 | 
          | 
          | 
             {
  | 
      
      
         | 723 | 
          | 
          | 
               printf("%s\n", flto_out);
  | 
      
      
         | 724 | 
          | 
          | 
               free (flto_out);
  | 
      
      
         | 725 | 
          | 
          | 
               flto_out = NULL;
  | 
      
      
         | 726 | 
          | 
          | 
             }
  | 
      
      
         | 727 | 
          | 
          | 
           else
  | 
      
      
         | 728 | 
          | 
          | 
             {
  | 
      
      
         | 729 | 
          | 
          | 
               FILE *stream = fopen (ltrans_output_file, "r");
  | 
      
      
         | 730 | 
          | 
          | 
               FILE *mstream = NULL;
  | 
      
      
         | 731 | 
          | 
          | 
               struct obstack env_obstack;
  | 
      
      
         | 732 | 
          | 
          | 
          
  | 
      
      
         | 733 | 
          | 
          | 
               if (!stream)
  | 
      
      
         | 734 | 
          | 
          | 
                 fatal_perror ("fopen: %s", ltrans_output_file);
  | 
      
      
         | 735 | 
          | 
          | 
          
  | 
      
      
         | 736 | 
          | 
          | 
               /* Parse the list of LTRANS inputs from the WPA stage.  */
  | 
      
      
         | 737 | 
          | 
          | 
               obstack_init (&env_obstack);
  | 
      
      
         | 738 | 
          | 
          | 
               nr = 0;
  | 
      
      
         | 739 | 
          | 
          | 
               for (;;)
  | 
      
      
         | 740 | 
          | 
          | 
                 {
  | 
      
      
         | 741 | 
          | 
          | 
                   const unsigned piece = 32;
  | 
      
      
         | 742 | 
          | 
          | 
                   char *output_name = NULL;
  | 
      
      
         | 743 | 
          | 
          | 
                   char *buf, *input_name = (char *)xmalloc (piece);
  | 
      
      
         | 744 | 
          | 
          | 
                   size_t len;
  | 
      
      
         | 745 | 
          | 
          | 
          
  | 
      
      
         | 746 | 
          | 
          | 
                   buf = input_name;
  | 
      
      
         | 747 | 
          | 
          | 
         cont:
  | 
      
      
         | 748 | 
          | 
          | 
                   if (!fgets (buf, piece, stream))
  | 
      
      
         | 749 | 
          | 
          | 
                     break;
  | 
      
      
         | 750 | 
          | 
          | 
                   len = strlen (input_name);
  | 
      
      
         | 751 | 
          | 
          | 
                   if (input_name[len - 1] != '\n')
  | 
      
      
         | 752 | 
          | 
          | 
                     {
  | 
      
      
         | 753 | 
          | 
          | 
                       input_name = (char *)xrealloc (input_name, len + piece);
  | 
      
      
         | 754 | 
          | 
          | 
                       buf = input_name + len;
  | 
      
      
         | 755 | 
          | 
          | 
                       goto cont;
  | 
      
      
         | 756 | 
          | 
          | 
                     }
  | 
      
      
         | 757 | 
          | 
          | 
                   input_name[len - 1] = '\0';
  | 
      
      
         | 758 | 
          | 
          | 
          
  | 
      
      
         | 759 | 
          | 
          | 
                   if (input_name[0] == '*')
  | 
      
      
         | 760 | 
          | 
          | 
                     output_name = &input_name[1];
  | 
      
      
         | 761 | 
          | 
          | 
          
  | 
      
      
         | 762 | 
          | 
          | 
                   nr++;
  | 
      
      
         | 763 | 
          | 
          | 
                   input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
  | 
      
      
         | 764 | 
          | 
          | 
                   output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
  | 
      
      
         | 765 | 
          | 
          | 
                   input_names[nr-1] = input_name;
  | 
      
      
         | 766 | 
          | 
          | 
                   output_names[nr-1] = output_name;
  | 
      
      
         | 767 | 
          | 
          | 
                 }
  | 
      
      
         | 768 | 
          | 
          | 
               fclose (stream);
  | 
      
      
         | 769 | 
          | 
          | 
               maybe_unlink_file (ltrans_output_file);
  | 
      
      
         | 770 | 
          | 
          | 
               ltrans_output_file = NULL;
  | 
      
      
         | 771 | 
          | 
          | 
          
  | 
      
      
         | 772 | 
          | 
          | 
               if (parallel)
  | 
      
      
         | 773 | 
          | 
          | 
                 {
  | 
      
      
         | 774 | 
          | 
          | 
                   makefile = make_temp_file (".mk");
  | 
      
      
         | 775 | 
          | 
          | 
                   mstream = fopen (makefile, "w");
  | 
      
      
         | 776 | 
          | 
          | 
                 }
  | 
      
      
         | 777 | 
          | 
          | 
          
  | 
      
      
         | 778 | 
          | 
          | 
               /* Execute the LTRANS stage for each input file (or prepare a
  | 
      
      
         | 779 | 
          | 
          | 
                  makefile to invoke this in parallel).  */
  | 
      
      
         | 780 | 
          | 
          | 
               for (i = 0; i < nr; ++i)
  | 
      
      
         | 781 | 
          | 
          | 
                 {
  | 
      
      
         | 782 | 
          | 
          | 
                   char *output_name;
  | 
      
      
         | 783 | 
          | 
          | 
                   char *input_name = input_names[i];
  | 
      
      
         | 784 | 
          | 
          | 
                   /* If it's a pass-through file do nothing.  */
  | 
      
      
         | 785 | 
          | 
          | 
                   if (output_names[i])
  | 
      
      
         | 786 | 
          | 
          | 
                     continue;
  | 
      
      
         | 787 | 
          | 
          | 
          
  | 
      
      
         | 788 | 
          | 
          | 
                   /* Replace the .o suffix with a .ltrans.o suffix and write
  | 
      
      
         | 789 | 
          | 
          | 
                      the resulting name to the LTRANS output list.  */
  | 
      
      
         | 790 | 
          | 
          | 
                   obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
  | 
      
      
         | 791 | 
          | 
          | 
                   obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
  | 
      
      
         | 792 | 
          | 
          | 
                   output_name = XOBFINISH (&env_obstack, char *);
  | 
      
      
         | 793 | 
          | 
          | 
          
  | 
      
      
         | 794 | 
          | 
          | 
                   /* Adjust the dumpbase if the linker output file was seen.  */
  | 
      
      
         | 795 | 
          | 
          | 
                   if (linker_output)
  | 
      
      
         | 796 | 
          | 
          | 
                     {
  | 
      
      
         | 797 | 
          | 
          | 
                       char *dumpbase
  | 
      
      
         | 798 | 
          | 
          | 
                           = (char *) xmalloc (strlen (linker_output)
  | 
      
      
         | 799 | 
          | 
          | 
                                               + sizeof(DUMPBASE_SUFFIX) + 1);
  | 
      
      
         | 800 | 
          | 
          | 
                       snprintf (dumpbase,
  | 
      
      
         | 801 | 
          | 
          | 
                                 strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
  | 
      
      
         | 802 | 
          | 
          | 
                                 "%s.ltrans%u", linker_output, i);
  | 
      
      
         | 803 | 
          | 
          | 
                       argv_ptr[0] = dumpbase;
  | 
      
      
         | 804 | 
          | 
          | 
                     }
  | 
      
      
         | 805 | 
          | 
          | 
          
  | 
      
      
         | 806 | 
          | 
          | 
                   argv_ptr[1] = "-fltrans";
  | 
      
      
         | 807 | 
          | 
          | 
                   argv_ptr[2] = "-o";
  | 
      
      
         | 808 | 
          | 
          | 
                   argv_ptr[3] = output_name;
  | 
      
      
         | 809 | 
          | 
          | 
                   argv_ptr[4] = input_name;
  | 
      
      
         | 810 | 
          | 
          | 
                   argv_ptr[5] = NULL;
  | 
      
      
         | 811 | 
          | 
          | 
                   if (parallel)
  | 
      
      
         | 812 | 
          | 
          | 
                     {
  | 
      
      
         | 813 | 
          | 
          | 
                       fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
  | 
      
      
         | 814 | 
          | 
          | 
                       for (j = 1; new_argv[j] != NULL; ++j)
  | 
      
      
         | 815 | 
          | 
          | 
                         fprintf (mstream, " '%s'", new_argv[j]);
  | 
      
      
         | 816 | 
          | 
          | 
                       fprintf (mstream, "\n");
  | 
      
      
         | 817 | 
          | 
          | 
                       /* If we are not preserving the ltrans input files then
  | 
      
      
         | 818 | 
          | 
          | 
                          truncate them as soon as we have processed it.  This
  | 
      
      
         | 819 | 
          | 
          | 
                          reduces temporary disk-space usage.  */
  | 
      
      
         | 820 | 
          | 
          | 
                       if (! debug)
  | 
      
      
         | 821 | 
          | 
          | 
                         fprintf (mstream, "\t@-touch -r %s %s.tem > /dev/null 2>&1 "
  | 
      
      
         | 822 | 
          | 
          | 
                                  "&& mv %s.tem %s\n",
  | 
      
      
         | 823 | 
          | 
          | 
                                  input_name, input_name, input_name, input_name);
  | 
      
      
         | 824 | 
          | 
          | 
                     }
  | 
      
      
         | 825 | 
          | 
          | 
                   else
  | 
      
      
         | 826 | 
          | 
          | 
                     {
  | 
      
      
         | 827 | 
          | 
          | 
                       fork_execute (CONST_CAST (char **, new_argv));
  | 
      
      
         | 828 | 
          | 
          | 
                       maybe_unlink_file (input_name);
  | 
      
      
         | 829 | 
          | 
          | 
                     }
  | 
      
      
         | 830 | 
          | 
          | 
          
  | 
      
      
         | 831 | 
          | 
          | 
                   output_names[i] = output_name;
  | 
      
      
         | 832 | 
          | 
          | 
                 }
  | 
      
      
         | 833 | 
          | 
          | 
               if (parallel)
  | 
      
      
         | 834 | 
          | 
          | 
                 {
  | 
      
      
         | 835 | 
          | 
          | 
                   struct pex_obj *pex;
  | 
      
      
         | 836 | 
          | 
          | 
                   char jobs[32];
  | 
      
      
         | 837 | 
          | 
          | 
          
  | 
      
      
         | 838 | 
          | 
          | 
                   fprintf (mstream, "all:");
  | 
      
      
         | 839 | 
          | 
          | 
                   for (i = 0; i < nr; ++i)
  | 
      
      
         | 840 | 
          | 
          | 
                     fprintf (mstream, " \\\n\t%s", output_names[i]);
  | 
      
      
         | 841 | 
          | 
          | 
                   fprintf (mstream, "\n");
  | 
      
      
         | 842 | 
          | 
          | 
                   fclose (mstream);
  | 
      
      
         | 843 | 
          | 
          | 
                   if (!jobserver)
  | 
      
      
         | 844 | 
          | 
          | 
                     {
  | 
      
      
         | 845 | 
          | 
          | 
                       /* Avoid passing --jobserver-fd= and similar flags
  | 
      
      
         | 846 | 
          | 
          | 
                          unless jobserver mode is explicitly enabled.  */
  | 
      
      
         | 847 | 
          | 
          | 
                       putenv (xstrdup ("MAKEFLAGS="));
  | 
      
      
         | 848 | 
          | 
          | 
                       putenv (xstrdup ("MFLAGS="));
  | 
      
      
         | 849 | 
          | 
          | 
                     }
  | 
      
      
         | 850 | 
          | 
          | 
                   new_argv[0] = getenv ("MAKE");
  | 
      
      
         | 851 | 
          | 
          | 
                   if (!new_argv[0])
  | 
      
      
         | 852 | 
          | 
          | 
                     new_argv[0] = "make";
  | 
      
      
         | 853 | 
          | 
          | 
                   new_argv[1] = "-f";
  | 
      
      
         | 854 | 
          | 
          | 
                   new_argv[2] = makefile;
  | 
      
      
         | 855 | 
          | 
          | 
                   i = 3;
  | 
      
      
         | 856 | 
          | 
          | 
                   if (!jobserver)
  | 
      
      
         | 857 | 
          | 
          | 
                     {
  | 
      
      
         | 858 | 
          | 
          | 
                       snprintf (jobs, 31, "-j%d", parallel);
  | 
      
      
         | 859 | 
          | 
          | 
                       new_argv[i++] = jobs;
  | 
      
      
         | 860 | 
          | 
          | 
                     }
  | 
      
      
         | 861 | 
          | 
          | 
                   new_argv[i++] = "all";
  | 
      
      
         | 862 | 
          | 
          | 
                   new_argv[i++] = NULL;
  | 
      
      
         | 863 | 
          | 
          | 
                   pex = collect_execute (CONST_CAST (char **, new_argv));
  | 
      
      
         | 864 | 
          | 
          | 
                   collect_wait (new_argv[0], pex);
  | 
      
      
         | 865 | 
          | 
          | 
                   maybe_unlink_file (makefile);
  | 
      
      
         | 866 | 
          | 
          | 
                   makefile = NULL;
  | 
      
      
         | 867 | 
          | 
          | 
                   for (i = 0; i < nr; ++i)
  | 
      
      
         | 868 | 
          | 
          | 
                     maybe_unlink_file (input_names[i]);
  | 
      
      
         | 869 | 
          | 
          | 
                 }
  | 
      
      
         | 870 | 
          | 
          | 
               for (i = 0; i < nr; ++i)
  | 
      
      
         | 871 | 
          | 
          | 
                 {
  | 
      
      
         | 872 | 
          | 
          | 
                   fputs (output_names[i], stdout);
  | 
      
      
         | 873 | 
          | 
          | 
                   putc ('\n', stdout);
  | 
      
      
         | 874 | 
          | 
          | 
                   free (input_names[i]);
  | 
      
      
         | 875 | 
          | 
          | 
                 }
  | 
      
      
         | 876 | 
          | 
          | 
               nr = 0;
  | 
      
      
         | 877 | 
          | 
          | 
               free (output_names);
  | 
      
      
         | 878 | 
          | 
          | 
               free (input_names);
  | 
      
      
         | 879 | 
          | 
          | 
               free (list_option_full);
  | 
      
      
         | 880 | 
          | 
          | 
               obstack_free (&env_obstack, NULL);
  | 
      
      
         | 881 | 
          | 
          | 
             }
  | 
      
      
         | 882 | 
          | 
          | 
          
  | 
      
      
         | 883 | 
          | 
          | 
           obstack_free (&argv_obstack, NULL);
  | 
      
      
         | 884 | 
          | 
          | 
         }
  | 
      
      
         | 885 | 
          | 
          | 
          
  | 
      
      
         | 886 | 
          | 
          | 
          
  | 
      
      
         | 887 | 
          | 
          | 
         /* Entry point.  */
  | 
      
      
         | 888 | 
          | 
          | 
          
  | 
      
      
         | 889 | 
          | 
          | 
         int
  | 
      
      
         | 890 | 
          | 
          | 
         main (int argc, char *argv[])
  | 
      
      
         | 891 | 
          | 
          | 
         {
  | 
      
      
         | 892 | 
          | 
          | 
           const char *p;
  | 
      
      
         | 893 | 
          | 
          | 
          
  | 
      
      
         | 894 | 
          | 
          | 
           p = argv[0] + strlen (argv[0]);
  | 
      
      
         | 895 | 
          | 
          | 
           while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
  | 
      
      
         | 896 | 
          | 
          | 
             --p;
  | 
      
      
         | 897 | 
          | 
          | 
           progname = p;
  | 
      
      
         | 898 | 
          | 
          | 
          
  | 
      
      
         | 899 | 
          | 
          | 
           xmalloc_set_program_name (progname);
  | 
      
      
         | 900 | 
          | 
          | 
          
  | 
      
      
         | 901 | 
          | 
          | 
           gcc_init_libintl ();
  | 
      
      
         | 902 | 
          | 
          | 
          
  | 
      
      
         | 903 | 
          | 
          | 
           diagnostic_initialize (global_dc, 0);
  | 
      
      
         | 904 | 
          | 
          | 
          
  | 
      
      
         | 905 | 
          | 
          | 
           if (signal (SIGINT, SIG_IGN) != SIG_IGN)
  | 
      
      
         | 906 | 
          | 
          | 
             signal (SIGINT, fatal_signal);
  | 
      
      
         | 907 | 
          | 
          | 
         #ifdef SIGHUP
  | 
      
      
         | 908 | 
          | 
          | 
           if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
  | 
      
      
         | 909 | 
          | 
          | 
             signal (SIGHUP, fatal_signal);
  | 
      
      
         | 910 | 
          | 
          | 
         #endif
  | 
      
      
         | 911 | 
          | 
          | 
           if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
  | 
      
      
         | 912 | 
          | 
          | 
             signal (SIGTERM, fatal_signal);
  | 
      
      
         | 913 | 
          | 
          | 
         #ifdef SIGPIPE
  | 
      
      
         | 914 | 
          | 
          | 
           if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
  | 
      
      
         | 915 | 
          | 
          | 
             signal (SIGPIPE, fatal_signal);
  | 
      
      
         | 916 | 
          | 
          | 
         #endif
  | 
      
      
         | 917 | 
          | 
          | 
         #ifdef SIGCHLD
  | 
      
      
         | 918 | 
          | 
          | 
           /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
  | 
      
      
         | 919 | 
          | 
          | 
              receive the signal.  A different setting is inheritable */
  | 
      
      
         | 920 | 
          | 
          | 
           signal (SIGCHLD, SIG_DFL);
  | 
      
      
         | 921 | 
          | 
          | 
         #endif
  | 
      
      
         | 922 | 
          | 
          | 
          
  | 
      
      
         | 923 | 
          | 
          | 
           /* We may be called with all the arguments stored in some file and
  | 
      
      
         | 924 | 
          | 
          | 
              passed with @file.  Expand them into argv before processing.  */
  | 
      
      
         | 925 | 
          | 
          | 
           expandargv (&argc, &argv);
  | 
      
      
         | 926 | 
          | 
          | 
          
  | 
      
      
         | 927 | 
          | 
          | 
           run_gcc (argc, argv);
  | 
      
      
         | 928 | 
          | 
          | 
          
  | 
      
      
         | 929 | 
          | 
          | 
           return 0;
  | 
      
      
         | 930 | 
          | 
          | 
         }
  |