OSDN Git Service

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