OSDN Git Service

* cp-tree.h (struct tinst_level): Add chain_next GTY
[pf3gnuchains/gcc-fork.git] / gcc / lto-wrapper.c
1 /* 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
47 int debug;                              /* true if -save-temps.  */
48 int verbose;                            /* true if -v.  */
49
50 enum lto_mode_d {
51   LTO_MODE_NONE,                        /* Not doing LTO.  */
52   LTO_MODE_LTO,                         /* Normal LTO.  */
53   LTO_MODE_WHOPR                        /* WHOPR.  */
54 };
55
56 /* Current LTO mode.  */
57 static enum lto_mode_d lto_mode = LTO_MODE_NONE;
58
59 static char *ltrans_output_file;
60 static char *flto_out;
61 static char *args_name;
62 static unsigned int nr;
63 static char **input_names;
64 static char **output_names;
65 static char *makefile;
66
67 static void maybe_unlink_file (const char *);
68
69  /* Delete tempfiles.  */
70
71 static void
72 lto_wrapper_cleanup (void)
73 {
74   static bool cleanup_done = false;
75   unsigned int i;
76
77   if (cleanup_done)
78     return;
79
80   /* Setting cleanup_done prevents an infinite loop if one of the
81      calls to maybe_unlink_file fails. */
82   cleanup_done = true;
83
84   if (ltrans_output_file)
85     maybe_unlink_file (ltrans_output_file);
86   if (flto_out)
87     maybe_unlink_file (flto_out);
88   if (args_name)
89     maybe_unlink_file (args_name);
90   if (makefile)
91     maybe_unlink_file (makefile);
92   for (i = 0; i < nr; ++i)
93     {
94       maybe_unlink_file (input_names[i]);
95       if (output_names[i])
96         maybe_unlink_file (output_names[i]);
97     }
98 }
99
100 static void
101 fatal_signal (int signum)
102 {
103   signal (signum, SIG_DFL);
104   lto_wrapper_cleanup ();
105   /* Get the same signal again, this time not handled,
106      so its normal effect occurs.  */
107   kill (getpid (), signum);
108 }
109
110 /* Just die. CMSGID is the error message. */
111
112 static void __attribute__ ((format (printf, 1, 2)))
113 fatal (const char * cmsgid, ...)
114 {
115   va_list ap;
116
117   va_start (ap, cmsgid);
118   fprintf (stderr, "lto-wrapper: ");
119   vfprintf (stderr, _(cmsgid), ap);
120   fprintf (stderr, "\n");
121   va_end (ap);
122
123   lto_wrapper_cleanup ();
124   exit (FATAL_EXIT_CODE);
125 }
126
127
128 /* Die when sys call fails. CMSGID is the error message.  */
129
130 static void __attribute__ ((format (printf, 1, 2)))
131 fatal_perror (const char *cmsgid, ...)
132 {
133   int e = errno;
134   va_list ap;
135
136   va_start (ap, cmsgid);
137   fprintf (stderr, "lto-wrapper: ");
138   vfprintf (stderr, _(cmsgid), ap);
139   fprintf (stderr, ": %s\n", xstrerror (e));
140   va_end (ap);
141
142   lto_wrapper_cleanup ();
143   exit (FATAL_EXIT_CODE);
144 }
145
146
147 /* Execute a program, and wait for the reply. ARGV are the arguments. The
148    last one must be NULL. */
149
150 static struct pex_obj *
151 collect_execute (char **argv)
152 {
153   struct pex_obj *pex;
154   const char *errmsg;
155   int err;
156
157   if (verbose)
158     {
159       char **p_argv;
160       const char *str;
161
162       for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++)
163         fprintf (stderr, " %s", str);
164
165       fprintf (stderr, "\n");
166     }
167
168   fflush (stdout);
169   fflush (stderr);
170
171   pex = pex_init (0, "lto-wrapper", NULL);
172   if (pex == NULL)
173     fatal_perror ("pex_init failed");
174
175   /* Do not use PEX_LAST here, we use our stdout for communicating with
176      collect2 or the linker-plugin.  Any output from the sub-process
177      will confuse that.  */
178   errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
179                     NULL, &err);
180   if (errmsg != NULL)
181     {
182       if (err != 0)
183         {
184           errno = err;
185           fatal_perror (errmsg);
186         }
187       else
188         fatal (errmsg);
189     }
190
191   return pex;
192 }
193
194
195 /* Wait for a process to finish, and exit if a nonzero status is found.
196    PROG is the program name. PEX is the process we should wait for. */
197
198 static int
199 collect_wait (const char *prog, struct pex_obj *pex)
200 {
201   int status;
202
203   if (!pex_get_status (pex, 1, &status))
204     fatal_perror ("can't get program status");
205   pex_free (pex);
206
207   if (status)
208     {
209       if (WIFSIGNALED (status))
210         {
211           int sig = WTERMSIG (status);
212           if (WCOREDUMP (status))
213             fatal ("%s terminated with signal %d [%s], core dumped",
214                    prog, sig, strsignal (sig));
215           else
216             fatal ("%s terminated with signal %d [%s]",
217                    prog, sig, strsignal (sig));
218         }
219
220       if (WIFEXITED (status))
221         fatal ("%s returned %d exit status", prog, WEXITSTATUS (status));
222     }
223
224   return 0;
225 }
226
227
228 /* Unlink a temporary LTRANS file unless requested otherwise.  */
229
230 static void
231 maybe_unlink_file (const char *file)
232 {
233   if (! debug)
234     {
235       if (unlink_if_ordinary (file)
236           && errno != ENOENT)
237         fatal_perror ("deleting LTRANS file %s", file);
238     }
239   else
240     fprintf (stderr, "[Leaving LTRANS %s]\n", file);
241 }
242
243
244 /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish.  */
245
246 static void
247 fork_execute (char **argv)
248 {
249   struct pex_obj *pex;
250   char *new_argv[3];
251   char *at_args;
252   FILE *args;
253   int status;
254
255   args_name = make_temp_file (".args");
256   at_args = concat ("@", args_name, NULL);
257   args = fopen (args_name, "w");
258   if (args == NULL)
259     fatal ("failed to open %s", args_name);
260
261   status = writeargv (&argv[1], args);
262
263   if (status)
264     fatal ("could not write to temporary file %s",  args_name);
265
266   fclose (args);
267
268   new_argv[0] = argv[0];
269   new_argv[1] = at_args;
270   new_argv[2] = NULL;
271
272   pex = collect_execute (new_argv);
273   collect_wait (new_argv[0], pex);
274
275   maybe_unlink_file (args_name);
276   args_name = NULL;
277   free (at_args);
278 }
279
280 /* Template of LTRANS dumpbase suffix.  */
281 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
282
283 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
284
285 static void
286 run_gcc (unsigned argc, char *argv[])
287 {
288   unsigned i, j;
289   const char **new_argv;
290   const char **argv_ptr;
291   char *list_option_full = NULL;
292   const char *linker_output = NULL;
293   const char *collect_gcc_options, *collect_gcc;
294   struct obstack env_obstack;
295   bool seen_o = false;
296   int parallel = 0;
297   int jobserver = 0;
298   bool no_partition = false;
299
300   /* Get the driver and options.  */
301   collect_gcc = getenv ("COLLECT_GCC");
302   if (!collect_gcc)
303     fatal ("environment variable COLLECT_GCC must be set");
304
305   /* Set the CFLAGS environment variable.  */
306   collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
307   if (!collect_gcc_options)
308     fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
309
310   /* Count arguments.  */
311   i = 0;
312   for (j = 0; collect_gcc_options[j] != '\0'; ++j)
313     if (collect_gcc_options[j] == '\'')
314       ++i;
315
316   if (i % 2 != 0)
317     fatal ("malformed COLLECT_GCC_OPTIONS");
318
319   /* Initalize the common arguments for the driver.  */
320   new_argv = (const char **) xmalloc ((15 + i / 2 + argc) * sizeof (char *));
321   argv_ptr = new_argv;
322   *argv_ptr++ = collect_gcc;
323   *argv_ptr++ = "-xlto";
324   *argv_ptr++ = "-c";
325   for (j = 0; collect_gcc_options[j] != '\0'; ++j)
326     if (collect_gcc_options[j] == '\'')
327       {
328         char *option;
329
330         ++j;
331         i = j;
332         while (collect_gcc_options[j] != '\'')
333           ++j;
334
335         obstack_init (&env_obstack);
336         obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
337         obstack_1grow (&env_obstack, 0);
338         option = XOBFINISH (&env_obstack, char *);
339         if (seen_o)
340           {
341             linker_output = option;
342             seen_o = false;
343             continue;
344           }
345
346         /* If we see -o, skip it and skip and record its argument.  */
347         if (option[0] == '-' && option[1] == 'o')
348           {
349             if (option[2] == '\0')
350               seen_o = true;
351             else
352               linker_output = &option[2];
353             continue;
354           }
355
356         if (strcmp (option, "-save-temps") == 0)
357           debug = 1;
358         if (strcmp (option, "-v") == 0)
359           verbose = 1;
360
361         if (strcmp (option, "-flto-partition=none") == 0)
362           no_partition = true;
363         /* We've handled these LTO options, do not pass them on.  */
364         if (strncmp (option, "-flto=", 6) == 0
365             || !strcmp (option, "-flto"))
366           {
367             lto_mode = LTO_MODE_WHOPR;
368             if (option[5] == '=')
369               {
370                 if (!strcmp (option + 6, "jobserver"))
371                   {
372                     jobserver = 1;
373                     parallel = 1;
374                   }
375                 else
376                   {
377                     parallel = atoi (option + 6);
378                     if (parallel <= 1)
379                       parallel = 0;
380                   }
381               }
382           }
383         else
384           *argv_ptr++ = option;
385       }
386   if (no_partition)
387     {
388       lto_mode = LTO_MODE_LTO;
389       jobserver = 0;
390       parallel = 0;
391     }
392
393   if (linker_output)
394     {
395       char *output_dir, *base, *name;
396       bool bit_bucket = strcmp (linker_output, HOST_BIT_BUCKET) == 0;
397
398       output_dir = xstrdup (linker_output);
399       base = output_dir;
400       for (name = base; *name; name++)
401         if (IS_DIR_SEPARATOR (*name))
402           base = name + 1;
403       *base = '\0';
404
405       linker_output = &linker_output[base - output_dir];
406       if (*output_dir == '\0')
407         {
408           static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
409           output_dir = current_dir;
410         }
411       if (!bit_bucket)
412         {
413           *argv_ptr++ = "-dumpdir";
414           *argv_ptr++ = output_dir;
415         }
416
417       *argv_ptr++ = "-dumpbase";
418     }
419   else
420     argv_ptr--;
421
422   if (lto_mode == LTO_MODE_LTO)
423     {
424       flto_out = make_temp_file (".lto.o");
425       if (linker_output)
426         argv_ptr[0] = linker_output;
427       argv_ptr[1] = "-o";
428       argv_ptr[2] = flto_out;
429     }
430   else 
431     {
432       const char *list_option = "-fltrans-output-list=";
433       size_t list_option_len = strlen (list_option);
434       char *tmp;
435
436       if (linker_output)
437         {
438           char *dumpbase = (char *) xmalloc (strlen (linker_output)
439                                              + sizeof (".wpa") + 1);
440           strcpy (dumpbase, linker_output);
441           strcat (dumpbase, ".wpa");
442           argv_ptr[0] = dumpbase;
443         }
444
445       if (linker_output && debug)
446         {
447           ltrans_output_file = (char *) xmalloc (strlen (linker_output)
448                                                  + sizeof (".ltrans.out") + 1);
449           strcpy (ltrans_output_file, linker_output);
450           strcat (ltrans_output_file, ".ltrans.out");
451         }
452       else
453         ltrans_output_file = make_temp_file (".ltrans.out");
454       list_option_full = (char *) xmalloc (sizeof (char) *
455                          (strlen (ltrans_output_file) + list_option_len + 1));
456       tmp = list_option_full;
457
458       argv_ptr[1] = tmp;
459       strcpy (tmp, list_option);
460       tmp += list_option_len;
461       strcpy (tmp, ltrans_output_file);
462
463       argv_ptr[2] = "-fwpa";
464     }
465
466   /* Append the input objects and possible preceeding arguments.  */
467   for (i = 1; i < argc; ++i)
468     argv_ptr[2 + i] = argv[i];
469   argv_ptr[2 + i] = NULL;
470
471   fork_execute (CONST_CAST (char **, new_argv));
472
473   if (lto_mode == LTO_MODE_LTO)
474     {
475       printf("%s\n", flto_out);
476       free (flto_out);
477       flto_out = NULL;
478     }
479   else
480     {
481       FILE *stream = fopen (ltrans_output_file, "r");
482       FILE *mstream = NULL;
483
484       if (!stream)
485         fatal_perror ("fopen: %s", ltrans_output_file);
486
487       /* Parse the list of LTRANS inputs from the WPA stage.  */
488       nr = 0;
489       for (;;)
490         {
491           const unsigned piece = 32;
492           char *output_name = NULL;
493           char *buf, *input_name = (char *)xmalloc (piece);
494           size_t len;
495
496           buf = input_name;
497 cont:
498           if (!fgets (buf, piece, stream))
499             break;
500           len = strlen (input_name);
501           if (input_name[len - 1] != '\n')
502             {
503               input_name = (char *)xrealloc (input_name, len + piece);
504               buf = input_name + len;
505               goto cont;
506             }
507           input_name[len - 1] = '\0';
508
509           if (input_name[0] == '*')
510             output_name = &input_name[1];
511
512           nr++;
513           input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
514           output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
515           input_names[nr-1] = input_name;
516           output_names[nr-1] = output_name;
517         }
518       fclose (stream);
519       maybe_unlink_file (ltrans_output_file);
520       ltrans_output_file = NULL;
521
522       if (parallel)
523         {
524           makefile = make_temp_file (".mk");
525           mstream = fopen (makefile, "w");
526         }
527
528       /* Execute the LTRANS stage for each input file (or prepare a
529          makefile to invoke this in parallel).  */
530       for (i = 0; i < nr; ++i)
531         {
532           char *output_name;
533           char *input_name = input_names[i];
534           /* If it's a pass-through file do nothing.  */
535           if (output_names[i])
536             continue;
537
538           /* Replace the .o suffix with a .ltrans.o suffix and write
539              the resulting name to the LTRANS output list.  */
540           obstack_init (&env_obstack);
541           obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
542           obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
543           output_name = XOBFINISH (&env_obstack, char *);
544
545           /* Adjust the dumpbase if the linker output file was seen.  */
546           if (linker_output)
547             {
548               char *dumpbase
549                   = (char *) xmalloc (strlen (linker_output)
550                                       + sizeof(DUMPBASE_SUFFIX) + 1);
551               snprintf (dumpbase,
552                         strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
553                         "%s.ltrans%u", linker_output, i);
554               argv_ptr[0] = dumpbase;
555             }
556
557           argv_ptr[1] = "-fltrans";
558           argv_ptr[2] = "-o";
559           argv_ptr[3] = output_name;
560           argv_ptr[4] = input_name;
561           argv_ptr[5] = NULL;
562           if (parallel)
563             {
564               fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
565               for (j = 1; new_argv[j] != NULL; ++j)
566                 fprintf (mstream, " '%s'", new_argv[j]);
567               fprintf (mstream, "\n");
568             }
569           else
570             fork_execute (CONST_CAST (char **, new_argv));
571
572           output_names[i] = output_name;
573         }
574       if (parallel)
575         {
576           struct pex_obj *pex;
577           char jobs[32];
578
579           fprintf (mstream, "all:");
580           for (i = 0; i < nr; ++i)
581             fprintf (mstream, " \\\n\t%s", output_names[i]);
582           fprintf (mstream, "\n");
583           fclose (mstream);
584           if (!jobserver)
585             {
586               /* Avoid passing --jobserver-fd= and similar flags 
587                  unless jobserver mode is explicitly enabled.  */
588               putenv (xstrdup ("MAKEFLAGS="));
589               putenv (xstrdup ("MFLAGS="));
590             }
591           new_argv[0] = getenv ("MAKE");
592           if (!new_argv[0])
593             new_argv[0] = "make";
594           new_argv[1] = "-f";
595           new_argv[2] = makefile;
596           i = 3;
597           if (!jobserver)
598             {
599               snprintf (jobs, 31, "-j%d", parallel);
600               new_argv[i++] = jobs;
601             }
602           new_argv[i++] = "all";
603           new_argv[i++] = NULL;
604           pex = collect_execute (CONST_CAST (char **, new_argv));
605           collect_wait (new_argv[0], pex);
606           maybe_unlink_file (makefile);
607           makefile = NULL;
608         }
609       for (i = 0; i < nr; ++i)
610         {
611           fputs (output_names[i], stdout);
612           putc ('\n', stdout);
613           maybe_unlink_file (input_names[i]);
614           free (input_names[i]);
615         }
616       nr = 0;
617       free (output_names);
618       free (input_names);
619       free (list_option_full);
620     }
621
622   obstack_free (&env_obstack, NULL);
623 }
624
625
626 /* Entry point.  */
627
628 int
629 main (int argc, char *argv[])
630 {
631   const char *p;
632
633   p = argv[0] + strlen (argv[0]);
634   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
635     --p;
636   progname = p;
637
638   xmalloc_set_program_name (progname);
639
640   gcc_init_libintl ();
641
642   diagnostic_initialize (global_dc, 0);
643
644   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
645     signal (SIGINT, fatal_signal);
646 #ifdef SIGHUP
647   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
648     signal (SIGHUP, fatal_signal);
649 #endif
650   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
651     signal (SIGTERM, fatal_signal);
652 #ifdef SIGPIPE
653   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
654     signal (SIGPIPE, fatal_signal);
655 #endif
656 #ifdef SIGCHLD
657   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
658      receive the signal.  A different setting is inheritable */
659   signal (SIGCHLD, SIG_DFL);
660 #endif
661
662   /* We may be called with all the arguments stored in some file and
663      passed with @file.  Expand them into argv before processing.  */
664   expandargv (&argc, &argv);
665   run_gcc (argc, argv);
666
667   return 0;
668 }