xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/lto-wrapper.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Wrapper to call lto.  Used by collect2 and the linker plugin.
2    Copyright (C) 2009-2015 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 #include "config.h"
41 #include "system.h"
42 #include "coretypes.h"
43 #include "intl.h"
44 #include "diagnostic.h"
45 #include "obstack.h"
46 #include "opts.h"
47 #include "options.h"
48 #include "simple-object.h"
49 #include "lto-section-names.h"
50 #include "collect-utils.h"
51 
52 /* Environment variable, used for passing the names of offload targets from GCC
53    driver to lto-wrapper.  */
54 #define OFFLOAD_TARGET_NAMES_ENV	"OFFLOAD_TARGET_NAMES"
55 
56 enum lto_mode_d {
57   LTO_MODE_NONE,			/* Not doing LTO.  */
58   LTO_MODE_LTO,				/* Normal LTO.  */
59   LTO_MODE_WHOPR			/* WHOPR.  */
60 };
61 
62 /* Current LTO mode.  */
63 static enum lto_mode_d lto_mode = LTO_MODE_NONE;
64 
65 static char *ltrans_output_file;
66 static char *flto_out;
67 static unsigned int nr;
68 static char **input_names;
69 static char **output_names;
70 static char **offload_names;
71 static const char *offloadbegin, *offloadend;
72 static char *makefile;
73 
74 const char tool_name[] = "lto-wrapper";
75 
76 /* Delete tempfiles.  Called from utils_cleanup.  */
77 
78 void
79 tool_cleanup (bool)
80 {
81   unsigned int i;
82 
83   if (ltrans_output_file)
84     maybe_unlink (ltrans_output_file);
85   if (flto_out)
86     maybe_unlink (flto_out);
87   if (makefile)
88     maybe_unlink (makefile);
89   for (i = 0; i < nr; ++i)
90     {
91       maybe_unlink (input_names[i]);
92       if (output_names[i])
93 	maybe_unlink (output_names[i]);
94     }
95 }
96 
97 static void
98 lto_wrapper_cleanup (void)
99 {
100   utils_cleanup (false);
101 }
102 
103 /* Unlink a temporary LTRANS file unless requested otherwise.  */
104 
105 void
106 maybe_unlink (const char *file)
107 {
108   if (!save_temps)
109     {
110       if (unlink_if_ordinary (file)
111 	  && errno != ENOENT)
112 	fatal_error (input_location, "deleting LTRANS file %s: %m", file);
113     }
114   else if (verbose)
115     fprintf (stderr, "[Leaving LTRANS %s]\n", file);
116 }
117 
118 /* Template of LTRANS dumpbase suffix.  */
119 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
120 
121 /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
122    environment according to LANG_MASK.  */
123 
124 static void
125 get_options_from_collect_gcc_options (const char *collect_gcc,
126 				      const char *collect_gcc_options,
127 				      unsigned int lang_mask,
128 				      struct cl_decoded_option **decoded_options,
129 				      unsigned int *decoded_options_count)
130 {
131   struct obstack argv_obstack;
132   char *argv_storage;
133   const char **argv;
134   int j, k, argc;
135 
136   argv_storage = xstrdup (collect_gcc_options);
137   obstack_init (&argv_obstack);
138   obstack_ptr_grow (&argv_obstack, collect_gcc);
139 
140   for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
141     {
142       if (argv_storage[j] == '\'')
143 	{
144 	  obstack_ptr_grow (&argv_obstack, &argv_storage[k]);
145 	  ++j;
146 	  do
147 	    {
148 	      if (argv_storage[j] == '\0')
149 		fatal_error (input_location, "malformed COLLECT_GCC_OPTIONS");
150 	      else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
151 		{
152 		  argv_storage[k++] = '\'';
153 		  j += 4;
154 		}
155 	      else if (argv_storage[j] == '\'')
156 		break;
157 	      else
158 		argv_storage[k++] = argv_storage[j++];
159 	    }
160 	  while (1);
161 	  argv_storage[k++] = '\0';
162 	}
163     }
164 
165   obstack_ptr_grow (&argv_obstack, NULL);
166   argc = obstack_object_size (&argv_obstack) / sizeof (void *) - 1;
167   argv = XOBFINISH (&argv_obstack, const char **);
168 
169   decode_cmdline_options_to_array (argc, (const char **)argv,
170 				   lang_mask,
171 				   decoded_options, decoded_options_count);
172   obstack_free (&argv_obstack, NULL);
173 }
174 
175 /* Append OPTION to the options array DECODED_OPTIONS with size
176    DECODED_OPTIONS_COUNT.  */
177 
178 static void
179 append_option (struct cl_decoded_option **decoded_options,
180 	       unsigned int *decoded_options_count,
181 	       struct cl_decoded_option *option)
182 {
183   ++*decoded_options_count;
184   *decoded_options
185     = (struct cl_decoded_option *)
186 	xrealloc (*decoded_options,
187 		  (*decoded_options_count
188 		   * sizeof (struct cl_decoded_option)));
189   memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
190 	  sizeof (struct cl_decoded_option));
191 }
192 
193 /* Try to merge and complain about options FDECODED_OPTIONS when applied
194    ontop of DECODED_OPTIONS.  */
195 
196 static void
197 merge_and_complain (struct cl_decoded_option **decoded_options,
198 		    unsigned int *decoded_options_count,
199 		    struct cl_decoded_option *fdecoded_options,
200 		    unsigned int fdecoded_options_count)
201 {
202   unsigned int i, j;
203 
204   /* ???  Merge options from files.  Most cases can be
205      handled by either unioning or intersecting
206      (for example -fwrapv is a case for unioning,
207      -ffast-math is for intersection).  Most complaints
208      about real conflicts between different options can
209      be deferred to the compiler proper.  Options that
210      we can neither safely handle by intersection nor
211      unioning would need to be complained about here.
212      Ideally we'd have a flag in the opt files that
213      tells whether to union or intersect or reject.
214      In absence of that it's unclear what a good default is.
215      It's also difficult to get positional handling correct.  */
216 
217   /* The following does what the old LTO option code did,
218      union all target and a selected set of common options.  */
219   for (i = 0; i < fdecoded_options_count; ++i)
220     {
221       struct cl_decoded_option *foption = &fdecoded_options[i];
222       switch (foption->opt_index)
223 	{
224 	case OPT_SPECIAL_unknown:
225 	case OPT_SPECIAL_ignore:
226 	case OPT_SPECIAL_program_name:
227 	case OPT_SPECIAL_input_file:
228 	  break;
229 
230 	default:
231 	  if (!(cl_options[foption->opt_index].flags & CL_TARGET))
232 	    break;
233 
234 	  /* Fallthru.  */
235 	case OPT_fPIC:
236 	case OPT_fpic:
237 	case OPT_fPIE:
238 	case OPT_fpie:
239 	case OPT_fcommon:
240 	case OPT_fexceptions:
241 	case OPT_fnon_call_exceptions:
242 	case OPT_fgnu_tm:
243 	  /* Do what the old LTO code did - collect exactly one option
244 	     setting per OPT code, we pick the first we encounter.
245 	     ???  This doesn't make too much sense, but when it doesn't
246 	     then we should complain.  */
247 	  for (j = 0; j < *decoded_options_count; ++j)
248 	    if ((*decoded_options)[j].opt_index == foption->opt_index)
249 	      break;
250 	  if (j == *decoded_options_count)
251 	    append_option (decoded_options, decoded_options_count, foption);
252 	  break;
253 
254 	case OPT_ftrapv:
255 	case OPT_fstrict_overflow:
256 	case OPT_ffp_contract_:
257 	  /* For selected options we can merge conservatively.  */
258 	  for (j = 0; j < *decoded_options_count; ++j)
259 	    if ((*decoded_options)[j].opt_index == foption->opt_index)
260 	      break;
261 	  if (j == *decoded_options_count)
262 	    append_option (decoded_options, decoded_options_count, foption);
263 	  /* FP_CONTRACT_OFF < FP_CONTRACT_ON < FP_CONTRACT_FAST,
264 	     -fno-trapv < -ftrapv,
265 	     -fno-strict-overflow < -fstrict-overflow  */
266 	  else if (foption->value < (*decoded_options)[j].value)
267 	    (*decoded_options)[j] = *foption;
268 	  break;
269 
270 	case OPT_fmath_errno:
271 	case OPT_fsigned_zeros:
272 	case OPT_ftrapping_math:
273 	case OPT_fwrapv:
274 	case OPT_fopenmp:
275 	case OPT_fopenacc:
276 	case OPT_fcheck_pointer_bounds:
277 	  /* For selected options we can merge conservatively.  */
278 	  for (j = 0; j < *decoded_options_count; ++j)
279 	    if ((*decoded_options)[j].opt_index == foption->opt_index)
280 	      break;
281 	  if (j == *decoded_options_count)
282 	    append_option (decoded_options, decoded_options_count, foption);
283 	  /* -fmath-errno > -fno-math-errno,
284 	     -fsigned-zeros > -fno-signed-zeros,
285 	     -ftrapping-math -> -fno-trapping-math,
286 	     -fwrapv > -fno-wrapv.  */
287 	  else if (foption->value > (*decoded_options)[j].value)
288 	    (*decoded_options)[j] = *foption;
289 	  break;
290 
291 	case OPT_freg_struct_return:
292 	case OPT_fpcc_struct_return:
293 	case OPT_fshort_double:
294 	  for (j = 0; j < *decoded_options_count; ++j)
295 	    if ((*decoded_options)[j].opt_index == foption->opt_index)
296 	      break;
297 	  if (j == *decoded_options_count)
298 	    fatal_error (input_location,
299 			 "Option %s not used consistently in all LTO input"
300 			 " files", foption->orig_option_with_args_text);
301 	  break;
302 
303 	case OPT_foffload_abi_:
304 	  for (j = 0; j < *decoded_options_count; ++j)
305 	    if ((*decoded_options)[j].opt_index == foption->opt_index)
306 	      break;
307 	    if (j == *decoded_options_count)
308 	      append_option (decoded_options, decoded_options_count, foption);
309 	    else if (foption->value != (*decoded_options)[j].value)
310 	      fatal_error (input_location,
311 			   "Option %s not used consistently in all LTO input"
312 			   " files", foption->orig_option_with_args_text);
313 	    break;
314 
315 	case OPT_O:
316 	case OPT_Ofast:
317 	case OPT_Og:
318 	case OPT_Os:
319 	  for (j = 0; j < *decoded_options_count; ++j)
320 	    if ((*decoded_options)[j].opt_index == OPT_O
321 		|| (*decoded_options)[j].opt_index == OPT_Ofast
322 		|| (*decoded_options)[j].opt_index == OPT_Og
323 		|| (*decoded_options)[j].opt_index == OPT_Os)
324 	      break;
325 	  if (j == *decoded_options_count)
326 	    append_option (decoded_options, decoded_options_count, foption);
327 	  else if ((*decoded_options)[j].opt_index == foption->opt_index
328 		   && foption->opt_index != OPT_O)
329 	    /* Exact same options get merged.  */
330 	    ;
331 	  else
332 	    {
333 	      /* For mismatched option kinds preserve the optimization
334 	         level only, thus merge it as -On.  This also handles
335 		 merging of same optimization level -On.  */
336 	      int level = 0;
337 	      switch (foption->opt_index)
338 		{
339 		case OPT_O:
340 		  if (foption->arg[0] == '\0')
341 		    level = MAX (level, 1);
342 		  else
343 		    level = MAX (level, atoi (foption->arg));
344 		  break;
345 		case OPT_Ofast:
346 		  level = MAX (level, 3);
347 		  break;
348 		case OPT_Og:
349 		  level = MAX (level, 1);
350 		  break;
351 		case OPT_Os:
352 		  level = MAX (level, 2);
353 		  break;
354 		default:
355 		  gcc_unreachable ();
356 		}
357 	      switch ((*decoded_options)[j].opt_index)
358 		{
359 		case OPT_O:
360 		  if ((*decoded_options)[j].arg[0] == '\0')
361 		    level = MAX (level, 1);
362 		  else
363 		    level = MAX (level, atoi ((*decoded_options)[j].arg));
364 		  break;
365 		case OPT_Ofast:
366 		  level = MAX (level, 3);
367 		  break;
368 		case OPT_Og:
369 		  level = MAX (level, 1);
370 		  break;
371 		case OPT_Os:
372 		  level = MAX (level, 2);
373 		  break;
374 		default:
375 		  gcc_unreachable ();
376 		}
377 	      (*decoded_options)[j].opt_index = OPT_O;
378 	      char *tem;
379 	      tem = xasprintf ("-O%d", level);
380 	      (*decoded_options)[j].arg = &tem[2];
381 	      (*decoded_options)[j].canonical_option[0] = tem;
382 	      (*decoded_options)[j].value = 1;
383 	    }
384 	  break;
385 
386 	case OPT_foffload_:
387 	  append_option (decoded_options, decoded_options_count, foption);
388 	  break;
389 	}
390     }
391 }
392 
393 /* Auxiliary function that frees elements of PTR and PTR itself.
394    N is number of elements to be freed.  If PTR is NULL, nothing is freed.
395    If an element is NULL, subsequent elements are not freed.  */
396 
397 static void **
398 free_array_of_ptrs (void **ptr, unsigned n)
399 {
400   if (!ptr)
401     return NULL;
402   for (unsigned i = 0; i < n; i++)
403     {
404       if (!ptr[i])
405 	break;
406       free (ptr[i]);
407     }
408   free (ptr);
409   return NULL;
410 }
411 
412 /* Parse STR, saving found tokens into PVALUES and return their number.
413    Tokens are assumed to be delimited by ':'.  If APPEND is non-null,
414    append it to every token we find.  */
415 
416 static unsigned
417 parse_env_var (const char *str, char ***pvalues, const char *append)
418 {
419   const char *curval, *nextval;
420   char **values;
421   unsigned num = 1, i;
422 
423   curval = strchr (str, ':');
424   while (curval)
425     {
426       num++;
427       curval = strchr (curval + 1, ':');
428     }
429 
430   values = (char**) xmalloc (num * sizeof (char*));
431   curval = str;
432   nextval = strchr (curval, ':');
433   if (nextval == NULL)
434     nextval = strchr (curval, '\0');
435 
436   int append_len = append ? strlen (append) : 0;
437   for (i = 0; i < num; i++)
438     {
439       int l = nextval - curval;
440       values[i] = (char*) xmalloc (l + 1 + append_len);
441       memcpy (values[i], curval, l);
442       values[i][l] = 0;
443       if (append)
444 	strcat (values[i], append);
445       curval = nextval + 1;
446       nextval = strchr (curval, ':');
447       if (nextval == NULL)
448 	nextval = strchr (curval, '\0');
449     }
450   *pvalues = values;
451   return num;
452 }
453 
454 /* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK.  */
455 
456 static void
457 append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
458 			 unsigned int count)
459 {
460   /* Append compiler driver arguments as far as they were merged.  */
461   for (unsigned int j = 1; j < count; ++j)
462     {
463       struct cl_decoded_option *option = &opts[j];
464 
465       /* File options have been properly filtered by lto-opts.c.  */
466       switch (option->opt_index)
467 	{
468 	/* Drop arguments that we want to take from the link line.  */
469 	case OPT_flto_:
470 	case OPT_flto:
471 	case OPT_flto_partition_:
472 	  continue;
473 
474 	default:
475 	  break;
476 	}
477 
478       /* For now do what the original LTO option code was doing - pass
479 	 on any CL_TARGET flag and a few selected others.  */
480       switch (option->opt_index)
481 	{
482 	case OPT_fPIC:
483 	case OPT_fpic:
484 	case OPT_fPIE:
485 	case OPT_fpie:
486 	case OPT_fcommon:
487 	case OPT_fexceptions:
488 	case OPT_fnon_call_exceptions:
489 	case OPT_fgnu_tm:
490 	case OPT_freg_struct_return:
491 	case OPT_fpcc_struct_return:
492 	case OPT_fshort_double:
493 	case OPT_ffp_contract_:
494 	case OPT_fmath_errno:
495 	case OPT_fsigned_zeros:
496 	case OPT_ftrapping_math:
497 	case OPT_fwrapv:
498 	case OPT_fopenmp:
499 	case OPT_fopenacc:
500 	case OPT_ftrapv:
501 	case OPT_fstrict_overflow:
502 	case OPT_foffload_abi_:
503 	case OPT_O:
504 	case OPT_Ofast:
505 	case OPT_Og:
506 	case OPT_Os:
507 	case OPT_fcheck_pointer_bounds:
508 	  break;
509 
510 	default:
511 	  if (!(cl_options[option->opt_index].flags & CL_TARGET))
512 	    continue;
513 	}
514 
515       /* Pass the option on.  */
516       for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
517 	obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
518     }
519 }
520 
521 /* Append linker options OPTS to ARGV_OBSTACK.  */
522 
523 static void
524 append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
525 		       unsigned int count)
526 {
527   /* Append linker driver arguments.  Compiler options from the linker
528      driver arguments will override / merge with those from the compiler.  */
529   for (unsigned int j = 1; j < count; ++j)
530     {
531       struct cl_decoded_option *option = &opts[j];
532 
533       /* Do not pass on frontend specific flags not suitable for lto.  */
534       if (!(cl_options[option->opt_index].flags
535 	    & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
536 	continue;
537 
538       switch (option->opt_index)
539 	{
540 	case OPT_o:
541 	case OPT_flto_:
542 	case OPT_flto:
543 	  /* We've handled these LTO options, do not pass them on.  */
544 	  continue;
545 
546 	case OPT_freg_struct_return:
547 	case OPT_fpcc_struct_return:
548 	case OPT_fshort_double:
549 	  /* Ignore these, they are determined by the input files.
550 	     ???  We fail to diagnose a possible mismatch here.  */
551 	  continue;
552 
553 	default:
554 	  break;
555 	}
556 
557       /* Pass the option on.  */
558       for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
559 	obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
560     }
561 }
562 
563 /* Extract options for TARGET offload compiler from OPTIONS and append
564    them to ARGV_OBSTACK.  */
565 
566 static void
567 append_offload_options (obstack *argv_obstack, const char *target,
568 			struct cl_decoded_option *options,
569 			unsigned int options_count)
570 {
571   for (unsigned i = 0; i < options_count; i++)
572     {
573       const char *cur, *next, *opts;
574       char **argv;
575       unsigned argc;
576       struct cl_decoded_option *option = &options[i];
577 
578       if (option->opt_index != OPT_foffload_)
579 	continue;
580 
581       /* If option argument starts with '-' then no target is specified.  That
582 	 means offload options are specified for all targets, so we need to
583 	 append them.  */
584       if (option->arg[0] == '-')
585 	opts = option->arg;
586       else
587 	{
588 	  opts = strchr (option->arg, '=');
589 	  if (!opts)
590 	    continue;
591 
592 	  cur = option->arg;
593 
594 	  while (cur < opts)
595 	    {
596 	      next = strchr (cur, ',');
597 	      if (next == NULL)
598 		next = opts;
599 	      next = (next > opts) ? opts : next;
600 
601 	      if (strlen (target) == (size_t) (next - cur)
602 		  && strncmp (target, cur, next - cur) == 0)
603 		break;
604 
605 	      cur = next + 1;
606 	    }
607 
608 	  if (cur >= opts)
609 	    continue;
610 
611 	  opts++;
612 	}
613 
614       argv = buildargv (opts);
615       for (argc = 0; argv[argc]; argc++)
616 	obstack_ptr_grow (argv_obstack, argv[argc]);
617     }
618 }
619 
620 /* Check whether NAME can be accessed in MODE.  This is like access,
621    except that it never considers directories to be executable.  */
622 
623 static int
624 access_check (const char *name, int mode)
625 {
626   if (mode == X_OK)
627     {
628       struct stat st;
629 
630       if (stat (name, &st) < 0
631 	  || S_ISDIR (st.st_mode))
632 	return -1;
633     }
634 
635   return access (name, mode);
636 }
637 
638 /* Prepare a target image for offload TARGET, using mkoffload tool from
639    COMPILER_PATH.  Return the name of the resultant object file.  */
640 
641 static char *
642 compile_offload_image (const char *target, const char *compiler_path,
643 		       unsigned in_argc, char *in_argv[],
644 		       struct cl_decoded_option *compiler_opts,
645 		       unsigned int compiler_opt_count,
646 		       struct cl_decoded_option *linker_opts,
647 		       unsigned int linker_opt_count)
648 {
649   char *filename = NULL;
650   char **argv;
651   char *suffix
652     = XALLOCAVEC (char, sizeof ("/accel//mkoffload") + strlen (target));
653   strcpy (suffix, "/accel/");
654   strcat (suffix, target);
655   strcat (suffix, "/mkoffload");
656 
657   char **paths = NULL;
658   unsigned n_paths = parse_env_var (compiler_path, &paths, suffix);
659 
660   const char *compiler = NULL;
661   for (unsigned i = 0; i < n_paths; i++)
662     if (access_check (paths[i], X_OK) == 0)
663       {
664 	compiler = paths[i];
665 	break;
666       }
667 
668   if (compiler)
669     {
670       /* Generate temporary output file name.  */
671       filename = make_temp_file (".target.o");
672 
673       struct obstack argv_obstack;
674       obstack_init (&argv_obstack);
675       obstack_ptr_grow (&argv_obstack, compiler);
676       obstack_ptr_grow (&argv_obstack, "-o");
677       obstack_ptr_grow (&argv_obstack, filename);
678 
679       /* Append names of input object files.  */
680       for (unsigned i = 0; i < in_argc; i++)
681 	obstack_ptr_grow (&argv_obstack, in_argv[i]);
682 
683       /* Append options from offload_lto sections.  */
684       append_compiler_options (&argv_obstack, compiler_opts,
685 			       compiler_opt_count);
686 
687       /* Append options specified by -foffload last.  In case of conflicting
688 	 options we expect offload compiler to choose the latest.  */
689       append_offload_options (&argv_obstack, target, compiler_opts,
690 			      compiler_opt_count);
691       append_offload_options (&argv_obstack, target, linker_opts,
692 			      linker_opt_count);
693 
694       obstack_ptr_grow (&argv_obstack, NULL);
695       argv = XOBFINISH (&argv_obstack, char **);
696       fork_execute (argv[0], argv, true);
697       obstack_free (&argv_obstack, NULL);
698     }
699 
700   free_array_of_ptrs ((void **) paths, n_paths);
701   return filename;
702 }
703 
704 
705 /* The main routine dealing with offloading.
706    The routine builds a target image for each offload target.  IN_ARGC and
707    IN_ARGV specify options and input object files.  As all of them could contain
708    target sections, we pass them all to target compilers.  */
709 
710 static void
711 compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
712 				    struct cl_decoded_option *compiler_opts,
713 				    unsigned int compiler_opt_count,
714 				    struct cl_decoded_option *linker_opts,
715 				    unsigned int linker_opt_count)
716 {
717   char **names = NULL;
718   const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
719   if (!target_names)
720     return;
721   unsigned num_targets = parse_env_var (target_names, &names, NULL);
722 
723   const char *compiler_path = getenv ("COMPILER_PATH");
724   if (!compiler_path)
725     goto out;
726 
727   /* Prepare an image for each target and save the name of the resultant object
728      file to the OFFLOAD_NAMES array.  It is terminated by a NULL entry.  */
729   offload_names = XCNEWVEC (char *, num_targets + 1);
730   for (unsigned i = 0; i < num_targets; i++)
731     {
732       offload_names[i]
733 	= compile_offload_image (names[i], compiler_path, in_argc, in_argv,
734 				 compiler_opts, compiler_opt_count,
735 				 linker_opts, linker_opt_count);
736       if (!offload_names[i])
737 	fatal_error (input_location,
738 		     "problem with building target image for %s\n", names[i]);
739     }
740 
741  out:
742   free_array_of_ptrs ((void **) names, num_targets);
743 }
744 
745 /* Copy a file from SRC to DEST.  */
746 
747 static void
748 copy_file (const char *dest, const char *src)
749 {
750   FILE *d = fopen (dest, "wb");
751   FILE *s = fopen (src, "rb");
752   char buffer[512];
753   while (!feof (s))
754     {
755       size_t len = fread (buffer, 1, 512, s);
756       if (ferror (s) != 0)
757 	fatal_error (input_location, "reading input file");
758       if (len > 0)
759 	{
760 	  fwrite (buffer, 1, len, d);
761 	  if (ferror (d) != 0)
762 	    fatal_error (input_location, "writing output file");
763 	}
764     }
765 }
766 
767 /* Find the crtoffloadbegin.o and crtoffloadend.o files in LIBRARY_PATH, make
768    copies and store the names of the copies in offloadbegin and offloadend.  */
769 
770 static void
771 find_offloadbeginend (void)
772 {
773   char **paths = NULL;
774   const char *library_path = getenv ("LIBRARY_PATH");
775   if (!library_path)
776     return;
777   unsigned n_paths = parse_env_var (library_path, &paths, "/crtoffloadbegin.o");
778 
779   unsigned i;
780   for (i = 0; i < n_paths; i++)
781     if (access_check (paths[i], R_OK) == 0)
782       {
783 	size_t len = strlen (paths[i]);
784 	char *tmp = xstrdup (paths[i]);
785 	strcpy (paths[i] + len - strlen ("begin.o"), "end.o");
786 	if (access_check (paths[i], R_OK) != 0)
787 	  fatal_error (input_location,
788 		       "installation error, can't find crtoffloadend.o");
789 	/* The linker will delete the filenames we give it, so make
790 	   copies.  */
791 	offloadbegin = make_temp_file (".o");
792 	offloadend = make_temp_file (".o");
793 	copy_file (offloadbegin, tmp);
794 	copy_file (offloadend, paths[i]);
795 	free (tmp);
796 	break;
797       }
798   if (i == n_paths)
799     fatal_error (input_location,
800 		 "installation error, can't find crtoffloadbegin.o");
801 
802   free_array_of_ptrs ((void **) paths, n_paths);
803 }
804 
805 /* A subroutine of run_gcc.  Examine the open file FD for lto sections with
806    name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
807    and OPT_COUNT.  Return true if we found a matchingn section, false
808    otherwise.  COLLECT_GCC holds the value of the environment variable with
809    the same name.  */
810 
811 static bool
812 find_and_merge_options (int fd, off_t file_offset, const char *prefix,
813 			struct cl_decoded_option **opts,
814 			unsigned int *opt_count, const char *collect_gcc)
815 {
816   off_t offset, length;
817   char *data;
818   char *fopts;
819   const char *errmsg;
820   int err;
821   struct cl_decoded_option *fdecoded_options = *opts;
822   unsigned int fdecoded_options_count = *opt_count;
823 
824   simple_object_read *sobj;
825   sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
826 				   &errmsg, &err);
827   if (!sobj)
828     return false;
829 
830   char *secname = XALLOCAVEC (char, strlen (prefix) + sizeof (".opts"));
831   strcpy (secname, prefix);
832   strcat (secname, ".opts");
833   if (!simple_object_find_section (sobj, secname, &offset, &length,
834 				   &errmsg, &err))
835     {
836       simple_object_release_read (sobj);
837       return false;
838     }
839 
840   lseek (fd, file_offset + offset, SEEK_SET);
841   data = (char *)xmalloc (length);
842   read (fd, data, length);
843   fopts = data;
844   do
845     {
846       struct cl_decoded_option *f2decoded_options;
847       unsigned int f2decoded_options_count;
848       get_options_from_collect_gcc_options (collect_gcc,
849 					    fopts, CL_LANG_ALL,
850 					    &f2decoded_options,
851 					    &f2decoded_options_count);
852       if (!fdecoded_options)
853        {
854 	 fdecoded_options = f2decoded_options;
855 	 fdecoded_options_count = f2decoded_options_count;
856        }
857       else
858 	merge_and_complain (&fdecoded_options,
859 			    &fdecoded_options_count,
860 			    f2decoded_options, f2decoded_options_count);
861 
862       fopts += strlen (fopts) + 1;
863     }
864   while (fopts - data < length);
865 
866   free (data);
867   simple_object_release_read (sobj);
868   *opts = fdecoded_options;
869   *opt_count = fdecoded_options_count;
870   return true;
871 }
872 
873 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
874 
875 static void
876 run_gcc (unsigned argc, char *argv[])
877 {
878   unsigned i, j;
879   const char **new_argv;
880   const char **argv_ptr;
881   char *list_option_full = NULL;
882   const char *linker_output = NULL;
883   const char *collect_gcc, *collect_gcc_options;
884   int parallel = 0;
885   int jobserver = 0;
886   bool no_partition = false;
887   struct cl_decoded_option *fdecoded_options = NULL;
888   struct cl_decoded_option *offload_fdecoded_options = NULL;
889   unsigned int fdecoded_options_count = 0;
890   unsigned int offload_fdecoded_options_count = 0;
891   struct cl_decoded_option *decoded_options;
892   unsigned int decoded_options_count;
893   struct obstack argv_obstack;
894   int new_head_argc;
895   bool have_lto = false;
896   bool have_offload = false;
897   unsigned lto_argc = 0, offload_argc = 0;
898   char **lto_argv, **offload_argv;
899 
900   /* Get the driver and options.  */
901   collect_gcc = getenv ("COLLECT_GCC");
902   if (!collect_gcc)
903     fatal_error (input_location,
904 		 "environment variable COLLECT_GCC must be set");
905   collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
906   if (!collect_gcc_options)
907     fatal_error (input_location,
908 		 "environment variable COLLECT_GCC_OPTIONS must be set");
909   get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
910 					CL_LANG_ALL,
911 					&decoded_options,
912 					&decoded_options_count);
913 
914   /* Allocate arrays for input object files with LTO or offload IL,
915      and for possible preceding arguments.  */
916   lto_argv = XNEWVEC (char *, argc);
917   offload_argv = XNEWVEC (char *, argc);
918 
919   /* Look at saved options in the IL files.  */
920   for (i = 1; i < argc; ++i)
921     {
922       char *p;
923       int fd;
924       off_t file_offset = 0;
925       long loffset;
926       int consumed;
927       char *filename = argv[i];
928 
929       if ((p = strrchr (argv[i], '@'))
930 	  && p != argv[i]
931 	  && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
932 	  && strlen (p) == (unsigned int) consumed)
933 	{
934 	  filename = XNEWVEC (char, p - argv[i] + 1);
935 	  memcpy (filename, argv[i], p - argv[i]);
936 	  filename[p - argv[i]] = '\0';
937 	  file_offset = (off_t) loffset;
938 	}
939       fd = open (filename, O_RDONLY | O_BINARY);
940       if (fd == -1)
941 	{
942 	  lto_argv[lto_argc++] = argv[i];
943 	  continue;
944 	}
945 
946       if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
947 				  &fdecoded_options, &fdecoded_options_count,
948 				  collect_gcc))
949 	{
950 	  have_lto = true;
951 	  lto_argv[lto_argc++] = argv[i];
952 	}
953 
954       if (find_and_merge_options (fd, file_offset, OFFLOAD_SECTION_NAME_PREFIX,
955 				  &offload_fdecoded_options,
956 				  &offload_fdecoded_options_count, collect_gcc))
957 	{
958 	  have_offload = true;
959 	  offload_argv[offload_argc++] = argv[i];
960 	}
961 
962       close (fd);
963     }
964 
965   /* Initalize the common arguments for the driver.  */
966   obstack_init (&argv_obstack);
967   obstack_ptr_grow (&argv_obstack, collect_gcc);
968   obstack_ptr_grow (&argv_obstack, "-xlto");
969   obstack_ptr_grow (&argv_obstack, "-c");
970 
971   append_compiler_options (&argv_obstack, fdecoded_options,
972 			   fdecoded_options_count);
973   append_linker_options (&argv_obstack, decoded_options, decoded_options_count);
974 
975   /* Scan linker driver arguments for things that are of relevance to us.  */
976   for (j = 1; j < decoded_options_count; ++j)
977     {
978       struct cl_decoded_option *option = &decoded_options[j];
979       switch (option->opt_index)
980 	{
981 	case OPT_o:
982 	  linker_output = option->arg;
983 	  break;
984 
985 	case OPT_save_temps:
986 	  save_temps = 1;
987 	  break;
988 
989 	case OPT_v:
990 	  verbose = 1;
991 	  break;
992 
993 	case OPT_flto_partition_:
994 	  if (strcmp (option->arg, "none") == 0)
995 	    no_partition = true;
996 	  break;
997 
998 	case OPT_flto_:
999 	  if (strcmp (option->arg, "jobserver") == 0)
1000 	    {
1001 	      jobserver = 1;
1002 	      parallel = 1;
1003 	    }
1004 	  else
1005 	    {
1006 	      parallel = atoi (option->arg);
1007 	      if (parallel <= 1)
1008 		parallel = 0;
1009 	    }
1010 	  /* Fallthru.  */
1011 
1012 	case OPT_flto:
1013 	  lto_mode = LTO_MODE_WHOPR;
1014 	  break;
1015 
1016 	default:
1017 	  break;
1018 	}
1019     }
1020 
1021   if (no_partition)
1022     {
1023       lto_mode = LTO_MODE_LTO;
1024       jobserver = 0;
1025       parallel = 0;
1026     }
1027 
1028   if (linker_output)
1029     {
1030       char *output_dir, *base, *name;
1031       bool bit_bucket = strcmp (linker_output, HOST_BIT_BUCKET) == 0;
1032 
1033       output_dir = xstrdup (linker_output);
1034       base = output_dir;
1035       for (name = base; *name; name++)
1036 	if (IS_DIR_SEPARATOR (*name))
1037 	  base = name + 1;
1038       *base = '\0';
1039 
1040       linker_output = &linker_output[base - output_dir];
1041       if (*output_dir == '\0')
1042 	{
1043 	  static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
1044 	  output_dir = current_dir;
1045 	}
1046       if (!bit_bucket)
1047 	{
1048 	  obstack_ptr_grow (&argv_obstack, "-dumpdir");
1049 	  obstack_ptr_grow (&argv_obstack, output_dir);
1050 	}
1051 
1052       obstack_ptr_grow (&argv_obstack, "-dumpbase");
1053     }
1054 
1055   /* Remember at which point we can scrub args to re-use the commons.  */
1056   new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
1057 
1058   if (have_offload)
1059     {
1060       compile_images_for_offload_targets (offload_argc, offload_argv,
1061 					  offload_fdecoded_options,
1062 					  offload_fdecoded_options_count,
1063 					  decoded_options,
1064 					  decoded_options_count);
1065       if (offload_names)
1066 	{
1067 	  find_offloadbeginend ();
1068 	  for (i = 0; offload_names[i]; i++)
1069 	    printf ("%s\n", offload_names[i]);
1070 	  free_array_of_ptrs ((void **) offload_names, i);
1071 	}
1072     }
1073 
1074   if (offloadbegin)
1075     printf ("%s\n", offloadbegin);
1076 
1077   /* If object files contain offload sections, but do not contain LTO sections,
1078      then there is no need to perform a link-time recompilation, i.e.
1079      lto-wrapper is used only for a compilation of offload images.  */
1080   if (have_offload && !have_lto)
1081     {
1082       for (i = 1; i < argc; ++i)
1083 	if (strncmp (argv[i], "-fresolution=", sizeof ("-fresolution=") - 1))
1084 	  {
1085 	    char *out_file;
1086 	    /* Can be ".o" or ".so".  */
1087 	    char *ext = strrchr (argv[i], '.');
1088 	    if (ext == NULL)
1089 	      out_file = make_temp_file ("");
1090 	    else
1091 	      out_file = make_temp_file (ext);
1092 	    /* The linker will delete the files we give it, so make copies.  */
1093 	    copy_file (out_file, argv[i]);
1094 	    printf ("%s\n", out_file);
1095 	  }
1096       goto finish;
1097     }
1098 
1099   if (lto_mode == LTO_MODE_LTO)
1100     {
1101       flto_out = make_temp_file (".lto.o");
1102       if (linker_output)
1103 	obstack_ptr_grow (&argv_obstack, linker_output);
1104       obstack_ptr_grow (&argv_obstack, "-o");
1105       obstack_ptr_grow (&argv_obstack, flto_out);
1106     }
1107   else
1108     {
1109       const char *list_option = "-fltrans-output-list=";
1110       size_t list_option_len = strlen (list_option);
1111       char *tmp;
1112 
1113       if (linker_output)
1114 	{
1115 	  char *dumpbase = (char *) xmalloc (strlen (linker_output)
1116 					     + sizeof (".wpa") + 1);
1117 	  strcpy (dumpbase, linker_output);
1118 	  strcat (dumpbase, ".wpa");
1119 	  obstack_ptr_grow (&argv_obstack, dumpbase);
1120 	}
1121 
1122       if (linker_output && save_temps)
1123 	{
1124 	  ltrans_output_file = (char *) xmalloc (strlen (linker_output)
1125 						 + sizeof (".ltrans.out") + 1);
1126 	  strcpy (ltrans_output_file, linker_output);
1127 	  strcat (ltrans_output_file, ".ltrans.out");
1128 	}
1129       else
1130 	ltrans_output_file = make_temp_file (".ltrans.out");
1131       list_option_full = (char *) xmalloc (sizeof (char) *
1132 		         (strlen (ltrans_output_file) + list_option_len + 1));
1133       tmp = list_option_full;
1134 
1135       obstack_ptr_grow (&argv_obstack, tmp);
1136       strcpy (tmp, list_option);
1137       tmp += list_option_len;
1138       strcpy (tmp, ltrans_output_file);
1139 
1140       if (jobserver)
1141 	obstack_ptr_grow (&argv_obstack, xstrdup ("-fwpa=jobserver"));
1142       else if (parallel > 1)
1143 	{
1144 	  char buf[256];
1145 	  sprintf (buf, "-fwpa=%i", parallel);
1146 	  obstack_ptr_grow (&argv_obstack, xstrdup (buf));
1147 	}
1148       else
1149         obstack_ptr_grow (&argv_obstack, "-fwpa");
1150     }
1151 
1152   /* Append the input objects and possible preceding arguments.  */
1153   for (i = 0; i < lto_argc; ++i)
1154     obstack_ptr_grow (&argv_obstack, lto_argv[i]);
1155   obstack_ptr_grow (&argv_obstack, NULL);
1156 
1157   new_argv = XOBFINISH (&argv_obstack, const char **);
1158   argv_ptr = &new_argv[new_head_argc];
1159   fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true);
1160 
1161   if (lto_mode == LTO_MODE_LTO)
1162     {
1163       printf ("%s\n", flto_out);
1164       free (flto_out);
1165       flto_out = NULL;
1166     }
1167   else
1168     {
1169       FILE *stream = fopen (ltrans_output_file, "r");
1170       FILE *mstream = NULL;
1171       struct obstack env_obstack;
1172 
1173       if (!stream)
1174 	fatal_error (input_location, "fopen: %s: %m", ltrans_output_file);
1175 
1176       /* Parse the list of LTRANS inputs from the WPA stage.  */
1177       obstack_init (&env_obstack);
1178       nr = 0;
1179       for (;;)
1180 	{
1181 	  const unsigned piece = 32;
1182 	  char *output_name = NULL;
1183 	  char *buf, *input_name = (char *)xmalloc (piece);
1184 	  size_t len;
1185 
1186 	  buf = input_name;
1187 cont:
1188 	  if (!fgets (buf, piece, stream))
1189 	    break;
1190 	  len = strlen (input_name);
1191 	  if (input_name[len - 1] != '\n')
1192 	    {
1193 	      input_name = (char *)xrealloc (input_name, len + piece);
1194 	      buf = input_name + len;
1195 	      goto cont;
1196 	    }
1197 	  input_name[len - 1] = '\0';
1198 
1199 	  if (input_name[0] == '*')
1200 	    output_name = &input_name[1];
1201 
1202 	  nr++;
1203 	  input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
1204 	  output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
1205 	  input_names[nr-1] = input_name;
1206 	  output_names[nr-1] = output_name;
1207 	}
1208       fclose (stream);
1209       maybe_unlink (ltrans_output_file);
1210       ltrans_output_file = NULL;
1211 
1212       if (parallel)
1213 	{
1214 	  makefile = make_temp_file (".mk");
1215 	  mstream = fopen (makefile, "w");
1216 	}
1217 
1218       /* Execute the LTRANS stage for each input file (or prepare a
1219 	 makefile to invoke this in parallel).  */
1220       for (i = 0; i < nr; ++i)
1221 	{
1222 	  char *output_name;
1223 	  char *input_name = input_names[i];
1224 	  /* If it's a pass-through file do nothing.  */
1225 	  if (output_names[i])
1226 	    continue;
1227 
1228 	  /* Replace the .o suffix with a .ltrans.o suffix and write
1229 	     the resulting name to the LTRANS output list.  */
1230 	  obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
1231 	  obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
1232 	  output_name = XOBFINISH (&env_obstack, char *);
1233 
1234 	  /* Adjust the dumpbase if the linker output file was seen.  */
1235 	  if (linker_output)
1236 	    {
1237 	      char *dumpbase
1238 		  = (char *) xmalloc (strlen (linker_output)
1239 				      + sizeof (DUMPBASE_SUFFIX) + 1);
1240 	      snprintf (dumpbase,
1241 			strlen (linker_output) + sizeof (DUMPBASE_SUFFIX),
1242 			"%s.ltrans%u", linker_output, i);
1243 	      argv_ptr[0] = dumpbase;
1244 	    }
1245 
1246 	  argv_ptr[1] = "-fltrans";
1247 	  argv_ptr[2] = "-o";
1248 	  argv_ptr[3] = output_name;
1249 	  argv_ptr[4] = input_name;
1250 	  argv_ptr[5] = NULL;
1251 	  if (parallel)
1252 	    {
1253 	      fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
1254 	      for (j = 1; new_argv[j] != NULL; ++j)
1255 		fprintf (mstream, " '%s'", new_argv[j]);
1256 	      fprintf (mstream, "\n");
1257 	      /* If we are not preserving the ltrans input files then
1258 	         truncate them as soon as we have processed it.  This
1259 		 reduces temporary disk-space usage.  */
1260 	      if (! save_temps)
1261 		fprintf (mstream, "\t@-touch -r %s %s.tem > /dev/null 2>&1 "
1262 			 "&& mv %s.tem %s\n",
1263 			 input_name, input_name, input_name, input_name);
1264 	    }
1265 	  else
1266 	    {
1267 	      fork_execute (new_argv[0], CONST_CAST (char **, new_argv),
1268 			    true);
1269 	      maybe_unlink (input_name);
1270 	    }
1271 
1272 	  output_names[i] = output_name;
1273 	}
1274       if (parallel)
1275 	{
1276 	  struct pex_obj *pex;
1277 	  char jobs[32];
1278 
1279 	  fprintf (mstream, "all:");
1280 	  for (i = 0; i < nr; ++i)
1281 	    fprintf (mstream, " \\\n\t%s", output_names[i]);
1282 	  fprintf (mstream, "\n");
1283 	  fclose (mstream);
1284 	  if (!jobserver)
1285 	    {
1286 	      /* Avoid passing --jobserver-fd= and similar flags
1287 		 unless jobserver mode is explicitly enabled.  */
1288 	      putenv (xstrdup ("MAKEFLAGS="));
1289 	      putenv (xstrdup ("MFLAGS="));
1290 	    }
1291 	  new_argv[0] = getenv ("MAKE");
1292 	  if (!new_argv[0])
1293 	    new_argv[0] = "make";
1294 	  new_argv[1] = "-f";
1295 	  new_argv[2] = makefile;
1296 	  i = 3;
1297 	  if (!jobserver)
1298 	    {
1299 	      snprintf (jobs, 31, "-j%d", parallel);
1300 	      new_argv[i++] = jobs;
1301 	    }
1302 	  new_argv[i++] = "all";
1303 	  new_argv[i++] = NULL;
1304 	  pex = collect_execute (new_argv[0], CONST_CAST (char **, new_argv),
1305 				 NULL, NULL, PEX_SEARCH, false);
1306 	  do_wait (new_argv[0], pex);
1307 	  maybe_unlink (makefile);
1308 	  makefile = NULL;
1309 	  for (i = 0; i < nr; ++i)
1310 	    maybe_unlink (input_names[i]);
1311 	}
1312       for (i = 0; i < nr; ++i)
1313 	{
1314 	  fputs (output_names[i], stdout);
1315 	  putc ('\n', stdout);
1316 	  free (input_names[i]);
1317 	}
1318       nr = 0;
1319       free (output_names);
1320       free (input_names);
1321       free (list_option_full);
1322       obstack_free (&env_obstack, NULL);
1323     }
1324 
1325  finish:
1326   if (offloadend)
1327     printf ("%s\n", offloadend);
1328 
1329   XDELETE (lto_argv);
1330   XDELETE (offload_argv);
1331   obstack_free (&argv_obstack, NULL);
1332 }
1333 
1334 
1335 /* Entry point.  */
1336 
1337 int
1338 main (int argc, char *argv[])
1339 {
1340   const char *p;
1341 
1342   gcc_obstack_init (&opts_obstack);
1343 
1344   p = argv[0] + strlen (argv[0]);
1345   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
1346     --p;
1347   progname = p;
1348 
1349   xmalloc_set_program_name (progname);
1350 
1351   gcc_init_libintl ();
1352 
1353   diagnostic_initialize (global_dc, 0);
1354 
1355   if (atexit (lto_wrapper_cleanup) != 0)
1356     fatal_error (input_location, "atexit failed");
1357 
1358   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1359     signal (SIGINT, fatal_signal);
1360 #ifdef SIGHUP
1361   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1362     signal (SIGHUP, fatal_signal);
1363 #endif
1364   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
1365     signal (SIGTERM, fatal_signal);
1366 #ifdef SIGPIPE
1367   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
1368     signal (SIGPIPE, fatal_signal);
1369 #endif
1370 #ifdef SIGCHLD
1371   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
1372      receive the signal.  A different setting is inheritable */
1373   signal (SIGCHLD, SIG_DFL);
1374 #endif
1375 
1376   /* We may be called with all the arguments stored in some file and
1377      passed with @file.  Expand them into argv before processing.  */
1378   expandargv (&argc, &argv);
1379 
1380   run_gcc (argc, argv);
1381 
1382   return 0;
1383 }
1384