1 /* Wrapper to call lto. Used by collect2 and the linker plugin.
2 Copyright (C) 2009-2014 Free Software Foundation, Inc.
4 Factored out of collect2 by Rafael Espindola <espindola@google.com>
6 This file is part of GCC.
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
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
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/>. */
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.
30 $ lto-wrapper gcc/xgcc -B gcc a.o b.o -o test -flto
32 The above will print something like
35 If WHOPR is used instead, more than one file might be produced
36 ./ccXj2DTk.lto.ltrans.o
37 ./ccCJuXGv.lto.ltrans.o
42 #include "coretypes.h"
44 #include "diagnostic.h"
48 #include "simple-object.h"
49 #include "lto-section-names.h"
50 #include "collect-utils.h"
53 LTO_MODE_NONE
, /* Not doing LTO. */
54 LTO_MODE_LTO
, /* Normal LTO. */
55 LTO_MODE_WHOPR
/* WHOPR. */
58 /* Current LTO mode. */
59 static enum lto_mode_d lto_mode
= LTO_MODE_NONE
;
61 static char *ltrans_output_file
;
62 static char *flto_out
;
63 static unsigned int nr
;
64 static char **input_names
;
65 static char **output_names
;
66 static char *makefile
;
68 const char tool_name
[] = "lto-wrapper";
70 /* Delete tempfiles. Called from utils_cleanup. */
77 if (ltrans_output_file
)
78 maybe_unlink (ltrans_output_file
);
80 maybe_unlink (flto_out
);
82 maybe_unlink (makefile
);
83 for (i
= 0; i
< nr
; ++i
)
85 maybe_unlink (input_names
[i
]);
87 maybe_unlink (output_names
[i
]);
92 lto_wrapper_cleanup (void)
94 utils_cleanup (false);
97 /* Unlink a temporary LTRANS file unless requested otherwise. */
100 maybe_unlink (const char *file
)
104 if (unlink_if_ordinary (file
)
106 fatal_error ("deleting LTRANS file %s: %m", file
);
109 fprintf (stderr
, "[Leaving LTRANS %s]\n", file
);
112 /* Template of LTRANS dumpbase suffix. */
113 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
115 /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
116 environment according to LANG_MASK. */
119 get_options_from_collect_gcc_options (const char *collect_gcc
,
120 const char *collect_gcc_options
,
121 unsigned int lang_mask
,
122 struct cl_decoded_option
**decoded_options
,
123 unsigned int *decoded_options_count
)
125 struct obstack argv_obstack
;
130 argv_storage
= xstrdup (collect_gcc_options
);
131 obstack_init (&argv_obstack
);
132 obstack_ptr_grow (&argv_obstack
, collect_gcc
);
134 for (j
= 0, k
= 0; argv_storage
[j
] != '\0'; ++j
)
136 if (argv_storage
[j
] == '\'')
138 obstack_ptr_grow (&argv_obstack
, &argv_storage
[k
]);
142 if (argv_storage
[j
] == '\0')
143 fatal_error ("malformed COLLECT_GCC_OPTIONS");
144 else if (strncmp (&argv_storage
[j
], "'\\''", 4) == 0)
146 argv_storage
[k
++] = '\'';
149 else if (argv_storage
[j
] == '\'')
152 argv_storage
[k
++] = argv_storage
[j
++];
155 argv_storage
[k
++] = '\0';
159 obstack_ptr_grow (&argv_obstack
, NULL
);
160 argc
= obstack_object_size (&argv_obstack
) / sizeof (void *) - 1;
161 argv
= XOBFINISH (&argv_obstack
, const char **);
163 decode_cmdline_options_to_array (argc
, (const char **)argv
,
165 decoded_options
, decoded_options_count
);
166 obstack_free (&argv_obstack
, NULL
);
169 /* Append OPTION to the options array DECODED_OPTIONS with size
170 DECODED_OPTIONS_COUNT. */
173 append_option (struct cl_decoded_option
**decoded_options
,
174 unsigned int *decoded_options_count
,
175 struct cl_decoded_option
*option
)
177 ++*decoded_options_count
;
179 = (struct cl_decoded_option
*)
180 xrealloc (*decoded_options
,
181 (*decoded_options_count
182 * sizeof (struct cl_decoded_option
)));
183 memcpy (&(*decoded_options
)[*decoded_options_count
- 1], option
,
184 sizeof (struct cl_decoded_option
));
187 /* Try to merge and complain about options FDECODED_OPTIONS when applied
188 ontop of DECODED_OPTIONS. */
191 merge_and_complain (struct cl_decoded_option
**decoded_options
,
192 unsigned int *decoded_options_count
,
193 struct cl_decoded_option
*fdecoded_options
,
194 unsigned int fdecoded_options_count
)
198 /* ??? Merge options from files. Most cases can be
199 handled by either unioning or intersecting
200 (for example -fwrapv is a case for unioning,
201 -ffast-math is for intersection). Most complaints
202 about real conflicts between different options can
203 be deferred to the compiler proper. Options that
204 we can neither safely handle by intersection nor
205 unioning would need to be complained about here.
206 Ideally we'd have a flag in the opt files that
207 tells whether to union or intersect or reject.
208 In absence of that it's unclear what a good default is.
209 It's also difficult to get positional handling correct. */
211 /* The following does what the old LTO option code did,
212 union all target and a selected set of common options. */
213 for (i
= 0; i
< fdecoded_options_count
; ++i
)
215 struct cl_decoded_option
*foption
= &fdecoded_options
[i
];
216 switch (foption
->opt_index
)
218 case OPT_SPECIAL_unknown
:
219 case OPT_SPECIAL_ignore
:
220 case OPT_SPECIAL_program_name
:
221 case OPT_SPECIAL_input_file
:
225 if (!(cl_options
[foption
->opt_index
].flags
& CL_TARGET
))
234 case OPT_fexceptions
:
235 case OPT_fnon_call_exceptions
:
237 /* Do what the old LTO code did - collect exactly one option
238 setting per OPT code, we pick the first we encounter.
239 ??? This doesn't make too much sense, but when it doesn't
240 then we should complain. */
241 for (j
= 0; j
< *decoded_options_count
; ++j
)
242 if ((*decoded_options
)[j
].opt_index
== foption
->opt_index
)
244 if (j
== *decoded_options_count
)
245 append_option (decoded_options
, decoded_options_count
, foption
);
249 case OPT_fstrict_overflow
:
250 case OPT_ffp_contract_
:
251 /* For selected options we can merge conservatively. */
252 for (j
= 0; j
< *decoded_options_count
; ++j
)
253 if ((*decoded_options
)[j
].opt_index
== foption
->opt_index
)
255 if (j
== *decoded_options_count
)
256 append_option (decoded_options
, decoded_options_count
, foption
);
257 /* FP_CONTRACT_OFF < FP_CONTRACT_ON < FP_CONTRACT_FAST,
258 -fno-trapv < -ftrapv,
259 -fno-strict-overflow < -fstrict-overflow */
260 else if (foption
->value
< (*decoded_options
)[j
].value
)
261 (*decoded_options
)[j
] = *foption
;
265 /* For selected options we can merge conservatively. */
266 for (j
= 0; j
< *decoded_options_count
; ++j
)
267 if ((*decoded_options
)[j
].opt_index
== foption
->opt_index
)
269 if (j
== *decoded_options_count
)
270 append_option (decoded_options
, decoded_options_count
, foption
);
271 /* -fwrapv > -fno-wrapv. */
272 else if (foption
->value
> (*decoded_options
)[j
].value
)
273 (*decoded_options
)[j
] = *foption
;
276 case OPT_freg_struct_return
:
277 case OPT_fpcc_struct_return
:
278 case OPT_fshort_double
:
279 for (j
= 0; j
< *decoded_options_count
; ++j
)
280 if ((*decoded_options
)[j
].opt_index
== foption
->opt_index
)
282 if (j
== *decoded_options_count
)
283 fatal_error ("Option %s not used consistently in all LTO input"
284 " files", foption
->orig_option_with_args_text
);
291 for (j
= 0; j
< *decoded_options_count
; ++j
)
292 if ((*decoded_options
)[j
].opt_index
== OPT_O
293 || (*decoded_options
)[j
].opt_index
== OPT_Ofast
294 || (*decoded_options
)[j
].opt_index
== OPT_Og
295 || (*decoded_options
)[j
].opt_index
== OPT_Os
)
297 if (j
== *decoded_options_count
)
298 append_option (decoded_options
, decoded_options_count
, foption
);
299 else if ((*decoded_options
)[j
].opt_index
== foption
->opt_index
300 && foption
->opt_index
!= OPT_O
)
301 /* Exact same options get merged. */
305 /* For mismatched option kinds preserve the optimization
306 level only, thus merge it as -On. This also handles
307 merging of same optimization level -On. */
309 switch (foption
->opt_index
)
312 if (foption
->arg
[0] == '\0')
313 level
= MAX (level
, 1);
315 level
= MAX (level
, atoi (foption
->arg
));
318 level
= MAX (level
, 3);
321 level
= MAX (level
, 1);
324 level
= MAX (level
, 2);
329 switch ((*decoded_options
)[j
].opt_index
)
332 if ((*decoded_options
)[j
].arg
[0] == '\0')
333 level
= MAX (level
, 1);
335 level
= MAX (level
, atoi ((*decoded_options
)[j
].arg
));
338 level
= MAX (level
, 3);
341 level
= MAX (level
, 1);
344 level
= MAX (level
, 2);
349 (*decoded_options
)[j
].opt_index
= OPT_O
;
351 asprintf (&tem
, "-O%d", level
);
352 (*decoded_options
)[j
].arg
= &tem
[2];
353 (*decoded_options
)[j
].canonical_option
[0] = tem
;
354 (*decoded_options
)[j
].value
= 1;
361 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
364 run_gcc (unsigned argc
, char *argv
[])
367 const char **new_argv
;
368 const char **argv_ptr
;
369 char *list_option_full
= NULL
;
370 const char *linker_output
= NULL
;
371 const char *collect_gcc
, *collect_gcc_options
;
374 bool no_partition
= false;
375 struct cl_decoded_option
*fdecoded_options
= NULL
;
376 unsigned int fdecoded_options_count
= 0;
377 struct cl_decoded_option
*decoded_options
;
378 unsigned int decoded_options_count
;
379 struct obstack argv_obstack
;
382 /* Get the driver and options. */
383 collect_gcc
= getenv ("COLLECT_GCC");
385 fatal_error ("environment variable COLLECT_GCC must be set");
386 collect_gcc_options
= getenv ("COLLECT_GCC_OPTIONS");
387 if (!collect_gcc_options
)
388 fatal_error ("environment variable COLLECT_GCC_OPTIONS must be set");
389 get_options_from_collect_gcc_options (collect_gcc
, collect_gcc_options
,
392 &decoded_options_count
);
394 /* Look at saved options in the IL files. */
395 for (i
= 1; i
< argc
; ++i
)
402 off_t file_offset
= 0, offset
, length
;
404 simple_object_read
*sobj
;
406 struct cl_decoded_option
*f2decoded_options
;
407 unsigned int f2decoded_options_count
;
408 char *filename
= argv
[i
];
409 if ((p
= strrchr (argv
[i
], '@'))
411 && sscanf (p
, "@%li%n", &loffset
, &consumed
) >= 1
412 && strlen (p
) == (unsigned int) consumed
)
414 filename
= XNEWVEC (char, p
- argv
[i
] + 1);
415 memcpy (filename
, argv
[i
], p
- argv
[i
]);
416 filename
[p
- argv
[i
]] = '\0';
417 file_offset
= (off_t
) loffset
;
419 fd
= open (argv
[i
], O_RDONLY
);
422 sobj
= simple_object_start_read (fd
, file_offset
, "__GNU_LTO",
429 if (!simple_object_find_section (sobj
, LTO_SECTION_NAME_PREFIX
"." "opts",
430 &offset
, &length
, &errmsg
, &err
))
432 simple_object_release_read (sobj
);
436 lseek (fd
, file_offset
+ offset
, SEEK_SET
);
437 data
= (char *)xmalloc (length
);
438 read (fd
, data
, length
);
442 get_options_from_collect_gcc_options (collect_gcc
,
445 &f2decoded_options_count
);
446 if (!fdecoded_options
)
448 fdecoded_options
= f2decoded_options
;
449 fdecoded_options_count
= f2decoded_options_count
;
452 merge_and_complain (&fdecoded_options
,
453 &fdecoded_options_count
,
454 f2decoded_options
, f2decoded_options_count
);
456 fopts
+= strlen (fopts
) + 1;
458 while (fopts
- data
< length
);
461 simple_object_release_read (sobj
);
465 /* Initalize the common arguments for the driver. */
466 obstack_init (&argv_obstack
);
467 obstack_ptr_grow (&argv_obstack
, collect_gcc
);
468 obstack_ptr_grow (&argv_obstack
, "-xlto");
469 obstack_ptr_grow (&argv_obstack
, "-c");
471 /* Append compiler driver arguments as far as they were merged. */
472 for (j
= 1; j
< fdecoded_options_count
; ++j
)
474 struct cl_decoded_option
*option
= &fdecoded_options
[j
];
476 /* File options have been properly filtered by lto-opts.c. */
477 switch (option
->opt_index
)
479 /* Drop arguments that we want to take from the link line. */
482 case OPT_flto_partition_
:
489 /* For now do what the original LTO option code was doing - pass
490 on any CL_TARGET flag and a few selected others. */
491 switch (option
->opt_index
)
498 case OPT_fexceptions
:
499 case OPT_fnon_call_exceptions
:
501 case OPT_freg_struct_return
:
502 case OPT_fpcc_struct_return
:
503 case OPT_fshort_double
:
504 case OPT_ffp_contract_
:
507 case OPT_fstrict_overflow
:
515 if (!(cl_options
[option
->opt_index
].flags
& CL_TARGET
))
519 /* Pass the option on. */
520 for (i
= 0; i
< option
->canonical_option_num_elements
; ++i
)
521 obstack_ptr_grow (&argv_obstack
, option
->canonical_option
[i
]);
524 /* Append linker driver arguments. Compiler options from the linker
525 driver arguments will override / merge with those from the compiler. */
526 for (j
= 1; j
< decoded_options_count
; ++j
)
528 struct cl_decoded_option
*option
= &decoded_options
[j
];
530 /* Do not pass on frontend specific flags not suitable for lto. */
531 if (!(cl_options
[option
->opt_index
].flags
532 & (CL_COMMON
|CL_TARGET
|CL_DRIVER
|CL_LTO
)))
535 switch (option
->opt_index
)
538 linker_output
= option
->arg
;
539 /* We generate new intermediate output, drop this arg. */
550 case OPT_flto_partition_
:
551 if (strcmp (option
->arg
, "none") == 0)
556 if (strcmp (option
->arg
, "jobserver") == 0)
563 parallel
= atoi (option
->arg
);
570 lto_mode
= LTO_MODE_WHOPR
;
571 /* We've handled these LTO options, do not pass them on. */
574 case OPT_freg_struct_return
:
575 case OPT_fpcc_struct_return
:
576 case OPT_fshort_double
:
577 /* Ignore these, they are determined by the input files.
578 ??? We fail to diagnose a possible mismatch here. */
585 /* Pass the option on. */
586 for (i
= 0; i
< option
->canonical_option_num_elements
; ++i
)
587 obstack_ptr_grow (&argv_obstack
, option
->canonical_option
[i
]);
592 lto_mode
= LTO_MODE_LTO
;
599 char *output_dir
, *base
, *name
;
600 bool bit_bucket
= strcmp (linker_output
, HOST_BIT_BUCKET
) == 0;
602 output_dir
= xstrdup (linker_output
);
604 for (name
= base
; *name
; name
++)
605 if (IS_DIR_SEPARATOR (*name
))
609 linker_output
= &linker_output
[base
- output_dir
];
610 if (*output_dir
== '\0')
612 static char current_dir
[] = { '.', DIR_SEPARATOR
, '\0' };
613 output_dir
= current_dir
;
617 obstack_ptr_grow (&argv_obstack
, "-dumpdir");
618 obstack_ptr_grow (&argv_obstack
, output_dir
);
621 obstack_ptr_grow (&argv_obstack
, "-dumpbase");
624 /* Remember at which point we can scrub args to re-use the commons. */
625 new_head_argc
= obstack_object_size (&argv_obstack
) / sizeof (void *);
627 if (lto_mode
== LTO_MODE_LTO
)
629 flto_out
= make_temp_file (".lto.o");
631 obstack_ptr_grow (&argv_obstack
, linker_output
);
632 obstack_ptr_grow (&argv_obstack
, "-o");
633 obstack_ptr_grow (&argv_obstack
, flto_out
);
637 const char *list_option
= "-fltrans-output-list=";
638 size_t list_option_len
= strlen (list_option
);
643 char *dumpbase
= (char *) xmalloc (strlen (linker_output
)
644 + sizeof (".wpa") + 1);
645 strcpy (dumpbase
, linker_output
);
646 strcat (dumpbase
, ".wpa");
647 obstack_ptr_grow (&argv_obstack
, dumpbase
);
650 if (linker_output
&& save_temps
)
652 ltrans_output_file
= (char *) xmalloc (strlen (linker_output
)
653 + sizeof (".ltrans.out") + 1);
654 strcpy (ltrans_output_file
, linker_output
);
655 strcat (ltrans_output_file
, ".ltrans.out");
658 ltrans_output_file
= make_temp_file (".ltrans.out");
659 list_option_full
= (char *) xmalloc (sizeof (char) *
660 (strlen (ltrans_output_file
) + list_option_len
+ 1));
661 tmp
= list_option_full
;
663 obstack_ptr_grow (&argv_obstack
, tmp
);
664 strcpy (tmp
, list_option
);
665 tmp
+= list_option_len
;
666 strcpy (tmp
, ltrans_output_file
);
669 obstack_ptr_grow (&argv_obstack
, xstrdup ("-fwpa=jobserver"));
670 else if (parallel
> 1)
673 sprintf (buf
, "-fwpa=%i", parallel
);
674 obstack_ptr_grow (&argv_obstack
, xstrdup (buf
));
677 obstack_ptr_grow (&argv_obstack
, "-fwpa");
680 /* Append the input objects and possible preceding arguments. */
681 for (i
= 1; i
< argc
; ++i
)
682 obstack_ptr_grow (&argv_obstack
, argv
[i
]);
683 obstack_ptr_grow (&argv_obstack
, NULL
);
685 new_argv
= XOBFINISH (&argv_obstack
, const char **);
686 argv_ptr
= &new_argv
[new_head_argc
];
687 fork_execute (new_argv
[0], CONST_CAST (char **, new_argv
), true);
689 if (lto_mode
== LTO_MODE_LTO
)
691 printf ("%s\n", flto_out
);
697 FILE *stream
= fopen (ltrans_output_file
, "r");
698 FILE *mstream
= NULL
;
699 struct obstack env_obstack
;
702 fatal_error ("fopen: %s: %m", ltrans_output_file
);
704 /* Parse the list of LTRANS inputs from the WPA stage. */
705 obstack_init (&env_obstack
);
709 const unsigned piece
= 32;
710 char *output_name
= NULL
;
711 char *buf
, *input_name
= (char *)xmalloc (piece
);
716 if (!fgets (buf
, piece
, stream
))
718 len
= strlen (input_name
);
719 if (input_name
[len
- 1] != '\n')
721 input_name
= (char *)xrealloc (input_name
, len
+ piece
);
722 buf
= input_name
+ len
;
725 input_name
[len
- 1] = '\0';
727 if (input_name
[0] == '*')
728 output_name
= &input_name
[1];
731 input_names
= (char **)xrealloc (input_names
, nr
* sizeof (char *));
732 output_names
= (char **)xrealloc (output_names
, nr
* sizeof (char *));
733 input_names
[nr
-1] = input_name
;
734 output_names
[nr
-1] = output_name
;
737 maybe_unlink (ltrans_output_file
);
738 ltrans_output_file
= NULL
;
742 makefile
= make_temp_file (".mk");
743 mstream
= fopen (makefile
, "w");
746 /* Execute the LTRANS stage for each input file (or prepare a
747 makefile to invoke this in parallel). */
748 for (i
= 0; i
< nr
; ++i
)
751 char *input_name
= input_names
[i
];
752 /* If it's a pass-through file do nothing. */
756 /* Replace the .o suffix with a .ltrans.o suffix and write
757 the resulting name to the LTRANS output list. */
758 obstack_grow (&env_obstack
, input_name
, strlen (input_name
) - 2);
759 obstack_grow (&env_obstack
, ".ltrans.o", sizeof (".ltrans.o"));
760 output_name
= XOBFINISH (&env_obstack
, char *);
762 /* Adjust the dumpbase if the linker output file was seen. */
766 = (char *) xmalloc (strlen (linker_output
)
767 + sizeof (DUMPBASE_SUFFIX
) + 1);
769 strlen (linker_output
) + sizeof (DUMPBASE_SUFFIX
),
770 "%s.ltrans%u", linker_output
, i
);
771 argv_ptr
[0] = dumpbase
;
774 argv_ptr
[1] = "-fltrans";
776 argv_ptr
[3] = output_name
;
777 argv_ptr
[4] = input_name
;
781 fprintf (mstream
, "%s:\n\t@%s ", output_name
, new_argv
[0]);
782 for (j
= 1; new_argv
[j
] != NULL
; ++j
)
783 fprintf (mstream
, " '%s'", new_argv
[j
]);
784 fprintf (mstream
, "\n");
785 /* If we are not preserving the ltrans input files then
786 truncate them as soon as we have processed it. This
787 reduces temporary disk-space usage. */
789 fprintf (mstream
, "\t@-touch -r %s %s.tem > /dev/null 2>&1 "
791 input_name
, input_name
, input_name
, input_name
);
795 fork_execute (new_argv
[0], CONST_CAST (char **, new_argv
),
797 maybe_unlink (input_name
);
800 output_names
[i
] = output_name
;
807 fprintf (mstream
, "all:");
808 for (i
= 0; i
< nr
; ++i
)
809 fprintf (mstream
, " \\\n\t%s", output_names
[i
]);
810 fprintf (mstream
, "\n");
814 /* Avoid passing --jobserver-fd= and similar flags
815 unless jobserver mode is explicitly enabled. */
816 putenv (xstrdup ("MAKEFLAGS="));
817 putenv (xstrdup ("MFLAGS="));
819 new_argv
[0] = getenv ("MAKE");
821 new_argv
[0] = "make";
823 new_argv
[2] = makefile
;
827 snprintf (jobs
, 31, "-j%d", parallel
);
828 new_argv
[i
++] = jobs
;
830 new_argv
[i
++] = "all";
831 new_argv
[i
++] = NULL
;
832 pex
= collect_execute (new_argv
[0], CONST_CAST (char **, new_argv
),
833 NULL
, NULL
, PEX_SEARCH
, false);
834 do_wait (new_argv
[0], pex
);
835 maybe_unlink (makefile
);
837 for (i
= 0; i
< nr
; ++i
)
838 maybe_unlink (input_names
[i
]);
840 for (i
= 0; i
< nr
; ++i
)
842 fputs (output_names
[i
], stdout
);
844 free (input_names
[i
]);
849 free (list_option_full
);
850 obstack_free (&env_obstack
, NULL
);
853 obstack_free (&argv_obstack
, NULL
);
860 main (int argc
, char *argv
[])
864 gcc_obstack_init (&opts_obstack
);
866 p
= argv
[0] + strlen (argv
[0]);
867 while (p
!= argv
[0] && !IS_DIR_SEPARATOR (p
[-1]))
871 xmalloc_set_program_name (progname
);
873 if (atexit (lto_wrapper_cleanup
) != 0)
874 fatal_error ("atexit failed");
878 diagnostic_initialize (global_dc
, 0);
880 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
881 signal (SIGINT
, fatal_signal
);
883 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
884 signal (SIGHUP
, fatal_signal
);
886 if (signal (SIGTERM
, SIG_IGN
) != SIG_IGN
)
887 signal (SIGTERM
, fatal_signal
);
889 if (signal (SIGPIPE
, SIG_IGN
) != SIG_IGN
)
890 signal (SIGPIPE
, fatal_signal
);
893 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
894 receive the signal. A different setting is inheritable */
895 signal (SIGCHLD
, SIG_DFL
);
898 /* We may be called with all the arguments stored in some file and
899 passed with @file. Expand them into argv before processing. */
900 expandargv (&argc
, &argv
);
902 run_gcc (argc
, argv
);