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