1 /* Wrapper to call lto. Used by collect2 and the linker plugin.
2 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4 Factored out of collect2 by Rafael Espindola <espindola@google.com>
6 This file is part of GCC.
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
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
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/>. */
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.
30 $ lto-wrapper gcc/xgcc -B gcc a.o b.o -o test -flto
32 The above will print something like
35 If WHOPR is used instead, more than one file might be produced
36 ./ccXj2DTk.lto.ltrans.o
37 ./ccCJuXGv.lto.ltrans.o
42 #include "coretypes.h"
44 #include "diagnostic.h"
47 int debug
; /* true if -save-temps. */
48 int verbose
; /* true if -v. */
51 LTO_MODE_NONE
, /* Not doing LTO. */
52 LTO_MODE_LTO
, /* Normal LTO. */
53 LTO_MODE_WHOPR
/* WHOPR. */
56 /* Current LTO mode. */
57 static enum lto_mode_d lto_mode
= LTO_MODE_NONE
;
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
;
67 static void maybe_unlink_file (const char *);
69 /* Delete tempfiles. */
72 lto_wrapper_cleanup (void)
74 static bool cleanup_done
= false;
80 /* Setting cleanup_done prevents an infinite loop if one of the
81 calls to maybe_unlink_file fails. */
84 if (ltrans_output_file
)
85 maybe_unlink_file (ltrans_output_file
);
87 maybe_unlink_file (flto_out
);
89 maybe_unlink_file (args_name
);
91 maybe_unlink_file (makefile
);
92 for (i
= 0; i
< nr
; ++i
)
94 maybe_unlink_file (input_names
[i
]);
96 maybe_unlink_file (output_names
[i
]);
101 fatal_signal (int signum
)
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
);
110 /* Just die. CMSGID is the error message. */
112 static void __attribute__ ((format (printf
, 1, 2)))
113 fatal (const char * cmsgid
, ...)
117 va_start (ap
, cmsgid
);
118 fprintf (stderr
, "lto-wrapper: ");
119 vfprintf (stderr
, _(cmsgid
), ap
);
120 fprintf (stderr
, "\n");
123 lto_wrapper_cleanup ();
124 exit (FATAL_EXIT_CODE
);
128 /* Die when sys call fails. CMSGID is the error message. */
130 static void __attribute__ ((format (printf
, 1, 2)))
131 fatal_perror (const char *cmsgid
, ...)
136 va_start (ap
, cmsgid
);
137 fprintf (stderr
, "lto-wrapper: ");
138 vfprintf (stderr
, _(cmsgid
), ap
);
139 fprintf (stderr
, ": %s\n", xstrerror (e
));
142 lto_wrapper_cleanup ();
143 exit (FATAL_EXIT_CODE
);
147 /* Execute a program, and wait for the reply. ARGV are the arguments. The
148 last one must be NULL. */
150 static struct pex_obj
*
151 collect_execute (char **argv
)
162 for (p_argv
= argv
; (str
= *p_argv
) != (char *) 0; p_argv
++)
163 fprintf (stderr
, " %s", str
);
165 fprintf (stderr
, "\n");
171 pex
= pex_init (0, "lto-wrapper", NULL
);
173 fatal_perror ("pex_init failed");
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
,
185 fatal_perror (errmsg
);
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. */
199 collect_wait (const char *prog
, struct pex_obj
*pex
)
203 if (!pex_get_status (pex
, 1, &status
))
204 fatal_perror ("can't get program status");
209 if (WIFSIGNALED (status
))
211 int sig
= WTERMSIG (status
);
212 if (WCOREDUMP (status
))
213 fatal ("%s terminated with signal %d [%s], core dumped",
214 prog
, sig
, strsignal (sig
));
216 fatal ("%s terminated with signal %d [%s]",
217 prog
, sig
, strsignal (sig
));
220 if (WIFEXITED (status
))
221 fatal ("%s returned %d exit status", prog
, WEXITSTATUS (status
));
228 /* Unlink a temporary LTRANS file unless requested otherwise. */
231 maybe_unlink_file (const char *file
)
235 if (unlink_if_ordinary (file
)
237 fatal_perror ("deleting LTRANS file %s", file
);
240 fprintf (stderr
, "[Leaving LTRANS %s]\n", file
);
244 /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */
247 fork_execute (char **argv
)
255 args_name
= make_temp_file (".args");
256 at_args
= concat ("@", args_name
, NULL
);
257 args
= fopen (args_name
, "w");
259 fatal ("failed to open %s", args_name
);
261 status
= writeargv (&argv
[1], args
);
264 fatal ("could not write to temporary file %s", args_name
);
268 new_argv
[0] = argv
[0];
269 new_argv
[1] = at_args
;
272 pex
= collect_execute (new_argv
);
273 collect_wait (new_argv
[0], pex
);
275 maybe_unlink_file (args_name
);
280 /* Template of LTRANS dumpbase suffix. */
281 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
283 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
286 run_gcc (unsigned argc
, char *argv
[])
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
;
298 bool no_partition
= false;
300 /* Get the driver and options. */
301 collect_gcc
= getenv ("COLLECT_GCC");
303 fatal ("environment variable COLLECT_GCC must be set");
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");
310 /* Count arguments. */
312 for (j
= 0; collect_gcc_options
[j
] != '\0'; ++j
)
313 if (collect_gcc_options
[j
] == '\'')
317 fatal ("malformed COLLECT_GCC_OPTIONS");
319 /* Initalize the common arguments for the driver. */
320 new_argv
= (const char **) xmalloc ((15 + i
/ 2 + argc
) * sizeof (char *));
322 *argv_ptr
++ = collect_gcc
;
323 *argv_ptr
++ = "-xlto";
325 for (j
= 0; collect_gcc_options
[j
] != '\0'; ++j
)
326 if (collect_gcc_options
[j
] == '\'')
332 while (collect_gcc_options
[j
] != '\'')
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 *);
341 linker_output
= option
;
346 /* If we see -o, skip it and skip and record its argument. */
347 if (option
[0] == '-' && option
[1] == 'o')
349 if (option
[2] == '\0')
352 linker_output
= &option
[2];
356 if (strcmp (option
, "-save-temps") == 0)
358 if (strcmp (option
, "-v") == 0)
361 if (strcmp (option
, "-flto-partition=none") == 0)
363 /* We've handled these LTO options, do not pass them on. */
364 if (strncmp (option
, "-flto=", 6) == 0
365 || !strcmp (option
, "-flto"))
367 lto_mode
= LTO_MODE_WHOPR
;
368 if (option
[5] == '=')
370 if (!strcmp (option
+ 6, "jobserver"))
377 parallel
= atoi (option
+ 6);
384 *argv_ptr
++ = option
;
388 lto_mode
= LTO_MODE_LTO
;
395 char *output_dir
, *base
, *name
;
396 bool bit_bucket
= strcmp (linker_output
, HOST_BIT_BUCKET
) == 0;
398 output_dir
= xstrdup (linker_output
);
400 for (name
= base
; *name
; name
++)
401 if (IS_DIR_SEPARATOR (*name
))
405 linker_output
= &linker_output
[base
- output_dir
];
406 if (*output_dir
== '\0')
408 static char current_dir
[] = { '.', DIR_SEPARATOR
, '\0' };
409 output_dir
= current_dir
;
413 *argv_ptr
++ = "-dumpdir";
414 *argv_ptr
++ = output_dir
;
417 *argv_ptr
++ = "-dumpbase";
422 if (lto_mode
== LTO_MODE_LTO
)
424 flto_out
= make_temp_file (".lto.o");
426 argv_ptr
[0] = linker_output
;
428 argv_ptr
[2] = flto_out
;
432 const char *list_option
= "-fltrans-output-list=";
433 size_t list_option_len
= strlen (list_option
);
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
;
445 if (linker_output
&& debug
)
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");
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
;
459 strcpy (tmp
, list_option
);
460 tmp
+= list_option_len
;
461 strcpy (tmp
, ltrans_output_file
);
463 argv_ptr
[2] = "-fwpa";
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
;
471 fork_execute (CONST_CAST (char **, new_argv
));
473 if (lto_mode
== LTO_MODE_LTO
)
475 printf("%s\n", flto_out
);
481 FILE *stream
= fopen (ltrans_output_file
, "r");
482 FILE *mstream
= NULL
;
485 fatal_perror ("fopen: %s", ltrans_output_file
);
487 /* Parse the list of LTRANS inputs from the WPA stage. */
491 const unsigned piece
= 32;
492 char *output_name
= NULL
;
493 char *buf
, *input_name
= (char *)xmalloc (piece
);
498 if (!fgets (buf
, piece
, stream
))
500 len
= strlen (input_name
);
501 if (input_name
[len
- 1] != '\n')
503 input_name
= (char *)xrealloc (input_name
, len
+ piece
);
504 buf
= input_name
+ len
;
507 input_name
[len
- 1] = '\0';
509 if (input_name
[0] == '*')
510 output_name
= &input_name
[1];
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
;
519 maybe_unlink_file (ltrans_output_file
);
520 ltrans_output_file
= NULL
;
524 makefile
= make_temp_file (".mk");
525 mstream
= fopen (makefile
, "w");
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
)
533 char *input_name
= input_names
[i
];
534 /* If it's a pass-through file do nothing. */
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 *);
545 /* Adjust the dumpbase if the linker output file was seen. */
549 = (char *) xmalloc (strlen (linker_output
)
550 + sizeof(DUMPBASE_SUFFIX
) + 1);
552 strlen (linker_output
) + sizeof(DUMPBASE_SUFFIX
),
553 "%s.ltrans%u", linker_output
, i
);
554 argv_ptr
[0] = dumpbase
;
557 argv_ptr
[1] = "-fltrans";
559 argv_ptr
[3] = output_name
;
560 argv_ptr
[4] = input_name
;
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");
570 fork_execute (CONST_CAST (char **, new_argv
));
572 output_names
[i
] = output_name
;
579 fprintf (mstream
, "all:");
580 for (i
= 0; i
< nr
; ++i
)
581 fprintf (mstream
, " \\\n\t%s", output_names
[i
]);
582 fprintf (mstream
, "\n");
586 /* Avoid passing --jobserver-fd= and similar flags
587 unless jobserver mode is explicitly enabled. */
588 putenv (xstrdup ("MAKEFLAGS="));
589 putenv (xstrdup ("MFLAGS="));
591 new_argv
[0] = getenv ("MAKE");
593 new_argv
[0] = "make";
595 new_argv
[2] = makefile
;
599 snprintf (jobs
, 31, "-j%d", parallel
);
600 new_argv
[i
++] = jobs
;
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
);
609 for (i
= 0; i
< nr
; ++i
)
611 fputs (output_names
[i
], stdout
);
613 maybe_unlink_file (input_names
[i
]);
614 free (input_names
[i
]);
619 free (list_option_full
);
622 obstack_free (&env_obstack
, NULL
);
629 main (int argc
, char *argv
[])
633 p
= argv
[0] + strlen (argv
[0]);
634 while (p
!= argv
[0] && !IS_DIR_SEPARATOR (p
[-1]))
638 xmalloc_set_program_name (progname
);
642 diagnostic_initialize (global_dc
, 0);
644 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
645 signal (SIGINT
, fatal_signal
);
647 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
648 signal (SIGHUP
, fatal_signal
);
650 if (signal (SIGTERM
, SIG_IGN
) != SIG_IGN
)
651 signal (SIGTERM
, fatal_signal
);
653 if (signal (SIGPIPE
, SIG_IGN
) != SIG_IGN
)
654 signal (SIGPIPE
, fatal_signal
);
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
);
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
);