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