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