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"
46 int debug
; /* true if -save-temps. */
47 int verbose
; /* true if -v. */
50 LTO_MODE_NONE
, /* Not doing LTO. */
51 LTO_MODE_LTO
, /* Normal LTO. */
52 LTO_MODE_WHOPR
/* WHOPR. */
55 /* Current LTO mode. */
56 static enum lto_mode_d lto_mode
= LTO_MODE_NONE
;
58 static char *ltrans_output_file
;
59 static char *flto_out
;
60 static char *args_name
;
61 static unsigned int nr
;
62 static char **input_names
;
63 static char **output_names
;
64 static char *makefile
;
66 static void maybe_unlink_file (const char *);
68 /* Delete tempfiles. */
71 lto_wrapper_cleanup (void)
73 static bool cleanup_done
= false;
79 /* Setting cleanup_done prevents an infinite loop if one of the
80 calls to maybe_unlink_file fails. */
83 if (ltrans_output_file
)
84 maybe_unlink_file (ltrans_output_file
);
86 maybe_unlink_file (flto_out
);
88 maybe_unlink_file (args_name
);
90 maybe_unlink_file (makefile
);
91 for (i
= 0; i
< nr
; ++i
)
93 maybe_unlink_file (input_names
[i
]);
95 maybe_unlink_file (output_names
[i
]);
100 fatal_signal (int signum
)
102 signal (signum
, SIG_DFL
);
103 lto_wrapper_cleanup ();
104 /* Get the same signal again, this time not handled,
105 so its normal effect occurs. */
106 kill (getpid (), signum
);
109 /* Just die. CMSGID is the error message. */
111 static void __attribute__ ((format (printf
, 1, 2)))
112 fatal (const char * cmsgid
, ...)
116 va_start (ap
, cmsgid
);
117 fprintf (stderr
, "lto-wrapper: ");
118 vfprintf (stderr
, _(cmsgid
), ap
);
119 fprintf (stderr
, "\n");
122 lto_wrapper_cleanup ();
123 exit (FATAL_EXIT_CODE
);
127 /* Die when sys call fails. CMSGID is the error message. */
129 static void __attribute__ ((format (printf
, 1, 2)))
130 fatal_perror (const char *cmsgid
, ...)
135 va_start (ap
, cmsgid
);
136 fprintf (stderr
, "lto-wrapper: ");
137 vfprintf (stderr
, _(cmsgid
), ap
);
138 fprintf (stderr
, ": %s\n", xstrerror (e
));
141 lto_wrapper_cleanup ();
142 exit (FATAL_EXIT_CODE
);
146 /* Execute a program, and wait for the reply. ARGV are the arguments. The
147 last one must be NULL. */
149 static struct pex_obj
*
150 collect_execute (char **argv
)
161 for (p_argv
= argv
; (str
= *p_argv
) != (char *) 0; p_argv
++)
162 fprintf (stderr
, " %s", str
);
164 fprintf (stderr
, "\n");
170 pex
= pex_init (0, "lto-wrapper", NULL
);
172 fatal_perror ("pex_init failed");
174 /* Do not use PEX_LAST here, we use our stdout for communicating with
175 collect2 or the linker-plugin. Any output from the sub-process
176 will confuse that. */
177 errmsg
= pex_run (pex
, PEX_SEARCH
, argv
[0], argv
, NULL
,
184 fatal_perror (errmsg
);
194 /* Wait for a process to finish, and exit if a nonzero status is found.
195 PROG is the program name. PEX is the process we should wait for. */
198 collect_wait (const char *prog
, struct pex_obj
*pex
)
202 if (!pex_get_status (pex
, 1, &status
))
203 fatal_perror ("can't get program status");
208 if (WIFSIGNALED (status
))
210 int sig
= WTERMSIG (status
);
211 if (WCOREDUMP (status
))
212 fatal ("%s terminated with signal %d [%s], core dumped",
213 prog
, sig
, strsignal (sig
));
215 fatal ("%s terminated with signal %d [%s]",
216 prog
, sig
, strsignal (sig
));
219 if (WIFEXITED (status
))
220 fatal ("%s returned %d exit status", prog
, WEXITSTATUS (status
));
227 /* Unlink a temporary LTRANS file unless requested otherwise. */
230 maybe_unlink_file (const char *file
)
234 if (unlink_if_ordinary (file
)
236 fatal_perror ("deleting LTRANS file %s", file
);
239 fprintf (stderr
, "[Leaving LTRANS %s]\n", file
);
243 /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */
246 fork_execute (char **argv
)
254 args_name
= make_temp_file (".args");
255 at_args
= concat ("@", args_name
, NULL
);
256 args
= fopen (args_name
, "w");
258 fatal ("failed to open %s", args_name
);
260 status
= writeargv (&argv
[1], args
);
263 fatal ("could not write to temporary file %s", args_name
);
267 new_argv
[0] = argv
[0];
268 new_argv
[1] = at_args
;
271 pex
= collect_execute (new_argv
);
272 collect_wait (new_argv
[0], pex
);
274 maybe_unlink_file (args_name
);
279 /* Template of LTRANS dumpbase suffix. */
280 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
282 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
285 run_gcc (unsigned argc
, char *argv
[])
288 const char **new_argv
;
289 const char **argv_ptr
;
290 char *list_option_full
= NULL
;
291 const char *linker_output
= NULL
;
292 const char *collect_gcc_options
, *collect_gcc
;
293 struct obstack env_obstack
;
297 bool no_partition
= false;
299 /* Get the driver and options. */
300 collect_gcc
= getenv ("COLLECT_GCC");
302 fatal ("environment variable COLLECT_GCC must be set");
304 /* Set the CFLAGS environment variable. */
305 collect_gcc_options
= getenv ("COLLECT_GCC_OPTIONS");
306 if (!collect_gcc_options
)
307 fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
309 /* Count arguments. */
311 for (j
= 0; collect_gcc_options
[j
] != '\0'; ++j
)
312 if (collect_gcc_options
[j
] == '\'')
316 fatal ("malformed COLLECT_GCC_OPTIONS");
318 /* Initalize the common arguments for the driver. */
319 new_argv
= (const char **) xmalloc ((15 + i
/ 2 + argc
) * sizeof (char *));
321 *argv_ptr
++ = collect_gcc
;
322 *argv_ptr
++ = "-xlto";
324 for (j
= 0; collect_gcc_options
[j
] != '\0'; ++j
)
325 if (collect_gcc_options
[j
] == '\'')
331 while (collect_gcc_options
[j
] != '\'')
334 obstack_init (&env_obstack
);
335 obstack_grow (&env_obstack
, &collect_gcc_options
[i
], j
- i
);
336 obstack_1grow (&env_obstack
, 0);
337 option
= XOBFINISH (&env_obstack
, char *);
340 linker_output
= option
;
345 /* If we see -o, skip it and skip and record its argument. */
346 if (option
[0] == '-' && option
[1] == 'o')
348 if (option
[2] == '\0')
351 linker_output
= &option
[2];
355 if (strcmp (option
, "-save-temps") == 0)
357 if (strcmp (option
, "-v") == 0)
360 if (strcmp (option
, "-flto-partition=none") == 0)
362 /* We've handled these LTO options, do not pass them on. */
363 if (strncmp (option
, "-flto=", 6) == 0
364 || !strcmp (option
, "-flto"))
366 lto_mode
= LTO_MODE_WHOPR
;
367 if (option
[5] == '=')
369 if (!strcmp (option
+ 6, "jobserver"))
376 parallel
= atoi (option
+ 6);
383 *argv_ptr
++ = option
;
387 lto_mode
= LTO_MODE_LTO
;
394 char *output_dir
, *base
, *name
;
396 output_dir
= xstrdup (linker_output
);
398 for (name
= base
; *name
; name
++)
399 if (IS_DIR_SEPARATOR (*name
))
403 linker_output
= &linker_output
[base
- output_dir
];
404 if (*output_dir
== '\0')
406 static char current_dir
[] = { '.', DIR_SEPARATOR
, '\0' };
407 output_dir
= current_dir
;
409 *argv_ptr
++ = "-dumpdir";
410 *argv_ptr
++ = output_dir
;
412 *argv_ptr
++ = "-dumpbase";
417 if (lto_mode
== LTO_MODE_LTO
)
419 flto_out
= make_temp_file (".lto.o");
421 argv_ptr
[0] = linker_output
;
423 argv_ptr
[2] = flto_out
;
425 else if (lto_mode
== LTO_MODE_WHOPR
)
427 const char *list_option
= "-fltrans-output-list=";
428 size_t list_option_len
= strlen (list_option
);
433 char *dumpbase
= (char *) xmalloc (strlen (linker_output
)
434 + sizeof (".wpa") + 1);
435 strcpy (dumpbase
, linker_output
);
436 strcat (dumpbase
, ".wpa");
437 argv_ptr
[0] = dumpbase
;
440 if (linker_output
&& debug
)
442 ltrans_output_file
= (char *) xmalloc (strlen (linker_output
)
443 + sizeof (".ltrans.out") + 1);
444 strcpy (ltrans_output_file
, linker_output
);
445 strcat (ltrans_output_file
, ".ltrans.out");
448 ltrans_output_file
= make_temp_file (".ltrans.out");
449 list_option_full
= (char *) xmalloc (sizeof (char) *
450 (strlen (ltrans_output_file
) + list_option_len
+ 1));
451 tmp
= list_option_full
;
454 strcpy (tmp
, list_option
);
455 tmp
+= list_option_len
;
456 strcpy (tmp
, ltrans_output_file
);
458 argv_ptr
[2] = "-fwpa";
461 fatal ("invalid LTO mode");
463 /* Append the input objects and possible preceeding arguments. */
464 for (i
= 1; i
< argc
; ++i
)
465 argv_ptr
[2 + i
] = argv
[i
];
466 argv_ptr
[2 + i
] = NULL
;
468 fork_execute (CONST_CAST (char **, new_argv
));
470 if (lto_mode
== LTO_MODE_LTO
)
472 printf("%s\n", flto_out
);
476 else if (lto_mode
== LTO_MODE_WHOPR
)
478 FILE *stream
= fopen (ltrans_output_file
, "r");
479 FILE *mstream
= NULL
;
482 fatal_perror ("fopen: %s", ltrans_output_file
);
484 /* Parse the list of LTRANS inputs from the WPA stage. */
488 const unsigned piece
= 32;
489 char *output_name
= NULL
;
490 char *buf
, *input_name
= (char *)xmalloc (piece
);
495 if (!fgets (buf
, piece
, stream
))
497 len
= strlen (input_name
);
498 if (input_name
[len
- 1] != '\n')
500 input_name
= (char *)xrealloc (input_name
, len
+ piece
);
501 buf
= input_name
+ len
;
504 input_name
[len
- 1] = '\0';
506 if (input_name
[0] == '*')
507 output_name
= &input_name
[1];
510 input_names
= (char **)xrealloc (input_names
, nr
* sizeof (char *));
511 output_names
= (char **)xrealloc (output_names
, nr
* sizeof (char *));
512 input_names
[nr
-1] = input_name
;
513 output_names
[nr
-1] = output_name
;
516 maybe_unlink_file (ltrans_output_file
);
517 ltrans_output_file
= NULL
;
521 makefile
= make_temp_file (".mk");
522 mstream
= fopen (makefile
, "w");
525 /* Execute the LTRANS stage for each input file (or prepare a
526 makefile to invoke this in parallel). */
527 for (i
= 0; i
< nr
; ++i
)
530 char *input_name
= input_names
[i
];
531 /* If it's a pass-through file do nothing. */
535 /* Replace the .o suffix with a .ltrans.o suffix and write
536 the resulting name to the LTRANS output list. */
537 obstack_init (&env_obstack
);
538 obstack_grow (&env_obstack
, input_name
, strlen (input_name
) - 2);
539 obstack_grow (&env_obstack
, ".ltrans.o", sizeof (".ltrans.o"));
540 output_name
= XOBFINISH (&env_obstack
, char *);
542 /* Adjust the dumpbase if the linker output file was seen. */
546 = (char *) xmalloc (strlen (linker_output
)
547 + sizeof(DUMPBASE_SUFFIX
) + 1);
549 strlen (linker_output
) + sizeof(DUMPBASE_SUFFIX
),
550 "%s.ltrans%u", linker_output
, i
);
551 argv_ptr
[0] = dumpbase
;
554 argv_ptr
[1] = "-fltrans";
556 argv_ptr
[3] = output_name
;
557 argv_ptr
[4] = input_name
;
561 fprintf (mstream
, "%s:\n\t@%s ", output_name
, new_argv
[0]);
562 for (j
= 1; new_argv
[j
] != NULL
; ++j
)
563 fprintf (mstream
, " '%s'", new_argv
[j
]);
564 fprintf (mstream
, "\n");
567 fork_execute (CONST_CAST (char **, new_argv
));
569 output_names
[i
] = output_name
;
576 fprintf (mstream
, "all:");
577 for (i
= 0; i
< nr
; ++i
)
578 fprintf (mstream
, " \\\n\t%s", output_names
[i
]);
579 fprintf (mstream
, "\n");
583 /* Avoid passing --jobserver-fd= and similar flags
584 unless jobserver mode is explicitly enabled. */
585 putenv (xstrdup ("MAKEFLAGS="));
586 putenv (xstrdup ("MFLAGS="));
588 new_argv
[0] = getenv ("MAKE");
590 new_argv
[0] = "make";
592 new_argv
[2] = makefile
;
596 snprintf (jobs
, 31, "-j%d", parallel
);
597 new_argv
[i
++] = jobs
;
599 new_argv
[i
++] = "all";
600 new_argv
[i
++] = NULL
;
601 pex
= collect_execute (CONST_CAST (char **, new_argv
));
602 collect_wait (new_argv
[0], pex
);
603 maybe_unlink_file (makefile
);
606 for (i
= 0; i
< nr
; ++i
)
608 fputs (output_names
[i
], stdout
);
610 maybe_unlink_file (input_names
[i
]);
611 free (input_names
[i
]);
616 free (list_option_full
);
619 fatal ("invalid LTO mode");
621 obstack_free (&env_obstack
, NULL
);
628 main (int argc
, char *argv
[])
632 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
633 signal (SIGINT
, fatal_signal
);
635 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
636 signal (SIGHUP
, fatal_signal
);
638 if (signal (SIGTERM
, SIG_IGN
) != SIG_IGN
)
639 signal (SIGTERM
, fatal_signal
);
641 if (signal (SIGPIPE
, SIG_IGN
) != SIG_IGN
)
642 signal (SIGPIPE
, fatal_signal
);
645 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
646 receive the signal. A different setting is inheritable */
647 signal (SIGCHLD
, SIG_DFL
);
650 /* We may be called with all the arguments stored in some file and
651 passed with @file. Expand them into argv before processing. */
652 expandargv (&argc
, &argv
);
653 run_gcc (argc
, argv
);