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 -fwhopr is used instead, more than one file might be produced
36 ./ccXj2DTk.lto.ltrans.o
37 ./ccCJuXGv.lto.ltrans.o
43 #include "coretypes.h"
46 #include "libiberty.h"
49 int debug
; /* true if -save-temps. */
50 int verbose
; /* true if -v. */
53 LTO_MODE_NONE
, /* Not doing LTO. */
54 LTO_MODE_LTO
, /* Normal LTO. */
55 LTO_MODE_WHOPR
/* WHOPR. */
58 /* Current LTO mode. */
59 static enum lto_mode_d lto_mode
= LTO_MODE_NONE
;
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
;
69 static void maybe_unlink_file (const char *);
71 /* Delete tempfiles and exit function. */
74 lto_wrapper_exit (int status
)
76 static bool cleanup_done
= false;
81 /* Setting cleanup_done prevents an infinite loop if one of the
82 calls to maybe_unlink_file fails. */
85 if (ltrans_output_file
)
86 maybe_unlink_file (ltrans_output_file
);
88 maybe_unlink_file (flto_out
);
90 maybe_unlink_file (args_name
);
92 maybe_unlink_file (makefile
);
93 for (i
= 0; i
< nr
; ++i
)
95 maybe_unlink_file (input_names
[i
]);
97 maybe_unlink_file (output_names
[i
]);
103 /* Just die. CMSGID is the error message. */
105 static void __attribute__ ((format (printf
, 1, 2)))
106 fatal (const char * cmsgid
, ...)
110 va_start (ap
, cmsgid
);
111 fprintf (stderr
, "lto-wrapper: ");
112 vfprintf (stderr
, _(cmsgid
), ap
);
113 fprintf (stderr
, "\n");
116 lto_wrapper_exit (FATAL_EXIT_CODE
);
120 /* Die when sys call fails. CMSGID is the error message. */
122 static void __attribute__ ((format (printf
, 1, 2)))
123 fatal_perror (const char *cmsgid
, ...)
128 va_start (ap
, cmsgid
);
129 fprintf (stderr
, "lto-wrapper: ");
130 vfprintf (stderr
, _(cmsgid
), ap
);
131 fprintf (stderr
, ": %s\n", xstrerror (e
));
134 lto_wrapper_exit (FATAL_EXIT_CODE
);
138 /* Execute a program, and wait for the reply. ARGV are the arguments. The
139 last one must be NULL. */
141 static struct pex_obj
*
142 collect_execute (char **argv
)
153 for (p_argv
= argv
; (str
= *p_argv
) != (char *) 0; p_argv
++)
154 fprintf (stderr
, " %s", str
);
156 fprintf (stderr
, "\n");
162 pex
= pex_init (0, "lto-wrapper", NULL
);
164 fatal_perror ("pex_init failed");
166 /* Do not use PEX_LAST here, we use our stdout for communicating with
167 collect2 or the linker-plugin. Any output from the sub-process
168 will confuse that. */
169 errmsg
= pex_run (pex
, PEX_SEARCH
, argv
[0], argv
, NULL
,
176 fatal_perror (errmsg
);
186 /* Wait for a process to finish, and exit if a nonzero status is found.
187 PROG is the program name. PEX is the process we should wait for. */
190 collect_wait (const char *prog
, struct pex_obj
*pex
)
194 if (!pex_get_status (pex
, 1, &status
))
195 fatal_perror ("can't get program status");
200 if (WIFSIGNALED (status
))
202 int sig
= WTERMSIG (status
);
203 if (WCOREDUMP (status
))
204 fatal ("%s terminated with signal %d [%s], core dumped",
205 prog
, sig
, strsignal (sig
));
207 fatal ("%s terminated with signal %d [%s]",
208 prog
, sig
, strsignal (sig
));
211 if (WIFEXITED (status
))
212 fatal ("%s returned %d exit status", prog
, WEXITSTATUS (status
));
219 /* Unlink a temporary LTRANS file unless requested otherwise. */
222 maybe_unlink_file (const char *file
)
226 if (unlink_if_ordinary (file
)
228 fatal_perror ("deleting LTRANS file %s", file
);
231 fprintf (stderr
, "[Leaving LTRANS %s]\n", file
);
235 /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */
238 fork_execute (char **argv
)
246 args_name
= make_temp_file (".args");
247 at_args
= concat ("@", args_name
, NULL
);
248 args
= fopen (args_name
, "w");
250 fatal ("failed to open %s", args_name
);
252 status
= writeargv (&argv
[1], args
);
255 fatal ("could not write to temporary file %s", args_name
);
259 new_argv
[0] = argv
[0];
260 new_argv
[1] = at_args
;
263 pex
= collect_execute (new_argv
);
264 collect_wait (new_argv
[0], pex
);
266 maybe_unlink_file (args_name
);
271 /* Template of LTRANS dumpbase suffix. */
272 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
274 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
277 run_gcc (unsigned argc
, char *argv
[])
280 const char **new_argv
;
281 const char **argv_ptr
;
282 char *list_option_full
= NULL
;
283 const char *linker_output
= NULL
;
284 const char *collect_gcc_options
, *collect_gcc
;
285 struct obstack env_obstack
;
289 /* Get the driver and options. */
290 collect_gcc
= getenv ("COLLECT_GCC");
292 fatal ("environment variable COLLECT_GCC must be set");
294 /* Set the CFLAGS environment variable. */
295 collect_gcc_options
= getenv ("COLLECT_GCC_OPTIONS");
296 if (!collect_gcc_options
)
297 fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
299 /* Count arguments. */
301 for (j
= 0; collect_gcc_options
[j
] != '\0'; ++j
)
302 if (collect_gcc_options
[j
] == '\'')
306 fatal ("malformed COLLECT_GCC_OPTIONS");
308 /* Initalize the common arguments for the driver. */
309 new_argv
= (const char **) xmalloc ((15 + i
/ 2 + argc
) * sizeof (char *));
311 *argv_ptr
++ = collect_gcc
;
312 *argv_ptr
++ = "-xlto";
314 for (j
= 0; collect_gcc_options
[j
] != '\0'; ++j
)
315 if (collect_gcc_options
[j
] == '\'')
321 while (collect_gcc_options
[j
] != '\'')
324 obstack_init (&env_obstack
);
325 obstack_grow (&env_obstack
, &collect_gcc_options
[i
], j
- i
);
326 obstack_1grow (&env_obstack
, 0);
327 option
= XOBFINISH (&env_obstack
, char *);
330 linker_output
= option
;
335 /* If we see -o, skip it and skip and record its argument. */
336 if (option
[0] == '-' && option
[1] == 'o')
338 if (option
[2] == '\0')
341 linker_output
= &option
[2];
345 if (strcmp (option
, "-save-temps") == 0)
347 if (strcmp (option
, "-v") == 0)
350 /* We've handled these LTO options, do not pass them on. */
351 if (strcmp (option
, "-flto") == 0)
352 lto_mode
= LTO_MODE_LTO
;
353 else if (strncmp (option
, "-fwhopr", 7) == 0)
355 lto_mode
= LTO_MODE_WHOPR
;
356 if (option
[7] == '=')
358 parallel
= atoi (option
+8);
364 *argv_ptr
++ = option
;
369 char *output_dir
, *base
, *name
;
371 output_dir
= xstrdup (linker_output
);
373 for (name
= base
; *name
; name
++)
374 if (IS_DIR_SEPARATOR (*name
))
378 linker_output
= &linker_output
[base
- output_dir
];
379 if (*output_dir
== '\0')
381 static char current_dir
[] = { '.', DIR_SEPARATOR
, '\0' };
382 output_dir
= current_dir
;
384 *argv_ptr
++ = "-dumpdir";
385 *argv_ptr
++ = output_dir
;
387 *argv_ptr
++ = "-dumpbase";
392 if (lto_mode
== LTO_MODE_LTO
)
394 flto_out
= make_temp_file (".lto.o");
396 argv_ptr
[0] = linker_output
;
398 argv_ptr
[2] = flto_out
;
399 argv_ptr
[3] = "-combine";
401 else if (lto_mode
== LTO_MODE_WHOPR
)
403 const char *list_option
= "-fltrans-output-list=";
404 size_t list_option_len
= strlen (list_option
);
409 char *dumpbase
= (char *) xmalloc (strlen (linker_output
)
410 + sizeof(".wpa") + 1);
411 strcpy (dumpbase
, linker_output
);
412 strcat (dumpbase
, ".wpa");
413 argv_ptr
[0] = dumpbase
;
416 ltrans_output_file
= make_temp_file (".ltrans.out");
417 list_option_full
= (char *) xmalloc (sizeof (char) *
418 (strlen (ltrans_output_file
) + list_option_len
+ 1));
419 tmp
= list_option_full
;
422 strcpy (tmp
, list_option
);
423 tmp
+= list_option_len
;
424 strcpy (tmp
, ltrans_output_file
);
426 argv_ptr
[2] = "-fwpa";
427 argv_ptr
[3] = "-combine";
430 fatal ("invalid LTO mode");
432 /* Append the input objects and possible preceeding arguments. */
433 for (i
= 1; i
< argc
; ++i
)
434 argv_ptr
[3 + i
] = argv
[i
];
435 argv_ptr
[3 + i
] = NULL
;
437 fork_execute (CONST_CAST (char **, new_argv
));
439 if (lto_mode
== LTO_MODE_LTO
)
441 printf("%s\n", flto_out
);
445 else if (lto_mode
== LTO_MODE_WHOPR
)
447 FILE *stream
= fopen (ltrans_output_file
, "r");
448 FILE *mstream
= NULL
;
451 fatal_perror ("fopen: %s", ltrans_output_file
);
453 /* Parse the list of LTRANS inputs from the WPA stage. */
457 const unsigned piece
= 32;
458 char *output_name
= NULL
;
459 char *buf
, *input_name
= (char *)xmalloc (piece
);
464 if (!fgets (buf
, piece
, stream
))
466 len
= strlen (input_name
);
467 if (input_name
[len
- 1] != '\n')
469 input_name
= (char *)xrealloc (input_name
, len
+ piece
);
470 buf
= input_name
+ len
;
473 input_name
[len
- 1] = '\0';
475 if (input_name
[0] == '*')
476 output_name
= &input_name
[1];
479 input_names
= (char **)xrealloc (input_names
, nr
* sizeof (char *));
480 output_names
= (char **)xrealloc (output_names
, nr
* sizeof (char *));
481 input_names
[nr
-1] = input_name
;
482 output_names
[nr
-1] = output_name
;
485 maybe_unlink_file (ltrans_output_file
);
486 ltrans_output_file
= NULL
;
490 makefile
= make_temp_file (".mk");
491 mstream
= fopen (makefile
, "w");
494 /* Execute the LTRANS stage for each input file (or prepare a
495 makefile to invoke this in parallel). */
496 for (i
= 0; i
< nr
; ++i
)
499 char *input_name
= input_names
[i
];
500 /* If it's a pass-through file do nothing. */
504 /* Replace the .o suffix with a .ltrans.o suffix and write
505 the resulting name to the LTRANS output list. */
506 obstack_init (&env_obstack
);
507 obstack_grow (&env_obstack
, input_name
, strlen (input_name
) - 2);
508 obstack_grow (&env_obstack
, ".ltrans.o", sizeof (".ltrans.o"));
509 output_name
= XOBFINISH (&env_obstack
, char *);
511 /* Adjust the dumpbase if the linker output file was seen. */
515 = (char *) xmalloc (strlen (linker_output
)
516 + sizeof(DUMPBASE_SUFFIX
) + 1);
518 strlen (linker_output
) + sizeof(DUMPBASE_SUFFIX
),
519 "%s.ltrans%u", linker_output
, nr
);
520 argv_ptr
[0] = dumpbase
;
523 argv_ptr
[1] = "-fltrans";
525 argv_ptr
[3] = output_name
;
526 argv_ptr
[4] = input_name
;
530 fprintf (mstream
, "%s:\n\t@%s ", output_name
, new_argv
[0]);
531 for (j
= 1; new_argv
[j
] != NULL
; ++j
)
532 fprintf (mstream
, " '%s'", new_argv
[j
]);
533 fprintf (mstream
, "\n");
536 fork_execute (CONST_CAST (char **, new_argv
));
538 output_names
[i
] = output_name
;
544 fprintf (mstream
, "all:");
545 for (i
= 0; i
< nr
; ++i
)
546 fprintf (mstream
, " \\\n\t%s", output_names
[i
]);
547 fprintf (mstream
, "\n");
549 /* Avoid passing --jobserver-fd= and similar flags. */
550 putenv (xstrdup ("MAKEFLAGS="));
551 putenv (xstrdup ("MFLAGS="));
552 new_argv
[0] = getenv ("MAKE");
554 new_argv
[0] = "make";
556 new_argv
[2] = makefile
;
557 snprintf (jobs
, 31, "-j%d", parallel
);
561 pex
= collect_execute (CONST_CAST (char **, new_argv
));
562 collect_wait (new_argv
[0], pex
);
563 maybe_unlink_file (makefile
);
566 for (i
= 0; i
< nr
; ++i
)
568 fputs (output_names
[i
], stdout
);
570 maybe_unlink_file (input_names
[i
]);
571 free (input_names
[i
]);
576 free (list_option_full
);
579 fatal ("invalid LTO mode");
581 obstack_free (&env_obstack
, NULL
);
588 main (int argc
, char *argv
[])
592 /* We may be called with all the arguments stored in some file and
593 passed with @file. Expand them into argv before processing. */
594 expandargv (&argc
, &argv
);
595 run_gcc (argc
, argv
);