1/* Wrapper to call lto. Used by collect2 and the linker plugin.
2 Copyright (C) 2009-2023 Free Software Foundation, Inc.
3
4 Factored out of collect2 by Rafael Espindola <espindola@google.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along 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#define INCLUDE_STRING
41#include "config.h"
42#include "system.h"
43#include "coretypes.h"
44#include "intl.h"
45#include "diagnostic.h"
46#include "obstack.h"
47#include "opts.h"
48#include "options.h"
49#include "simple-object.h"
50#include "lto-section-names.h"
51#include "collect-utils.h"
52#include "opts-diagnostic.h"
53#include "opt-suggestions.h"
54#include "opts-jobserver.h"
55
56/* Environment variable, used for passing the names of offload targets from GCC
57 driver to lto-wrapper. */
58#define OFFLOAD_TARGET_NAMES_ENV "OFFLOAD_TARGET_NAMES"
59#define OFFLOAD_TARGET_DEFAULT_ENV "OFFLOAD_TARGET_DEFAULT"
60
61/* By default there is no special suffix for target executables. */
62#ifdef TARGET_EXECUTABLE_SUFFIX
63#define HAVE_TARGET_EXECUTABLE_SUFFIX
64#else
65#define TARGET_EXECUTABLE_SUFFIX ""
66#endif
67
68enum lto_mode_d {
69 LTO_MODE_NONE, /* Not doing LTO. */
70 LTO_MODE_LTO, /* Normal LTO. */
71 LTO_MODE_WHOPR /* WHOPR. */
72};
73
74/* Current LTO mode. */
75static enum lto_mode_d lto_mode = LTO_MODE_NONE;
76
77static char *ltrans_output_file;
78static char *flto_out;
79static unsigned int nr;
80static int *ltrans_priorities;
81static char **input_names;
82static char **output_names;
83static char **offload_names;
84static char *offload_objects_file_name;
85static char *makefile;
86static unsigned int num_deb_objs;
87static const char **early_debug_object_names;
88static bool xassembler_options_error = false;
89
90const char tool_name[] = "lto-wrapper";
91
92/* Auxiliary function that frees elements of PTR and PTR itself.
93 N is number of elements to be freed. If PTR is NULL, nothing is freed.
94 If an element is NULL, subsequent elements are not freed. */
95
96static void **
97free_array_of_ptrs (void **ptr, unsigned n)
98{
99 if (!ptr)
100 return NULL;
101 for (unsigned i = 0; i < n; i++)
102 {
103 if (!ptr[i])
104 break;
105 free (ptr: ptr[i]);
106 }
107 free (ptr: ptr);
108 return NULL;
109}
110
111/* Delete tempfiles. Called from utils_cleanup. */
112
113void
114tool_cleanup (bool)
115{
116 unsigned int i;
117
118 if (ltrans_output_file)
119 maybe_unlink (ltrans_output_file);
120 if (flto_out)
121 maybe_unlink (flto_out);
122 if (offload_objects_file_name)
123 maybe_unlink (offload_objects_file_name);
124 if (makefile)
125 maybe_unlink (makefile);
126 if (early_debug_object_names)
127 for (i = 0; i < num_deb_objs; ++i)
128 if (early_debug_object_names[i])
129 maybe_unlink (early_debug_object_names[i]);
130 for (i = 0; i < nr; ++i)
131 {
132 maybe_unlink (input_names[i]);
133 if (output_names[i])
134 maybe_unlink (output_names[i]);
135 }
136 if (offload_names)
137 {
138 for (i = 0; offload_names[i]; i++)
139 maybe_unlink (offload_names[i]);
140 free_array_of_ptrs (ptr: (void **) offload_names, n: i);
141 }
142}
143
144static void
145lto_wrapper_cleanup (void)
146{
147 utils_cleanup (false);
148}
149
150/* Unlink a temporary LTRANS file unless requested otherwise. */
151
152void
153maybe_unlink (const char *file)
154{
155 if (!save_temps)
156 {
157 if (unlink_if_ordinary (file)
158 && errno != ENOENT)
159 fatal_error (input_location, "deleting LTRANS file %s: %m", file);
160 }
161 else if (verbose)
162 fprintf (stderr, format: "[Leaving LTRANS %s]\n", file);
163}
164
165/* Template of LTRANS dumpbase suffix. */
166#define DUMPBASE_SUFFIX "ltrans18446744073709551615"
167
168/* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
169 environment. */
170
171static vec<cl_decoded_option>
172get_options_from_collect_gcc_options (const char *collect_gcc,
173 const char *collect_gcc_options)
174{
175 cl_decoded_option *decoded_options;
176 unsigned int decoded_options_count;
177 struct obstack argv_obstack;
178 const char **argv;
179 int argc;
180
181 obstack_init (&argv_obstack);
182 obstack_ptr_grow (&argv_obstack, collect_gcc);
183
184 parse_options_from_collect_gcc_options (collect_gcc_options,
185 &argv_obstack, &argc);
186 argv = XOBFINISH (&argv_obstack, const char **);
187
188 decode_cmdline_options_to_array (argc, argv: (const char **)argv, CL_DRIVER,
189 decoded_options: &decoded_options, decoded_options_count: &decoded_options_count);
190 vec<cl_decoded_option> decoded;
191 decoded.create (nelems: decoded_options_count);
192 for (unsigned i = 0; i < decoded_options_count; ++i)
193 decoded.quick_push (obj: decoded_options[i]);
194 free (ptr: decoded_options);
195
196 obstack_free (&argv_obstack, NULL);
197
198 return decoded;
199}
200
201/* Find option in OPTIONS based on OPT_INDEX, starting at START. -1
202 value is returned if the option is not present. */
203
204static int
205find_option (vec<cl_decoded_option> &options, size_t opt_index,
206 unsigned start = 0)
207{
208 for (unsigned i = start; i < options.length (); ++i)
209 if (options[i].opt_index == opt_index)
210 return i;
211
212 return -1;
213}
214
215static int
216find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
217{
218 return find_option (options, opt_index: option->opt_index);
219}
220
221/* Merge -flto FOPTION into vector of DECODED_OPTIONS. */
222
223static void
224merge_flto_options (vec<cl_decoded_option> &decoded_options,
225 cl_decoded_option *foption)
226{
227 int existing_opt = find_option (options&: decoded_options, option: foption);
228 if (existing_opt == -1)
229 decoded_options.safe_push (obj: *foption);
230 else
231 {
232 if (strcmp (s1: foption->arg, s2: decoded_options[existing_opt].arg) != 0)
233 {
234 /* -flto=auto is preferred. */
235 if (strcmp (s1: decoded_options[existing_opt].arg, s2: "auto") == 0)
236 ;
237 else if (strcmp (s1: foption->arg, s2: "auto") == 0
238 || strcmp (s1: foption->arg, s2: "jobserver") == 0)
239 decoded_options[existing_opt].arg = foption->arg;
240 else if (strcmp (s1: decoded_options[existing_opt].arg,
241 s2: "jobserver") != 0)
242 {
243 int n = atoi (nptr: foption->arg);
244 int original_n = atoi (nptr: decoded_options[existing_opt].arg);
245 if (n > original_n)
246 decoded_options[existing_opt].arg = foption->arg;
247 }
248 }
249 }
250}
251
252/* Try to merge and complain about options FDECODED_OPTIONS when applied
253 ontop of DECODED_OPTIONS. */
254
255static void
256merge_and_complain (vec<cl_decoded_option> &decoded_options,
257 vec<cl_decoded_option> fdecoded_options,
258 vec<cl_decoded_option> decoded_cl_options)
259{
260 unsigned int i, j;
261 cl_decoded_option *pic_option = NULL;
262 cl_decoded_option *pie_option = NULL;
263 cl_decoded_option *cf_protection_option = NULL;
264
265 /* ??? Merge options from files. Most cases can be
266 handled by either unioning or intersecting
267 (for example -fwrapv is a case for unioning,
268 -ffast-math is for intersection). Most complaints
269 about real conflicts between different options can
270 be deferred to the compiler proper. Options that
271 we can neither safely handle by intersection nor
272 unioning would need to be complained about here.
273 Ideally we'd have a flag in the opt files that
274 tells whether to union or intersect or reject.
275 In absence of that it's unclear what a good default is.
276 It's also difficult to get positional handling correct. */
277
278 /* Look for a -fcf-protection option in the link-time options
279 which overrides any -fcf-protection from the lto sections. */
280 for (i = 0; i < decoded_cl_options.length (); ++i)
281 {
282 cl_decoded_option *foption = &decoded_cl_options[i];
283 if (foption->opt_index == OPT_fcf_protection_)
284 {
285 cf_protection_option = foption;
286 }
287 }
288
289 /* The following does what the old LTO option code did,
290 union all target and a selected set of common options. */
291 for (i = 0; i < fdecoded_options.length (); ++i)
292 {
293 cl_decoded_option *foption = &fdecoded_options[i];
294 int existing_opt = find_option (options&: decoded_options, option: foption);
295 switch (foption->opt_index)
296 {
297 case OPT_SPECIAL_unknown:
298 case OPT_SPECIAL_ignore:
299 case OPT_SPECIAL_warn_removed:
300 case OPT_SPECIAL_program_name:
301 case OPT_SPECIAL_input_file:
302 break;
303
304 default:
305 if (!(cl_options[foption->opt_index].flags & CL_TARGET))
306 break;
307
308 /* Fallthru. */
309 case OPT_fdiagnostics_show_caret:
310 case OPT_fdiagnostics_show_labels:
311 case OPT_fdiagnostics_show_line_numbers:
312 case OPT_fdiagnostics_show_option:
313 case OPT_fdiagnostics_show_location_:
314 case OPT_fshow_column:
315 case OPT_fcommon:
316 case OPT_fgnu_tm:
317 case OPT_g:
318 /* Do what the old LTO code did - collect exactly one option
319 setting per OPT code, we pick the first we encounter.
320 ??? This doesn't make too much sense, but when it doesn't
321 then we should complain. */
322 if (existing_opt == -1)
323 decoded_options.safe_push (obj: *foption);
324 break;
325
326 /* Figure out what PIC/PIE level wins and merge the results. */
327 case OPT_fPIC:
328 case OPT_fpic:
329 pic_option = foption;
330 break;
331 case OPT_fPIE:
332 case OPT_fpie:
333 pie_option = foption;
334 break;
335
336 case OPT_fopenmp:
337 case OPT_fopenacc:
338 case OPT_fasynchronous_unwind_tables:
339 case OPT_funwind_tables:
340 /* For selected options we can merge conservatively. */
341 if (existing_opt == -1)
342 decoded_options.safe_push (obj: *foption);
343 /* -fopenmp > -fno-openmp,
344 -fopenacc > -fno-openacc */
345 else if (foption->value > decoded_options[existing_opt].value)
346 decoded_options[existing_opt] = *foption;
347 break;
348
349 case OPT_fopenacc_dim_:
350 /* Append or check identical. */
351 if (existing_opt == -1)
352 decoded_options.safe_push (obj: *foption);
353 else if (strcmp (s1: decoded_options[existing_opt].arg, s2: foption->arg))
354 fatal_error (input_location,
355 "option %s with different values",
356 foption->orig_option_with_args_text);
357 break;
358
359 case OPT_fcf_protection_:
360 /* Default to link-time option, else append or check identical. */
361 if (!cf_protection_option
362 || cf_protection_option->value == CF_CHECK)
363 {
364 if (existing_opt == -1)
365 decoded_options.safe_push (obj: *foption);
366 else if (decoded_options[existing_opt].value != foption->value)
367 {
368 if (cf_protection_option
369 && cf_protection_option->value == CF_CHECK)
370 fatal_error (input_location,
371 "option %qs with mismatching values"
372 " (%s, %s)",
373 "-fcf-protection",
374 decoded_options[existing_opt].arg,
375 foption->arg);
376 else
377 {
378 /* Merge and update the -fcf-protection option. */
379 decoded_options[existing_opt].value
380 &= (foption->value & CF_FULL);
381 switch (decoded_options[existing_opt].value)
382 {
383 case CF_NONE:
384 decoded_options[existing_opt].arg = "none";
385 break;
386 case CF_BRANCH:
387 decoded_options[existing_opt].arg = "branch";
388 break;
389 case CF_RETURN:
390 decoded_options[existing_opt].arg = "return";
391 break;
392 default:
393 gcc_unreachable ();
394 }
395 }
396 }
397 }
398 break;
399
400 case OPT_O:
401 case OPT_Ofast:
402 case OPT_Og:
403 case OPT_Os:
404 case OPT_Oz:
405 existing_opt = -1;
406 for (j = 0; j < decoded_options.length (); ++j)
407 if (decoded_options[j].opt_index == OPT_O
408 || decoded_options[j].opt_index == OPT_Ofast
409 || decoded_options[j].opt_index == OPT_Og
410 || decoded_options[j].opt_index == OPT_Os
411 || decoded_options[j].opt_index == OPT_Oz)
412 {
413 existing_opt = j;
414 break;
415 }
416 if (existing_opt == -1)
417 decoded_options.safe_push (obj: *foption);
418 else if (decoded_options[existing_opt].opt_index == foption->opt_index
419 && foption->opt_index != OPT_O)
420 /* Exact same options get merged. */
421 ;
422 else
423 {
424 /* For mismatched option kinds preserve the optimization
425 level only, thus merge it as -On. This also handles
426 merging of same optimization level -On. */
427 int level = 0;
428 switch (foption->opt_index)
429 {
430 case OPT_O:
431 if (foption->arg[0] == '\0')
432 level = MAX (level, 1);
433 else
434 level = MAX (level, atoi (foption->arg));
435 break;
436 case OPT_Ofast:
437 level = MAX (level, 3);
438 break;
439 case OPT_Og:
440 level = MAX (level, 1);
441 break;
442 case OPT_Os:
443 case OPT_Oz:
444 level = MAX (level, 2);
445 break;
446 default:
447 gcc_unreachable ();
448 }
449 switch (decoded_options[existing_opt].opt_index)
450 {
451 case OPT_O:
452 if (decoded_options[existing_opt].arg[0] == '\0')
453 level = MAX (level, 1);
454 else
455 level = MAX (level,
456 atoi (decoded_options[existing_opt].arg));
457 break;
458 case OPT_Ofast:
459 level = MAX (level, 3);
460 break;
461 case OPT_Og:
462 level = MAX (level, 1);
463 break;
464 case OPT_Os:
465 case OPT_Oz:
466 level = MAX (level, 2);
467 break;
468 default:
469 gcc_unreachable ();
470 }
471 decoded_options[existing_opt].opt_index = OPT_O;
472 char *tem;
473 tem = xasprintf ("-O%d", level);
474 decoded_options[existing_opt].arg = &tem[2];
475 decoded_options[existing_opt].canonical_option[0] = tem;
476 decoded_options[existing_opt].value = 1;
477 }
478 break;
479
480
481 case OPT_foffload_abi_:
482 if (existing_opt == -1)
483 decoded_options.safe_push (obj: *foption);
484 else if (foption->value != decoded_options[existing_opt].value)
485 fatal_error (input_location,
486 "option %s not used consistently in all LTO input"
487 " files", foption->orig_option_with_args_text);
488 break;
489
490
491 case OPT_foffload_options_:
492 decoded_options.safe_push (obj: *foption);
493 break;
494
495 case OPT_flto_:
496 merge_flto_options (decoded_options, foption);
497 break;
498 }
499 }
500
501 /* Merge PIC options:
502 -fPIC + -fpic = -fpic
503 -fPIC + -fno-pic = -fno-pic
504 -fpic/-fPIC + nothing = nothing.
505 It is a common mistake to mix few -fPIC compiled objects into otherwise
506 non-PIC code. We do not want to build everything with PIC then.
507
508 Similarly we merge PIE options, however in addition we keep
509 -fPIC + -fPIE = -fPIE
510 -fpic + -fPIE = -fpie
511 -fPIC/-fpic + -fpie = -fpie
512
513 It would be good to warn on mismatches, but it is bit hard to do as
514 we do not know what nothing translates to. */
515
516 for (unsigned int j = 0; j < decoded_options.length ();)
517 if (decoded_options[j].opt_index == OPT_fPIC
518 || decoded_options[j].opt_index == OPT_fpic)
519 {
520 /* -fno-pic in one unit implies -fno-pic everywhere. */
521 if (decoded_options[j].value == 0)
522 j++;
523 /* If we have no pic option or merge in -fno-pic, we still may turn
524 existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
525 else if ((pic_option && pic_option->value == 0)
526 || !pic_option)
527 {
528 if (pie_option)
529 {
530 bool big = decoded_options[j].opt_index == OPT_fPIC
531 && pie_option->opt_index == OPT_fPIE;
532 decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
533 if (pie_option->value)
534 decoded_options[j].canonical_option[0]
535 = big ? "-fPIE" : "-fpie";
536 else
537 decoded_options[j].canonical_option[0] = "-fno-pie";
538 decoded_options[j].value = pie_option->value;
539 j++;
540 }
541 else if (pic_option)
542 {
543 decoded_options[j] = *pic_option;
544 j++;
545 }
546 /* We do not know if target defaults to pic or not, so just remove
547 option if it is missing in one unit but enabled in other. */
548 else
549 decoded_options.ordered_remove (ix: j);
550 }
551 else if (pic_option->opt_index == OPT_fpic
552 && decoded_options[j].opt_index == OPT_fPIC)
553 {
554 decoded_options[j] = *pic_option;
555 j++;
556 }
557 else
558 j++;
559 }
560 else if (decoded_options[j].opt_index == OPT_fPIE
561 || decoded_options[j].opt_index == OPT_fpie)
562 {
563 /* -fno-pie in one unit implies -fno-pie everywhere. */
564 if (decoded_options[j].value == 0)
565 j++;
566 /* If we have no pie option or merge in -fno-pie, we still preserve
567 PIE/pie if pic/PIC is present. */
568 else if ((pie_option && pie_option->value == 0)
569 || !pie_option)
570 {
571 /* If -fPIC/-fpic is given, merge it with -fPIE/-fpie. */
572 if (pic_option)
573 {
574 if (pic_option->opt_index == OPT_fpic
575 && decoded_options[j].opt_index == OPT_fPIE)
576 {
577 decoded_options[j].opt_index = OPT_fpie;
578 decoded_options[j].canonical_option[0]
579 = pic_option->value ? "-fpie" : "-fno-pie";
580 }
581 else if (!pic_option->value)
582 decoded_options[j].canonical_option[0] = "-fno-pie";
583 decoded_options[j].value = pic_option->value;
584 j++;
585 }
586 else if (pie_option)
587 {
588 decoded_options[j] = *pie_option;
589 j++;
590 }
591 /* Because we always append pic/PIE options this code path should
592 not happen unless the LTO object was built by old lto1 which
593 did not contain that logic yet. */
594 else
595 decoded_options.ordered_remove (ix: j);
596 }
597 else if (pie_option->opt_index == OPT_fpie
598 && decoded_options[j].opt_index == OPT_fPIE)
599 {
600 decoded_options[j] = *pie_option;
601 j++;
602 }
603 else
604 j++;
605 }
606 else
607 j++;
608
609 int existing_opt_index, existing_opt2_index;
610 if (!xassembler_options_error)
611 for (existing_opt_index = existing_opt2_index = 0; ;
612 existing_opt_index++, existing_opt2_index++)
613 {
614 existing_opt_index
615 = find_option (options&: decoded_options, opt_index: OPT_Xassembler, start: existing_opt_index);
616 existing_opt2_index
617 = find_option (options&: fdecoded_options, opt_index: OPT_Xassembler,
618 start: existing_opt2_index);
619
620 cl_decoded_option *existing_opt = NULL;
621 cl_decoded_option *existing_opt2 = NULL;
622 if (existing_opt_index != -1)
623 existing_opt = &decoded_options[existing_opt_index];
624 if (existing_opt2_index != -1)
625 existing_opt2 = &fdecoded_options[existing_opt2_index];
626
627 if (existing_opt == NULL && existing_opt2 == NULL)
628 break;
629 else if (existing_opt != NULL && existing_opt2 == NULL)
630 {
631 warning (0, "Extra option to %<-Xassembler%>: %s,"
632 " dropping all %<-Xassembler%> and %<-Wa%> options.",
633 existing_opt->arg);
634 xassembler_options_error = true;
635 break;
636 }
637 else if (existing_opt == NULL && existing_opt2 != NULL)
638 {
639 warning (0, "Extra option to %<-Xassembler%>: %s,"
640 " dropping all %<-Xassembler%> and %<-Wa%> options.",
641 existing_opt2->arg);
642 xassembler_options_error = true;
643 break;
644 }
645 else if (strcmp (s1: existing_opt->arg, s2: existing_opt2->arg) != 0)
646 {
647 warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
648 " dropping all %<-Xassembler%> and %<-Wa%> options.",
649 existing_opt->arg, existing_opt2->arg);
650 xassembler_options_error = true;
651 break;
652 }
653 }
654}
655
656/* Parse STR, saving found tokens into PVALUES and return their number.
657 Tokens are assumed to be delimited by ':'. If APPEND is non-null,
658 append it to every token we find. */
659
660static unsigned
661parse_env_var (const char *str, char ***pvalues, const char *append)
662{
663 const char *curval, *nextval;
664 char **values;
665 unsigned num = 1, i;
666
667 curval = strchr (s: str, c: ':');
668 while (curval)
669 {
670 num++;
671 curval = strchr (s: curval + 1, c: ':');
672 }
673
674 values = (char**) xmalloc (num * sizeof (char*));
675 curval = str;
676 nextval = strchr (s: curval, c: ':');
677 if (nextval == NULL)
678 nextval = strchr (s: curval, c: '\0');
679
680 int append_len = append ? strlen (s: append) : 0;
681 for (i = 0; i < num; i++)
682 {
683 int l = nextval - curval;
684 values[i] = (char*) xmalloc (l + 1 + append_len);
685 memcpy (dest: values[i], src: curval, n: l);
686 values[i][l] = 0;
687 if (append)
688 strcat (dest: values[i], src: append);
689 curval = nextval + 1;
690 nextval = strchr (s: curval, c: ':');
691 if (nextval == NULL)
692 nextval = strchr (s: curval, c: '\0');
693 }
694 *pvalues = values;
695 return num;
696}
697
698/* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK. */
699
700static void
701append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
702{
703 /* Append compiler driver arguments as far as they were merged. */
704 for (unsigned int j = 1; j < opts.length (); ++j)
705 {
706 cl_decoded_option *option = &opts[j];
707
708 /* File options have been properly filtered by lto-opts.cc. */
709 switch (option->opt_index)
710 {
711 /* Drop arguments that we want to take from the link line. */
712 case OPT_flto_:
713 case OPT_flto:
714 case OPT_flto_partition_:
715 continue;
716
717 default:
718 break;
719 }
720
721 /* For now do what the original LTO option code was doing - pass
722 on any CL_TARGET flag and a few selected others. */
723 switch (option->opt_index)
724 {
725 case OPT_fdiagnostics_show_caret:
726 case OPT_fdiagnostics_show_labels:
727 case OPT_fdiagnostics_show_line_numbers:
728 case OPT_fdiagnostics_show_option:
729 case OPT_fdiagnostics_show_location_:
730 case OPT_fshow_column:
731 case OPT_fPIC:
732 case OPT_fpic:
733 case OPT_fPIE:
734 case OPT_fpie:
735 case OPT_fcommon:
736 case OPT_fgnu_tm:
737 case OPT_fopenmp:
738 case OPT_fopenacc:
739 case OPT_fopenacc_dim_:
740 case OPT_foffload_abi_:
741 case OPT_fcf_protection_:
742 case OPT_fasynchronous_unwind_tables:
743 case OPT_funwind_tables:
744 case OPT_g:
745 case OPT_O:
746 case OPT_Ofast:
747 case OPT_Og:
748 case OPT_Os:
749 case OPT_Oz:
750 break;
751
752 case OPT_Xassembler:
753 /* When we detected a mismatch in assembler options between
754 the input TU's fall back to previous behavior of ignoring them. */
755 if (xassembler_options_error)
756 continue;
757 break;
758
759 default:
760 if (!(cl_options[option->opt_index].flags & CL_TARGET))
761 continue;
762 }
763
764 /* Pass the option on. */
765 for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
766 obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
767 }
768}
769
770/* Append diag options in OPTS to ARGV_OBSTACK. */
771
772static void
773append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
774{
775 /* Append compiler driver arguments as far as they were merged. */
776 for (unsigned int j = 1; j < opts.length (); ++j)
777 {
778 cl_decoded_option *option = &opts[j];
779
780 switch (option->opt_index)
781 {
782 case OPT_fdiagnostics_color_:
783 case OPT_fdiagnostics_format_:
784 case OPT_fdiagnostics_show_caret:
785 case OPT_fdiagnostics_show_labels:
786 case OPT_fdiagnostics_show_line_numbers:
787 case OPT_fdiagnostics_show_option:
788 case OPT_fdiagnostics_show_location_:
789 case OPT_fshow_column:
790 break;
791 default:
792 continue;
793 }
794
795 /* Pass the option on. */
796 for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
797 obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
798 }
799}
800
801
802/* Append linker options OPTS to ARGV_OBSTACK. */
803
804static void
805append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
806{
807 /* Append linker driver arguments. Compiler options from the linker
808 driver arguments will override / merge with those from the compiler. */
809 for (unsigned int j = 1; j < opts.length (); ++j)
810 {
811 cl_decoded_option *option = &opts[j];
812
813 /* Do not pass on frontend specific flags not suitable for lto. */
814 if (!(cl_options[option->opt_index].flags
815 & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
816 continue;
817
818 switch (option->opt_index)
819 {
820 case OPT_o:
821 case OPT_flto_:
822 case OPT_flto:
823 /* We've handled these LTO options, do not pass them on. */
824 continue;
825
826 case OPT_fopenmp:
827 case OPT_fopenacc:
828 /* Ignore -fno-XXX form of these options, as otherwise
829 corresponding builtins will not be enabled. */
830 if (option->value == 0)
831 continue;
832 break;
833
834 default:
835 break;
836 }
837
838 /* Pass the option on. */
839 for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
840 obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
841 }
842}
843
844/* Extract options for TARGET offload compiler from OPTIONS and append
845 them to ARGV_OBSTACK. */
846
847static void
848append_offload_options (obstack *argv_obstack, const char *target,
849 vec<cl_decoded_option> options)
850{
851 for (unsigned i = 0; i < options.length (); i++)
852 {
853 const char *cur, *next, *opts;
854 char **argv;
855 unsigned argc;
856 cl_decoded_option *option = &options[i];
857
858 if (option->opt_index != OPT_foffload_options_)
859 continue;
860
861 /* If option argument starts with '-' then no target is specified. That
862 means offload options are specified for all targets, so we need to
863 append them. */
864 if (option->arg[0] == '-')
865 opts = option->arg;
866 else
867 {
868 opts = strchr (s: option->arg, c: '=');
869 gcc_assert (opts);
870 cur = option->arg;
871
872 while (cur < opts)
873 {
874 next = strchr (s: cur, c: ',');
875 if (next == NULL)
876 next = opts;
877 next = (next > opts) ? opts : next;
878
879 /* Are we looking for this offload target? */
880 if (strlen (s: target) == (size_t) (next - cur)
881 && strncmp (s1: target, s2: cur, n: next - cur) == 0)
882 break;
883
884 /* Skip the comma or equal sign. */
885 cur = next + 1;
886 }
887
888 if (cur >= opts)
889 continue;
890
891 opts++;
892 }
893
894 argv = buildargv (opts);
895 for (argc = 0; argv[argc]; argc++)
896 obstack_ptr_grow (argv_obstack, argv[argc]);
897 }
898}
899
900/* Check whether NAME can be accessed in MODE. This is like access,
901 except that it never considers directories to be executable. */
902
903static int
904access_check (const char *name, int mode)
905{
906 if (mode == X_OK)
907 {
908 struct stat st;
909
910 if (stat (file: name, buf: &st) < 0
911 || S_ISDIR (st.st_mode))
912 return -1;
913 }
914
915 return access (name: name, type: mode);
916}
917
918/* Prepare a target image for offload TARGET, using mkoffload tool from
919 COMPILER_PATH. Return the name of the resultant object file. */
920
921static const char *
922compile_offload_image (const char *target, const char *compiler_path,
923 unsigned in_argc, char *in_argv[],
924 vec<cl_decoded_option> compiler_opts,
925 vec<cl_decoded_option> linker_opts,
926 char **filename)
927{
928 char *dumpbase;
929 char **argv;
930 char *suffix
931 = XALLOCAVEC (char, sizeof ("/accel//mkoffload") + strlen (target));
932 strcpy (dest: suffix, src: "/accel/");
933 strcat (dest: suffix, src: target);
934 strcat (dest: suffix, src: "/mkoffload");
935 *filename = NULL;
936
937 char **paths = NULL;
938 unsigned n_paths = parse_env_var (str: compiler_path, pvalues: &paths, append: suffix);
939
940 const char *compiler = NULL;
941 for (unsigned i = 0; i < n_paths; i++)
942 if (access_check (name: paths[i], X_OK) == 0)
943 {
944 compiler = paths[i];
945 break;
946 }
947#if OFFLOAD_DEFAULTED
948 if (!compiler && getenv (OFFLOAD_TARGET_DEFAULT_ENV))
949 {
950 free_array_of_ptrs ((void **) paths, n_paths);
951 return NULL;
952 }
953#endif
954
955 if (!compiler)
956 fatal_error (input_location,
957 "could not find %s in %s (consider using %<-B%>)",
958 suffix + 1, compiler_path);
959
960 dumpbase = concat (dumppfx, "x", target, NULL);
961
962 /* Generate temporary output file name. */
963 if (save_temps)
964 *filename = concat (dumpbase, ".o", NULL);
965 else
966 *filename = make_temp_file (".target.o");
967
968 struct obstack argv_obstack;
969 obstack_init (&argv_obstack);
970 obstack_ptr_grow (&argv_obstack, compiler);
971 if (save_temps)
972 obstack_ptr_grow (&argv_obstack, "-save-temps");
973 if (verbose)
974 obstack_ptr_grow (&argv_obstack, "-v");
975 obstack_ptr_grow (&argv_obstack, "-o");
976 obstack_ptr_grow (&argv_obstack, *filename);
977
978 /* Append names of input object files. */
979 for (unsigned i = 0; i < in_argc; i++)
980 obstack_ptr_grow (&argv_obstack, in_argv[i]);
981
982 /* Append options from offload_lto sections. */
983 append_compiler_options (argv_obstack: &argv_obstack, opts: compiler_opts);
984 append_diag_options (argv_obstack: &argv_obstack, opts: linker_opts);
985
986 obstack_ptr_grow (&argv_obstack, "-dumpbase");
987 obstack_ptr_grow (&argv_obstack, dumpbase);
988
989 /* Append options specified by -foffload last. In case of conflicting
990 options we expect offload compiler to choose the latest. */
991 append_offload_options (argv_obstack: &argv_obstack, target, options: compiler_opts);
992 append_offload_options (argv_obstack: &argv_obstack, target, options: linker_opts);
993
994 obstack_ptr_grow (&argv_obstack, NULL);
995 argv = XOBFINISH (&argv_obstack, char **);
996 fork_execute (argv[0], argv, true, "offload_args");
997 obstack_free (&argv_obstack, NULL);
998
999 free_array_of_ptrs (ptr: (void **) paths, n: n_paths);
1000 return *filename;
1001}
1002
1003
1004/* The main routine dealing with offloading.
1005 The routine builds a target image for each offload target. IN_ARGC and
1006 IN_ARGV specify options and input object files. As all of them could contain
1007 target sections, we pass them all to target compilers. */
1008
1009static void
1010compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
1011 vec<cl_decoded_option> compiler_opts,
1012 vec<cl_decoded_option> linker_opts)
1013{
1014 char **names = NULL;
1015 const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
1016 if (!target_names)
1017 return;
1018 unsigned num_targets = parse_env_var (str: target_names, pvalues: &names, NULL);
1019 int next_name_entry = 0;
1020
1021 const char *compiler_path = getenv (name: "COMPILER_PATH");
1022 if (!compiler_path)
1023 goto out;
1024
1025 /* Prepare an image for each target and save the name of the resultant object
1026 file to the OFFLOAD_NAMES array. It is terminated by a NULL entry. */
1027 offload_names = XCNEWVEC (char *, num_targets + 1);
1028 for (unsigned i = 0; i < num_targets; i++)
1029 {
1030 if (!compile_offload_image (target: names[i], compiler_path, in_argc, in_argv,
1031 compiler_opts, linker_opts,
1032 filename: &offload_names[next_name_entry]))
1033#if OFFLOAD_DEFAULTED
1034 continue;
1035#else
1036 fatal_error (input_location,
1037 "problem with building target image for %s", names[i]);
1038#endif
1039 next_name_entry++;
1040 }
1041
1042#if OFFLOAD_DEFAULTED
1043 if (next_name_entry == 0)
1044 {
1045 free (offload_names);
1046 offload_names = NULL;
1047 }
1048#endif
1049
1050 out:
1051 free_array_of_ptrs (ptr: (void **) names, n: num_targets);
1052}
1053
1054/* Copy a file from SRC to DEST. */
1055
1056static void
1057copy_file (const char *dest, const char *src)
1058{
1059 FILE *d = fopen (filename: dest, modes: "wb");
1060 FILE *s = fopen (filename: src, modes: "rb");
1061 char buffer[512];
1062 while (!feof (stream: s))
1063 {
1064 size_t len = fread (ptr: buffer, size: 1, n: 512, stream: s);
1065 if (ferror (stream: s) != 0)
1066 fatal_error (input_location, "reading input file");
1067 if (len > 0)
1068 {
1069 fwrite (ptr: buffer, size: 1, n: len, s: d);
1070 if (ferror (stream: d) != 0)
1071 fatal_error (input_location, "writing output file");
1072 }
1073 }
1074 fclose (stream: d);
1075 fclose (stream: s);
1076}
1077
1078/* Find the crtoffloadtable.o file in LIBRARY_PATH, make copy and pass name of
1079 the copy to the linker. */
1080
1081static void
1082find_crtoffloadtable (int save_temps, const char *dumppfx)
1083{
1084 char **paths = NULL;
1085 const char *library_path = getenv (name: "LIBRARY_PATH");
1086 if (!library_path)
1087 return;
1088 unsigned n_paths = parse_env_var (str: library_path, pvalues: &paths, append: "/crtoffloadtable.o");
1089
1090 unsigned i;
1091 for (i = 0; i < n_paths; i++)
1092 if (access_check (name: paths[i], R_OK) == 0)
1093 {
1094 /* The linker will delete the filename we give it, so make a copy. */
1095 char *crtoffloadtable;
1096 if (!save_temps)
1097 crtoffloadtable = make_temp_file (".crtoffloadtable.o");
1098 else
1099 crtoffloadtable = concat (dumppfx, "crtoffloadtable.o", NULL);
1100 copy_file (dest: crtoffloadtable, src: paths[i]);
1101 printf (format: "%s\n", crtoffloadtable);
1102 XDELETEVEC (crtoffloadtable);
1103 break;
1104 }
1105 if (i == n_paths)
1106 fatal_error (input_location,
1107 "installation error, cannot find %<crtoffloadtable.o%>");
1108
1109 free_array_of_ptrs (ptr: (void **) paths, n: n_paths);
1110}
1111
1112/* A subroutine of run_gcc. Examine the open file FD for lto sections with
1113 name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
1114 Return true if we found a matching section, false
1115 otherwise. COLLECT_GCC holds the value of the environment variable with
1116 the same name. */
1117
1118static bool
1119find_and_merge_options (int fd, off_t file_offset, const char *prefix,
1120 vec<cl_decoded_option> decoded_cl_options, bool first,
1121 vec<cl_decoded_option> *opts, const char *collect_gcc)
1122{
1123 off_t offset, length;
1124 char *data;
1125 char *fopts;
1126 const char *errmsg;
1127 int err;
1128 vec<cl_decoded_option> fdecoded_options;
1129
1130 if (!first)
1131 fdecoded_options = *opts;
1132
1133 simple_object_read *sobj;
1134 sobj = simple_object_start_read (descriptor: fd, offset: file_offset, segment_name: "__GNU_LTO",
1135 errmsg: &errmsg, err: &err);
1136 if (!sobj)
1137 return false;
1138
1139 char *secname = XALLOCAVEC (char, strlen (prefix) + sizeof (".opts"));
1140 strcpy (dest: secname, src: prefix);
1141 strcat (dest: secname, src: ".opts");
1142 if (!simple_object_find_section (simple_object: sobj, name: secname, offset: &offset, length: &length,
1143 errmsg: &errmsg, err: &err))
1144 {
1145 simple_object_release_read (sobj);
1146 return false;
1147 }
1148
1149 lseek (fd: fd, offset: file_offset + offset, SEEK_SET);
1150 data = (char *)xmalloc (length);
1151 read (fd: fd, buf: data, nbytes: length);
1152 fopts = data;
1153 do
1154 {
1155 vec<cl_decoded_option> f2decoded_options
1156 = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options: fopts);
1157 if (first)
1158 {
1159 fdecoded_options = f2decoded_options;
1160 first = false;
1161 }
1162 else
1163 merge_and_complain (decoded_options&: fdecoded_options, fdecoded_options: f2decoded_options,
1164 decoded_cl_options);
1165
1166 fopts += strlen (s: fopts) + 1;
1167 }
1168 while (fopts - data < length);
1169
1170 free (ptr: data);
1171 simple_object_release_read (sobj);
1172 *opts = fdecoded_options;
1173 return true;
1174}
1175
1176/* Copy early debug info sections from INFILE to a new file whose name
1177 is returned. Return NULL on error. */
1178
1179const char *
1180debug_objcopy (const char *infile, bool rename)
1181{
1182 char *outfile;
1183 const char *errmsg;
1184 int err;
1185
1186 const char *p;
1187 const char *orig_infile = infile;
1188 off_t inoff = 0;
1189 long loffset;
1190 int consumed;
1191 if ((p = strrchr (s: infile, c: '@'))
1192 && p != infile
1193 && sscanf (s: p, format: "@%li%n", &loffset, &consumed) >= 1
1194 && strlen (s: p) == (unsigned int) consumed)
1195 {
1196 char *fname = xstrdup (infile);
1197 fname[p - infile] = '\0';
1198 infile = fname;
1199 inoff = (off_t) loffset;
1200 }
1201 int infd = open (file: infile, O_RDONLY | O_BINARY);
1202 if (infd == -1)
1203 return NULL;
1204 simple_object_read *inobj = simple_object_start_read (descriptor: infd, offset: inoff,
1205 segment_name: "__GNU_LTO",
1206 errmsg: &errmsg, err: &err);
1207 if (!inobj)
1208 return NULL;
1209
1210 off_t off, len;
1211 if (simple_object_find_section (simple_object: inobj, name: ".gnu.debuglto_.debug_info",
1212 offset: &off, length: &len, errmsg: &errmsg, err: &err) != 1)
1213 {
1214 if (errmsg)
1215 fatal_error (0, "%s: %s", errmsg, xstrerror (err));
1216
1217 simple_object_release_read (inobj);
1218 close (fd: infd);
1219 return NULL;
1220 }
1221
1222 if (save_temps)
1223 outfile = concat (orig_infile, ".debug.temp.o", NULL);
1224 else
1225 outfile = make_temp_file (".debug.temp.o");
1226 errmsg = simple_object_copy_lto_debug_sections (src_object: inobj, dest: outfile, err: &err, rename);
1227 if (errmsg)
1228 {
1229 unlink_if_ordinary (outfile);
1230 fatal_error (0, "%s: %s", errmsg, xstrerror (err));
1231 }
1232
1233 simple_object_release_read (inobj);
1234 close (fd: infd);
1235
1236 return outfile;
1237}
1238
1239/* Helper for qsort: compare priorities for parallel compilation. */
1240
1241int
1242cmp_priority (const void *a, const void *b)
1243{
1244 return *((const int *)b)-*((const int *)a);
1245}
1246
1247/* Number of CPUs that can be used for parallel LTRANS phase. */
1248
1249static unsigned long nthreads_var = 0;
1250
1251#ifdef HAVE_PTHREAD_AFFINITY_NP
1252unsigned long cpuset_size;
1253static unsigned long get_cpuset_size;
1254cpu_set_t *cpusetp;
1255
1256unsigned long
1257static cpuset_popcount (unsigned long cpusetsize, cpu_set_t *cpusetp)
1258{
1259#ifdef CPU_COUNT_S
1260 /* glibc 2.7 and above provide a macro for this. */
1261 return CPU_COUNT_S (cpusetsize, cpusetp);
1262#else
1263#ifdef CPU_COUNT
1264 if (cpusetsize == sizeof (cpu_set_t))
1265 /* glibc 2.6 and above provide a macro for this. */
1266 return CPU_COUNT (cpusetp);
1267#endif
1268 size_t i;
1269 unsigned long ret = 0;
1270 STATIC_ASSERT (sizeof (cpusetp->__bits[0]) == sizeof (unsigned long int));
1271 for (i = 0; i < cpusetsize / sizeof (cpusetp->__bits[0]); i++)
1272 {
1273 unsigned long int mask = cpusetp->__bits[i];
1274 if (mask == 0)
1275 continue;
1276 ret += __builtin_popcountl (mask);
1277 }
1278 return ret;
1279#endif
1280}
1281#endif
1282
1283/* At startup, determine the default number of threads. It would seem
1284 this should be related to the number of cpus online. */
1285
1286static void
1287init_num_threads (void)
1288{
1289#ifdef HAVE_PTHREAD_AFFINITY_NP
1290#if defined (_SC_NPROCESSORS_CONF) && defined (CPU_ALLOC_SIZE)
1291 cpuset_size = sysconf (_SC_NPROCESSORS_CONF);
1292 cpuset_size = CPU_ALLOC_SIZE (cpuset_size);
1293#else
1294 cpuset_size = sizeof (cpu_set_t);
1295#endif
1296
1297 cpusetp = (cpu_set_t *) xmalloc (gomp_cpuset_size);
1298 do
1299 {
1300 int ret = pthread_getaffinity_np (pthread_self (), gomp_cpuset_size,
1301 cpusetp);
1302 if (ret == 0)
1303 {
1304 /* Count only the CPUs this process can use. */
1305 nthreads_var = cpuset_popcount (cpuset_size, cpusetp);
1306 if (nthreads_var == 0)
1307 break;
1308 get_cpuset_size = cpuset_size;
1309#ifdef CPU_ALLOC_SIZE
1310 unsigned long i;
1311 for (i = cpuset_size * 8; i; i--)
1312 if (CPU_ISSET_S (i - 1, cpuset_size, cpusetp))
1313 break;
1314 cpuset_size = CPU_ALLOC_SIZE (i);
1315#endif
1316 return;
1317 }
1318 if (ret != EINVAL)
1319 break;
1320#ifdef CPU_ALLOC_SIZE
1321 if (cpuset_size < sizeof (cpu_set_t))
1322 cpuset_size = sizeof (cpu_set_t);
1323 else
1324 cpuset_size = cpuset_size * 2;
1325 if (cpuset_size < 8 * sizeof (cpu_set_t))
1326 cpusetp
1327 = (cpu_set_t *) realloc (cpusetp, cpuset_size);
1328 else
1329 {
1330 /* Avoid fatal if too large memory allocation would be
1331 requested, e.g. kernel returning EINVAL all the time. */
1332 void *p = realloc (cpusetp, cpuset_size);
1333 if (p == NULL)
1334 break;
1335 cpusetp = (cpu_set_t *) p;
1336 }
1337#else
1338 break;
1339#endif
1340 }
1341 while (1);
1342 cpuset_size = 0;
1343 nthreads_var = 1;
1344 free (cpusetp);
1345 cpusetp = NULL;
1346#endif
1347#ifdef _SC_NPROCESSORS_ONLN
1348 nthreads_var = sysconf (_SC_NPROCESSORS_ONLN);
1349#endif
1350}
1351
1352/* Print link to -flto documentation with a hint message. */
1353
1354void
1355print_lto_docs_link ()
1356{
1357 bool print_url = global_dc->printer->url_format != URL_FORMAT_NONE;
1358 const char *url = global_dc->m_get_option_url (global_dc, OPT_flto);
1359
1360 pretty_printer pp;
1361 pp.url_format = URL_FORMAT_DEFAULT;
1362 pp_string (&pp, "see the ");
1363 if (print_url)
1364 pp_begin_url (pp: &pp, url);
1365 pp_string (&pp, "%<-flto%> option documentation");
1366 if (print_url)
1367 pp_end_url (pp: &pp);
1368 pp_string (&pp, " for more information");
1369 inform (UNKNOWN_LOCATION, pp_formatted_text (&pp));
1370}
1371
1372/* Test that a make command is present and working, return true if so. */
1373
1374static bool
1375make_exists (void)
1376{
1377 const char *make = "make";
1378 char **make_argv = buildargv (getenv (name: "MAKE"));
1379 if (make_argv)
1380 make = make_argv[0];
1381 const char *make_args[] = {make, "--version", NULL};
1382
1383 int exit_status = 0;
1384 int err = 0;
1385 const char *errmsg
1386 = pex_one (PEX_SEARCH, executable: make_args[0], CONST_CAST (char **, make_args),
1387 pname: "make", NULL, NULL, status: &exit_status, err: &err);
1388 freeargv (make_argv);
1389 return errmsg == NULL && exit_status == 0 && err == 0;
1390}
1391
1392/* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
1393
1394static void
1395run_gcc (unsigned argc, char *argv[])
1396{
1397 unsigned i, j;
1398 const char **new_argv;
1399 const char **argv_ptr;
1400 char *list_option_full = NULL;
1401 const char *linker_output = NULL;
1402 const char *collect_gcc;
1403 char *collect_gcc_options;
1404 int parallel = 0;
1405 int jobserver = 0;
1406 bool jobserver_requested = false;
1407 int auto_parallel = 0;
1408 bool no_partition = false;
1409 bool fdecoded_options_first = true;
1410 vec<cl_decoded_option> fdecoded_options;
1411 fdecoded_options.create (nelems: 16);
1412 bool offload_fdecoded_options_first = true;
1413 vec<cl_decoded_option> offload_fdecoded_options = vNULL;
1414 struct obstack argv_obstack;
1415 int new_head_argc;
1416 bool have_lto = false;
1417 bool have_offload = false;
1418 unsigned lto_argc = 0, ltoobj_argc = 0;
1419 char **lto_argv, **ltoobj_argv;
1420 bool linker_output_rel = false;
1421 bool skip_debug = false;
1422 const char *incoming_dumppfx = dumppfx = NULL;
1423 static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
1424
1425 /* Get the driver and options. */
1426 collect_gcc = getenv (name: "COLLECT_GCC");
1427 if (!collect_gcc)
1428 fatal_error (input_location,
1429 "environment variable %<COLLECT_GCC%> must be set");
1430 collect_gcc_options = getenv (name: "COLLECT_GCC_OPTIONS");
1431 if (!collect_gcc_options)
1432 fatal_error (input_location,
1433 "environment variable %<COLLECT_GCC_OPTIONS%> must be set");
1434
1435 char *collect_as_options = getenv (name: "COLLECT_AS_OPTIONS");
1436
1437 /* Prepend -Xassembler to each option, and append the string
1438 to collect_gcc_options. */
1439 if (collect_as_options)
1440 {
1441 obstack temporary_obstack;
1442 obstack_init (&temporary_obstack);
1443
1444 prepend_xassembler_to_collect_as_options (collect_as_options,
1445 &temporary_obstack);
1446 obstack_1grow (&temporary_obstack, '\0');
1447
1448 char *xassembler_opts_string
1449 = XOBFINISH (&temporary_obstack, char *);
1450 collect_gcc_options = concat (collect_gcc_options, xassembler_opts_string,
1451 NULL);
1452 }
1453
1454 vec<cl_decoded_option> decoded_options
1455 = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
1456
1457 /* Allocate array for input object files with LTO IL,
1458 and for possible preceding arguments. */
1459 lto_argv = XNEWVEC (char *, argc);
1460 ltoobj_argv = XNEWVEC (char *, argc);
1461
1462 /* Look at saved options in the IL files. */
1463 for (i = 1; i < argc; ++i)
1464 {
1465 char *p;
1466 int fd;
1467 off_t file_offset = 0;
1468 long loffset;
1469 int consumed;
1470 char *filename = argv[i];
1471
1472 if (startswith (str: argv[i], prefix: "-foffload-objects="))
1473 {
1474 have_offload = true;
1475 offload_objects_file_name
1476 = argv[i] + sizeof ("-foffload-objects=") - 1;
1477 continue;
1478 }
1479
1480 if ((p = strrchr (s: argv[i], c: '@'))
1481 && p != argv[i]
1482 && sscanf (s: p, format: "@%li%n", &loffset, &consumed) >= 1
1483 && strlen (s: p) == (unsigned int) consumed)
1484 {
1485 filename = XNEWVEC (char, p - argv[i] + 1);
1486 memcpy (dest: filename, src: argv[i], n: p - argv[i]);
1487 filename[p - argv[i]] = '\0';
1488 file_offset = (off_t) loffset;
1489 }
1490 fd = open (file: filename, O_RDONLY | O_BINARY);
1491 /* Linker plugin passes -fresolution and -flinker-output options.
1492 -flinker-output is passed only when user did not specify one and thus
1493 we do not need to worry about duplicities with the option handling
1494 below. */
1495 if (fd == -1)
1496 {
1497 lto_argv[lto_argc++] = argv[i];
1498 if (strcmp (s1: argv[i], s2: "-flinker-output=rel") == 0)
1499 linker_output_rel = true;
1500 continue;
1501 }
1502
1503 if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
1504 decoded_cl_options: decoded_options, first: fdecoded_options_first,
1505 opts: &fdecoded_options,
1506 collect_gcc))
1507 {
1508 have_lto = true;
1509 ltoobj_argv[ltoobj_argc++] = argv[i];
1510 fdecoded_options_first = false;
1511 }
1512 close (fd: fd);
1513 }
1514
1515 /* Initalize the common arguments for the driver. */
1516 obstack_init (&argv_obstack);
1517 obstack_ptr_grow (&argv_obstack, collect_gcc);
1518 obstack_ptr_grow (&argv_obstack, "-xlto");
1519 obstack_ptr_grow (&argv_obstack, "-c");
1520
1521 append_compiler_options (argv_obstack: &argv_obstack, opts: fdecoded_options);
1522 append_linker_options (argv_obstack: &argv_obstack, opts: decoded_options);
1523
1524 /* Scan linker driver arguments for things that are of relevance to us. */
1525 for (j = 1; j < decoded_options.length (); ++j)
1526 {
1527 cl_decoded_option *option = &decoded_options[j];
1528 switch (option->opt_index)
1529 {
1530 case OPT_o:
1531 linker_output = option->arg;
1532 break;
1533
1534 /* We don't have to distinguish between -save-temps=* and
1535 -save-temps, -dumpdir already carries that
1536 information. */
1537 case OPT_save_temps_:
1538 case OPT_save_temps:
1539 save_temps = 1;
1540 break;
1541
1542 case OPT_v:
1543 verbose = 1;
1544 break;
1545
1546 case OPT_flto_partition_:
1547 if (strcmp (s1: option->arg, s2: "none") == 0)
1548 no_partition = true;
1549 break;
1550
1551 case OPT_flto_:
1552 /* Merge linker -flto= option with what we have in IL files. */
1553 merge_flto_options (decoded_options&: fdecoded_options, foption: option);
1554 if (strcmp (s1: option->arg, s2: "jobserver") == 0)
1555 jobserver_requested = true;
1556 break;
1557
1558 case OPT_flinker_output_:
1559 linker_output_rel = !strcmp (s1: option->arg, s2: "rel");
1560 break;
1561
1562 case OPT_g:
1563 /* Recognize -g0. */
1564 skip_debug = option->arg && !strcmp (s1: option->arg, s2: "0");
1565 break;
1566
1567 case OPT_gbtf:
1568 case OPT_gctf:
1569 case OPT_gdwarf:
1570 case OPT_gdwarf_:
1571 case OPT_ggdb:
1572 case OPT_gvms:
1573 /* Negative forms, if allowed, enable debug info as well. */
1574 skip_debug = false;
1575 break;
1576
1577 case OPT_dumpdir:
1578 incoming_dumppfx = dumppfx = option->arg;
1579 break;
1580
1581 case OPT_fdiagnostics_urls_:
1582 diagnostic_urls_init (context: global_dc, value: option->value);
1583 break;
1584
1585 case OPT_fdiagnostics_color_:
1586 diagnostic_color_init (context: global_dc, value: option->value);
1587 break;
1588
1589 default:
1590 break;
1591 }
1592 }
1593
1594 /* Process LTO-related options on merged options. */
1595 for (j = 1; j < fdecoded_options.length (); ++j)
1596 {
1597 cl_decoded_option *option = &fdecoded_options[j];
1598 switch (option->opt_index)
1599 {
1600 case OPT_flto_:
1601 if (strcmp (s1: option->arg, s2: "jobserver") == 0)
1602 {
1603 parallel = 1;
1604 jobserver = 1;
1605 }
1606 else if (strcmp (s1: option->arg, s2: "auto") == 0)
1607 {
1608 parallel = 1;
1609 auto_parallel = 1;
1610 }
1611 else
1612 {
1613 parallel = atoi (nptr: option->arg);
1614 if (parallel <= 1)
1615 parallel = 0;
1616 }
1617 /* Fallthru. */
1618
1619 case OPT_flto:
1620 lto_mode = LTO_MODE_WHOPR;
1621 break;
1622 }
1623 }
1624
1625 /* Output lto-wrapper invocation command. */
1626 if (verbose)
1627 {
1628 for (i = 0; i < argc; ++i)
1629 {
1630 fputs (s: argv[i], stderr);
1631 fputc (c: ' ', stderr);
1632 }
1633 fputc (c: '\n', stderr);
1634 }
1635
1636 if (linker_output_rel)
1637 no_partition = true;
1638
1639 if (no_partition)
1640 {
1641 lto_mode = LTO_MODE_LTO;
1642 jobserver = 0;
1643 jobserver_requested = false;
1644 auto_parallel = 0;
1645 parallel = 0;
1646 }
1647 else
1648 {
1649 jobserver_info jinfo;
1650 if (jobserver && !jinfo.is_active)
1651 {
1652 /* Fall back to auto parallelism. */
1653 jobserver = 0;
1654 auto_parallel = 1;
1655 }
1656 else if (!jobserver && jinfo.is_active)
1657 {
1658 parallel = 1;
1659 jobserver = 1;
1660 }
1661 }
1662
1663 /* We need make working for a parallel execution. */
1664 if (parallel && !make_exists ())
1665 parallel = 0;
1666
1667 if (!dumppfx)
1668 {
1669 if (!linker_output
1670 || strcmp (s1: linker_output, HOST_BIT_BUCKET) == 0)
1671 dumppfx = "a.";
1672 else
1673 {
1674 const char *obase = lbasename (linker_output), *temp;
1675
1676 /* Strip the executable extension. */
1677 size_t blen = strlen (s: obase), xlen;
1678 if ((temp = strrchr (s: obase + 1, c: '.'))
1679 && (xlen = strlen (s: temp))
1680 && (strcmp (s1: temp, s2: ".exe") == 0
1681#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
1682 || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
1683#endif
1684 || strcmp (s1: obase, s2: "a.out") == 0))
1685 dumppfx = xstrndup (linker_output,
1686 obase - linker_output + blen - xlen + 1);
1687 else
1688 dumppfx = concat (linker_output, ".", NULL);
1689 }
1690 }
1691
1692 /* If there's no directory component in the dumppfx, add one, so
1693 that, when it is used as -dumpbase, it overrides any occurrence
1694 of -dumpdir that might have been passed in. */
1695 if (!dumppfx || lbasename (dumppfx) == dumppfx)
1696 dumppfx = concat (current_dir, dumppfx, NULL);
1697
1698 /* Make sure some -dumpdir is passed, so as to get predictable
1699 -dumpbase overriding semantics. If we got an incoming -dumpdir
1700 argument, we'll pass it on, so don't bother with another one
1701 then. */
1702 if (!incoming_dumppfx)
1703 {
1704 obstack_ptr_grow (&argv_obstack, "-dumpdir");
1705 obstack_ptr_grow (&argv_obstack, "");
1706 }
1707 obstack_ptr_grow (&argv_obstack, "-dumpbase");
1708
1709 /* Remember at which point we can scrub args to re-use the commons. */
1710 new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
1711
1712 if (have_offload)
1713 {
1714 unsigned i, num_offload_files;
1715 char **offload_argv;
1716 FILE *f;
1717
1718 f = fopen (filename: offload_objects_file_name, modes: "r");
1719 if (f == NULL)
1720 fatal_error (input_location, "cannot open %s: %m",
1721 offload_objects_file_name);
1722 if (fscanf (stream: f, format: "%u ", &num_offload_files) != 1)
1723 fatal_error (input_location, "cannot read %s: %m",
1724 offload_objects_file_name);
1725 offload_argv = XCNEWVEC (char *, num_offload_files);
1726
1727 /* Read names of object files with offload. */
1728 for (i = 0; i < num_offload_files; i++)
1729 {
1730 const unsigned piece = 32;
1731 char *buf, *filename = XNEWVEC (char, piece);
1732 size_t len;
1733
1734 buf = filename;
1735cont1:
1736 if (!fgets (s: buf, n: piece, stream: f))
1737 break;
1738 len = strlen (s: filename);
1739 if (filename[len - 1] != '\n')
1740 {
1741 filename = XRESIZEVEC (char, filename, len + piece);
1742 buf = filename + len;
1743 goto cont1;
1744 }
1745 filename[len - 1] = '\0';
1746 offload_argv[i] = filename;
1747 }
1748 fclose (stream: f);
1749 if (offload_argv[num_offload_files - 1] == NULL)
1750 fatal_error (input_location, "invalid format of %s",
1751 offload_objects_file_name);
1752 maybe_unlink (file: offload_objects_file_name);
1753 offload_objects_file_name = NULL;
1754
1755 /* Look at saved offload options in files. */
1756 for (i = 0; i < num_offload_files; i++)
1757 {
1758 char *p;
1759 long loffset;
1760 int fd, consumed;
1761 off_t file_offset = 0;
1762 char *filename = offload_argv[i];
1763
1764 if ((p = strrchr (s: offload_argv[i], c: '@'))
1765 && p != offload_argv[i]
1766 && sscanf (s: p, format: "@%li%n", &loffset, &consumed) >= 1
1767 && strlen (s: p) == (unsigned int) consumed)
1768 {
1769 filename = XNEWVEC (char, p - offload_argv[i] + 1);
1770 memcpy (dest: filename, src: offload_argv[i], n: p - offload_argv[i]);
1771 filename[p - offload_argv[i]] = '\0';
1772 file_offset = (off_t) loffset;
1773 }
1774 fd = open (file: filename, O_RDONLY | O_BINARY);
1775 if (fd == -1)
1776 fatal_error (input_location, "cannot open %s: %m", filename);
1777 if (!find_and_merge_options (fd, file_offset,
1778 OFFLOAD_SECTION_NAME_PREFIX,
1779 decoded_cl_options: decoded_options,
1780 first: offload_fdecoded_options_first,
1781 opts: &offload_fdecoded_options,
1782 collect_gcc))
1783 fatal_error (input_location, "cannot read %s: %m", filename);
1784 offload_fdecoded_options_first = false;
1785 close (fd: fd);
1786 if (filename != offload_argv[i])
1787 XDELETEVEC (filename);
1788 }
1789
1790 compile_images_for_offload_targets (in_argc: num_offload_files, in_argv: offload_argv,
1791 compiler_opts: offload_fdecoded_options, linker_opts: decoded_options);
1792
1793 free_array_of_ptrs (ptr: (void **) offload_argv, n: num_offload_files);
1794
1795 if (offload_names)
1796 {
1797 find_crtoffloadtable (save_temps, dumppfx);
1798 for (i = 0; offload_names[i]; i++)
1799 printf (format: "%s\n", offload_names[i]);
1800 free_array_of_ptrs (ptr: (void **) offload_names, n: i);
1801 offload_names = NULL;
1802 }
1803 }
1804
1805 /* If object files contain offload sections, but do not contain LTO sections,
1806 then there is no need to perform a link-time recompilation, i.e.
1807 lto-wrapper is used only for a compilation of offload images. */
1808 if (have_offload && !have_lto)
1809 goto finish;
1810
1811 if (lto_mode == LTO_MODE_LTO)
1812 {
1813 /* -dumpbase argument for LTO. */
1814 flto_out = concat (dumppfx, "lto.o", NULL);
1815 obstack_ptr_grow (&argv_obstack, flto_out);
1816
1817 if (!save_temps)
1818 flto_out = make_temp_file (".lto.o");
1819 obstack_ptr_grow (&argv_obstack, "-o");
1820 obstack_ptr_grow (&argv_obstack, flto_out);
1821 }
1822 else
1823 {
1824 const char *list_option = "-fltrans-output-list=";
1825
1826 /* -dumpbase argument for WPA. */
1827 char *dumpbase = concat (dumppfx, "wpa", NULL);
1828 obstack_ptr_grow (&argv_obstack, dumpbase);
1829
1830 if (save_temps)
1831 ltrans_output_file = concat (dumppfx, "ltrans.out", NULL);
1832 else
1833 ltrans_output_file = make_temp_file (".ltrans.out");
1834 list_option_full = concat (list_option, ltrans_output_file, NULL);
1835 obstack_ptr_grow (&argv_obstack, list_option_full);
1836
1837 if (jobserver)
1838 {
1839 if (verbose)
1840 fprintf (stderr, format: "Using make jobserver\n");
1841 obstack_ptr_grow (&argv_obstack, xstrdup ("-fwpa=jobserver"));
1842 }
1843 else if (auto_parallel)
1844 {
1845 char buf[256];
1846 init_num_threads ();
1847 if (nthreads_var == 0)
1848 nthreads_var = 1;
1849 if (verbose)
1850 fprintf (stderr, format: "LTO parallelism level set to %ld\n",
1851 nthreads_var);
1852 sprintf (s: buf, format: "-fwpa=%ld", nthreads_var);
1853 obstack_ptr_grow (&argv_obstack, xstrdup (buf));
1854 }
1855 else if (parallel > 1)
1856 {
1857 char buf[256];
1858 sprintf (s: buf, format: "-fwpa=%i", parallel);
1859 obstack_ptr_grow (&argv_obstack, xstrdup (buf));
1860 }
1861 else
1862 obstack_ptr_grow (&argv_obstack, "-fwpa");
1863 }
1864
1865 /* Append input arguments. */
1866 for (i = 0; i < lto_argc; ++i)
1867 obstack_ptr_grow (&argv_obstack, lto_argv[i]);
1868 /* Append the input objects. */
1869 for (i = 0; i < ltoobj_argc; ++i)
1870 obstack_ptr_grow (&argv_obstack, ltoobj_argv[i]);
1871 obstack_ptr_grow (&argv_obstack, NULL);
1872
1873 new_argv = XOBFINISH (&argv_obstack, const char **);
1874 argv_ptr = &new_argv[new_head_argc];
1875 fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true,
1876 "ltrans_args");
1877
1878 /* Copy the early generated debug info from the objects to temporary
1879 files and append those to the partial link commandline. */
1880 early_debug_object_names = NULL;
1881 if (! skip_debug)
1882 {
1883 early_debug_object_names = XCNEWVEC (const char *, ltoobj_argc+ 1);
1884 num_deb_objs = ltoobj_argc;
1885 for (i = 0; i < ltoobj_argc; ++i)
1886 {
1887 const char *tem;
1888 if ((tem = debug_objcopy (infile: ltoobj_argv[i], rename: !linker_output_rel)))
1889 early_debug_object_names[i] = tem;
1890 }
1891 }
1892
1893 if (lto_mode == LTO_MODE_LTO)
1894 {
1895 printf (format: "%s\n", flto_out);
1896 if (!skip_debug)
1897 {
1898 for (i = 0; i < ltoobj_argc; ++i)
1899 if (early_debug_object_names[i] != NULL)
1900 printf (format: "%s\n", early_debug_object_names[i]);
1901 }
1902 /* These now belong to collect2. */
1903 free (ptr: flto_out);
1904 flto_out = NULL;
1905 free (ptr: early_debug_object_names);
1906 early_debug_object_names = NULL;
1907 }
1908 else
1909 {
1910 FILE *stream = fopen (filename: ltrans_output_file, modes: "r");
1911 FILE *mstream = NULL;
1912 struct obstack env_obstack;
1913 int priority;
1914
1915 if (!stream)
1916 fatal_error (input_location, "%<fopen%>: %s: %m", ltrans_output_file);
1917
1918 /* Parse the list of LTRANS inputs from the WPA stage. */
1919 obstack_init (&env_obstack);
1920 nr = 0;
1921 for (;;)
1922 {
1923 const unsigned piece = 32;
1924 char *output_name = NULL;
1925 char *buf, *input_name = (char *)xmalloc (piece);
1926 size_t len;
1927
1928 buf = input_name;
1929 if (fscanf (stream: stream, format: "%i\n", &priority) != 1)
1930 {
1931 if (!feof (stream: stream))
1932 fatal_error (input_location,
1933 "corrupted ltrans output file %s",
1934 ltrans_output_file);
1935 break;
1936 }
1937cont:
1938 if (!fgets (s: buf, n: piece, stream: stream))
1939 break;
1940 len = strlen (s: input_name);
1941 if (input_name[len - 1] != '\n')
1942 {
1943 input_name = (char *)xrealloc (input_name, len + piece);
1944 buf = input_name + len;
1945 goto cont;
1946 }
1947 input_name[len - 1] = '\0';
1948
1949 if (input_name[0] == '*')
1950 output_name = &input_name[1];
1951
1952 nr++;
1953 ltrans_priorities
1954 = (int *)xrealloc (ltrans_priorities, nr * sizeof (int) * 2);
1955 input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
1956 output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
1957 ltrans_priorities[(nr-1)*2] = priority;
1958 ltrans_priorities[(nr-1)*2+1] = nr-1;
1959 input_names[nr-1] = input_name;
1960 output_names[nr-1] = output_name;
1961 }
1962 fclose (stream: stream);
1963 maybe_unlink (file: ltrans_output_file);
1964 ltrans_output_file = NULL;
1965
1966 if (nr > 1)
1967 {
1968 jobserver_info jinfo;
1969 if (jobserver_requested && !jinfo.is_active)
1970 {
1971 warning (0, jinfo.error_msg.c_str ());
1972 print_lto_docs_link ();
1973 }
1974 else if (parallel == 0)
1975 {
1976 warning (0, "using serial compilation of %d LTRANS jobs", nr);
1977 print_lto_docs_link ();
1978 }
1979 }
1980
1981 if (parallel)
1982 {
1983 makefile = make_temp_file (".mk");
1984 mstream = fopen (filename: makefile, modes: "w");
1985 qsort (ltrans_priorities, nr, sizeof (int) * 2, cmp_priority);
1986 }
1987
1988 /* Execute the LTRANS stage for each input file (or prepare a
1989 makefile to invoke this in parallel). */
1990 for (i = 0; i < nr; ++i)
1991 {
1992 char *output_name;
1993 char *input_name = input_names[i];
1994 /* If it's a pass-through file do nothing. */
1995 if (output_names[i])
1996 continue;
1997
1998 /* Replace the .o suffix with a .ltrans.o suffix and write
1999 the resulting name to the LTRANS output list. */
2000 obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
2001 obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
2002 output_name = XOBFINISH (&env_obstack, char *);
2003
2004 /* Adjust the dumpbase if the linker output file was seen. */
2005 int dumpbase_len = (strlen (s: dumppfx)
2006 + sizeof (DUMPBASE_SUFFIX)
2007 + sizeof (".ltrans"));
2008 char *dumpbase = (char *) xmalloc (dumpbase_len + 1);
2009 snprintf (s: dumpbase, maxlen: dumpbase_len, format: "%sltrans%u.ltrans", dumppfx, i);
2010 argv_ptr[0] = dumpbase;
2011
2012 argv_ptr[1] = "-fltrans";
2013 argv_ptr[2] = "-o";
2014 argv_ptr[3] = output_name;
2015 argv_ptr[4] = input_name;
2016 argv_ptr[5] = NULL;
2017 if (parallel)
2018 {
2019 fprintf (stream: mstream, format: "%s:\n\t@%s ", output_name, new_argv[0]);
2020 for (j = 1; new_argv[j] != NULL; ++j)
2021 fprintf (stream: mstream, format: " '%s'", new_argv[j]);
2022 fprintf (stream: mstream, format: "\n");
2023 /* If we are not preserving the ltrans input files then
2024 truncate them as soon as we have processed it. This
2025 reduces temporary disk-space usage. */
2026 if (! save_temps)
2027 fprintf (stream: mstream, format: "\t@-touch -r \"%s\" \"%s.tem\" > /dev/null "
2028 "2>&1 && mv \"%s.tem\" \"%s\"\n",
2029 input_name, input_name, input_name, input_name);
2030 }
2031 else
2032 {
2033 char argsuffix[sizeof (DUMPBASE_SUFFIX)
2034 + sizeof (".ltrans_args") + 1];
2035 if (save_temps)
2036 snprintf (s: argsuffix,
2037 maxlen: sizeof (DUMPBASE_SUFFIX) + sizeof (".ltrans_args"),
2038 format: "ltrans%u.ltrans_args", i);
2039 fork_execute (new_argv[0], CONST_CAST (char **, new_argv),
2040 true, save_temps ? argsuffix : NULL);
2041 maybe_unlink (file: input_name);
2042 }
2043
2044 output_names[i] = output_name;
2045 }
2046 if (parallel)
2047 {
2048 struct pex_obj *pex;
2049 char jobs[32];
2050
2051 fprintf (stream: mstream,
2052 format: ".PHONY: all\n"
2053 "all:");
2054 for (i = 0; i < nr; ++i)
2055 {
2056 int j = ltrans_priorities[i*2 + 1];
2057 fprintf (stream: mstream, format: " \\\n\t%s", output_names[j]);
2058 }
2059 fprintf (stream: mstream, format: "\n");
2060 fclose (stream: mstream);
2061 if (!jobserver)
2062 {
2063 /* Avoid passing --jobserver-fd= and similar flags
2064 unless jobserver mode is explicitly enabled. */
2065 putenv (string: xstrdup ("MAKEFLAGS="));
2066 putenv (string: xstrdup ("MFLAGS="));
2067 }
2068
2069 char **make_argv = buildargv (getenv (name: "MAKE"));
2070 if (make_argv)
2071 {
2072 for (unsigned argc = 0; make_argv[argc]; argc++)
2073 obstack_ptr_grow (&argv_obstack, make_argv[argc]);
2074 }
2075 else
2076 obstack_ptr_grow (&argv_obstack, "make");
2077
2078 obstack_ptr_grow (&argv_obstack, "-f");
2079 obstack_ptr_grow (&argv_obstack, makefile);
2080 if (!jobserver)
2081 {
2082 snprintf (s: jobs, maxlen: 31, format: "-j%ld",
2083 auto_parallel ? nthreads_var : parallel);
2084 obstack_ptr_grow (&argv_obstack, jobs);
2085 }
2086 obstack_ptr_grow (&argv_obstack, "all");
2087 obstack_ptr_grow (&argv_obstack, NULL);
2088 new_argv = XOBFINISH (&argv_obstack, const char **);
2089
2090 pex = collect_execute (new_argv[0], CONST_CAST (char **, new_argv),
2091 NULL, NULL, PEX_SEARCH, false, NULL);
2092 do_wait (new_argv[0], pex);
2093 freeargv (make_argv);
2094 maybe_unlink (file: makefile);
2095 makefile = NULL;
2096 for (i = 0; i < nr; ++i)
2097 maybe_unlink (file: input_names[i]);
2098 }
2099 for (i = 0; i < nr; ++i)
2100 {
2101 fputs (s: output_names[i], stdout);
2102 putc (c: '\n', stdout);
2103 free (ptr: input_names[i]);
2104 }
2105 if (!skip_debug)
2106 {
2107 for (i = 0; i < ltoobj_argc; ++i)
2108 if (early_debug_object_names[i] != NULL)
2109 printf (format: "%s\n", early_debug_object_names[i]);
2110 }
2111 nr = 0;
2112 free (ptr: ltrans_priorities);
2113 free (ptr: output_names);
2114 output_names = NULL;
2115 free (ptr: early_debug_object_names);
2116 early_debug_object_names = NULL;
2117 free (ptr: input_names);
2118 free (ptr: list_option_full);
2119 obstack_free (&env_obstack, NULL);
2120 }
2121
2122 finish:
2123 XDELETE (lto_argv);
2124 obstack_free (&argv_obstack, NULL);
2125}
2126
2127
2128/* Entry point. */
2129
2130int
2131main (int argc, char *argv[])
2132{
2133 const char *p;
2134
2135 init_opts_obstack ();
2136
2137 p = argv[0] + strlen (s: argv[0]);
2138 while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
2139 --p;
2140 progname = p;
2141
2142 xmalloc_set_program_name (progname);
2143
2144 gcc_init_libintl ();
2145
2146 diagnostic_initialize (context: global_dc, n_opts: 0);
2147 diagnostic_color_init (context: global_dc);
2148 diagnostic_urls_init (context: global_dc);
2149 global_dc->m_get_option_url = get_option_url;
2150
2151 if (atexit (func: lto_wrapper_cleanup) != 0)
2152 fatal_error (input_location, "%<atexit%> failed");
2153
2154 setup_signals ();
2155
2156 /* We may be called with all the arguments stored in some file and
2157 passed with @file. Expand them into argv before processing. */
2158 expandargv (&argc, &argv);
2159
2160 run_gcc (argc, argv);
2161
2162 return 0;
2163}
2164

source code of gcc/lto-wrapper.cc