1e4b17023SJohn Marino /* Compiler driver program that can handle many languages.
2e4b17023SJohn Marino Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3e4b17023SJohn Marino 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4e4b17023SJohn Marino 2010, 2011, 2012
5e4b17023SJohn Marino Free Software Foundation, Inc.
6e4b17023SJohn Marino
7e4b17023SJohn Marino This file is part of GCC.
8e4b17023SJohn Marino
9e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
10e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
11e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
12e4b17023SJohn Marino version.
13e4b17023SJohn Marino
14e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
16e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17e4b17023SJohn Marino for more details.
18e4b17023SJohn Marino
19e4b17023SJohn Marino You should have received a copy of the GNU General Public License
20e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
21e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
22e4b17023SJohn Marino
23e4b17023SJohn Marino /* This program is the user interface to the C compiler and possibly to
24e4b17023SJohn Marino other compilers. It is used because compilation is a complicated procedure
25e4b17023SJohn Marino which involves running several programs and passing temporary files between
26e4b17023SJohn Marino them, forwarding the users switches to those programs selectively,
27e4b17023SJohn Marino and deleting the temporary files at the end.
28e4b17023SJohn Marino
29e4b17023SJohn Marino CC recognizes how to compile each input file by suffixes in the file names.
30e4b17023SJohn Marino Once it knows which kind of compilation to perform, the procedure for
31e4b17023SJohn Marino compilation is specified by a string called a "spec". */
32e4b17023SJohn Marino
33e4b17023SJohn Marino #include "config.h"
34e4b17023SJohn Marino #include "system.h"
35e4b17023SJohn Marino #include "coretypes.h"
36e4b17023SJohn Marino #include "multilib.h" /* before tm.h */
37e4b17023SJohn Marino #include "tm.h"
38e4b17023SJohn Marino #include "xregex.h"
39e4b17023SJohn Marino #include "obstack.h"
40e4b17023SJohn Marino #include "intl.h"
41e4b17023SJohn Marino #include "prefix.h"
42e4b17023SJohn Marino #include "gcc.h"
43e4b17023SJohn Marino #include "diagnostic.h"
44e4b17023SJohn Marino #include "flags.h"
45e4b17023SJohn Marino #include "opts.h"
46e4b17023SJohn Marino #include "params.h"
47e4b17023SJohn Marino #include "vec.h"
48e4b17023SJohn Marino #include "filenames.h"
49e4b17023SJohn Marino
50e4b17023SJohn Marino /* By default there is no special suffix for target executables. */
51e4b17023SJohn Marino /* FIXME: when autoconf is fixed, remove the host check - dj */
52e4b17023SJohn Marino #if defined(TARGET_EXECUTABLE_SUFFIX) && defined(HOST_EXECUTABLE_SUFFIX)
53e4b17023SJohn Marino #define HAVE_TARGET_EXECUTABLE_SUFFIX
54e4b17023SJohn Marino #endif
55e4b17023SJohn Marino
56e4b17023SJohn Marino /* By default there is no special suffix for host executables. */
57e4b17023SJohn Marino #ifdef HOST_EXECUTABLE_SUFFIX
58e4b17023SJohn Marino #define HAVE_HOST_EXECUTABLE_SUFFIX
59e4b17023SJohn Marino #else
60e4b17023SJohn Marino #define HOST_EXECUTABLE_SUFFIX ""
61e4b17023SJohn Marino #endif
62e4b17023SJohn Marino
63e4b17023SJohn Marino /* By default, the suffix for target object files is ".o". */
64e4b17023SJohn Marino #ifdef TARGET_OBJECT_SUFFIX
65e4b17023SJohn Marino #define HAVE_TARGET_OBJECT_SUFFIX
66e4b17023SJohn Marino #else
67e4b17023SJohn Marino #define TARGET_OBJECT_SUFFIX ".o"
68e4b17023SJohn Marino #endif
69e4b17023SJohn Marino
70e4b17023SJohn Marino static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
71e4b17023SJohn Marino
72e4b17023SJohn Marino /* Most every one is fine with LIBRARY_PATH. For some, it conflicts. */
73e4b17023SJohn Marino #ifndef LIBRARY_PATH_ENV
74e4b17023SJohn Marino #define LIBRARY_PATH_ENV "LIBRARY_PATH"
75e4b17023SJohn Marino #endif
76e4b17023SJohn Marino
77e4b17023SJohn Marino /* If a stage of compilation returns an exit status >= 1,
78e4b17023SJohn Marino compilation of that file ceases. */
79e4b17023SJohn Marino
80e4b17023SJohn Marino #define MIN_FATAL_STATUS 1
81e4b17023SJohn Marino
82e4b17023SJohn Marino /* Flag set by cppspec.c to 1. */
83e4b17023SJohn Marino int is_cpp_driver;
84e4b17023SJohn Marino
85e4b17023SJohn Marino /* Flag set to nonzero if an @file argument has been supplied to gcc. */
86e4b17023SJohn Marino static bool at_file_supplied;
87e4b17023SJohn Marino
88e4b17023SJohn Marino /* Definition of string containing the arguments given to configure. */
89e4b17023SJohn Marino #include "configargs.h"
90e4b17023SJohn Marino
91e4b17023SJohn Marino /* Flag saying to print the command line options understood by gcc and its
92e4b17023SJohn Marino sub-processes. */
93e4b17023SJohn Marino
94e4b17023SJohn Marino static int print_help_list;
95e4b17023SJohn Marino
96e4b17023SJohn Marino /* Flag saying to print the version of gcc and its sub-processes. */
97e4b17023SJohn Marino
98e4b17023SJohn Marino static int print_version;
99e4b17023SJohn Marino
100e4b17023SJohn Marino /* Flag indicating whether we should ONLY print the command and
101e4b17023SJohn Marino arguments (like verbose_flag) without executing the command.
102e4b17023SJohn Marino Displayed arguments are quoted so that the generated command
103e4b17023SJohn Marino line is suitable for execution. This is intended for use in
104e4b17023SJohn Marino shell scripts to capture the driver-generated command line. */
105e4b17023SJohn Marino static int verbose_only_flag;
106e4b17023SJohn Marino
107e4b17023SJohn Marino /* Flag indicating how to print command line options of sub-processes. */
108e4b17023SJohn Marino
109e4b17023SJohn Marino static int print_subprocess_help;
110e4b17023SJohn Marino
111e4b17023SJohn Marino /* Whether we should report subprocess execution times to a file. */
112e4b17023SJohn Marino
113e4b17023SJohn Marino FILE *report_times_to_file = NULL;
114e4b17023SJohn Marino
115e4b17023SJohn Marino /* Nonzero means place this string before uses of /, so that include
116e4b17023SJohn Marino and library files can be found in an alternate location. */
117e4b17023SJohn Marino
118e4b17023SJohn Marino #ifdef TARGET_SYSTEM_ROOT
119e4b17023SJohn Marino static const char *target_system_root = TARGET_SYSTEM_ROOT;
120e4b17023SJohn Marino #else
121e4b17023SJohn Marino static const char *target_system_root = 0;
122e4b17023SJohn Marino #endif
123e4b17023SJohn Marino
124e4b17023SJohn Marino /* Nonzero means pass the updated target_system_root to the compiler. */
125e4b17023SJohn Marino
126e4b17023SJohn Marino static int target_system_root_changed;
127e4b17023SJohn Marino
128e4b17023SJohn Marino /* Nonzero means append this string to target_system_root. */
129e4b17023SJohn Marino
130e4b17023SJohn Marino static const char *target_sysroot_suffix = 0;
131e4b17023SJohn Marino
132e4b17023SJohn Marino /* Nonzero means append this string to target_system_root for headers. */
133e4b17023SJohn Marino
134e4b17023SJohn Marino static const char *target_sysroot_hdrs_suffix = 0;
135e4b17023SJohn Marino
136e4b17023SJohn Marino /* Nonzero means write "temp" files in source directory
137e4b17023SJohn Marino and use the source file's name in them, and don't delete them. */
138e4b17023SJohn Marino
139e4b17023SJohn Marino static enum save_temps {
140e4b17023SJohn Marino SAVE_TEMPS_NONE, /* no -save-temps */
141e4b17023SJohn Marino SAVE_TEMPS_CWD, /* -save-temps in current directory */
142*2bbc7733Szrj SAVE_TEMPS_OBJ, /* -save-temps in object directory */
143*2bbc7733Szrj SAVE_TEMPS_OBJZ /* -save-temps in object directory with mangling */
144e4b17023SJohn Marino } save_temps_flag;
145e4b17023SJohn Marino
146e4b17023SJohn Marino /* Output file to use to get the object directory for -save-temps=obj */
147e4b17023SJohn Marino static char *save_temps_prefix = 0;
148e4b17023SJohn Marino static size_t save_temps_length = 0;
149e4b17023SJohn Marino
150e4b17023SJohn Marino /* The compiler version. */
151e4b17023SJohn Marino
152e4b17023SJohn Marino static const char *compiler_version;
153e4b17023SJohn Marino
154e4b17023SJohn Marino /* The target version. */
155e4b17023SJohn Marino
156e4b17023SJohn Marino static const char *const spec_version = DEFAULT_TARGET_VERSION;
157e4b17023SJohn Marino
158e4b17023SJohn Marino /* The target machine. */
159e4b17023SJohn Marino
160e4b17023SJohn Marino static const char *spec_machine = DEFAULT_TARGET_MACHINE;
161e4b17023SJohn Marino
162e4b17023SJohn Marino /* Nonzero if cross-compiling.
163e4b17023SJohn Marino When -b is used, the value comes from the `specs' file. */
164e4b17023SJohn Marino
165e4b17023SJohn Marino #ifdef CROSS_DIRECTORY_STRUCTURE
166e4b17023SJohn Marino static const char *cross_compile = "1";
167e4b17023SJohn Marino #else
168e4b17023SJohn Marino static const char *cross_compile = "0";
169e4b17023SJohn Marino #endif
170e4b17023SJohn Marino
171e4b17023SJohn Marino /* Greatest exit code of sub-processes that has been encountered up to
172e4b17023SJohn Marino now. */
173e4b17023SJohn Marino static int greatest_status = 1;
174e4b17023SJohn Marino
175e4b17023SJohn Marino /* This is the obstack which we use to allocate many strings. */
176e4b17023SJohn Marino
177e4b17023SJohn Marino static struct obstack obstack;
178e4b17023SJohn Marino
179e4b17023SJohn Marino /* This is the obstack to build an environment variable to pass to
180e4b17023SJohn Marino collect2 that describes all of the relevant switches of what to
181e4b17023SJohn Marino pass the compiler in building the list of pointers to constructors
182e4b17023SJohn Marino and destructors. */
183e4b17023SJohn Marino
184e4b17023SJohn Marino static struct obstack collect_obstack;
185e4b17023SJohn Marino
186e4b17023SJohn Marino /* Forward declaration for prototypes. */
187e4b17023SJohn Marino struct path_prefix;
188e4b17023SJohn Marino struct prefix_list;
189e4b17023SJohn Marino
190e4b17023SJohn Marino static void init_spec (void);
191e4b17023SJohn Marino static void store_arg (const char *, int, int);
192e4b17023SJohn Marino static void insert_wrapper (const char *);
193e4b17023SJohn Marino static char *load_specs (const char *);
194e4b17023SJohn Marino static void read_specs (const char *, int);
195e4b17023SJohn Marino static void set_spec (const char *, const char *);
196e4b17023SJohn Marino static struct compiler *lookup_compiler (const char *, size_t, const char *);
197e4b17023SJohn Marino static char *build_search_list (const struct path_prefix *, const char *,
198e4b17023SJohn Marino bool, bool);
199e4b17023SJohn Marino static void xputenv (const char *);
200e4b17023SJohn Marino static void putenv_from_prefixes (const struct path_prefix *, const char *,
201e4b17023SJohn Marino bool);
202e4b17023SJohn Marino static int access_check (const char *, int);
203e4b17023SJohn Marino static char *find_a_file (const struct path_prefix *, const char *, int, bool);
204e4b17023SJohn Marino static void add_prefix (struct path_prefix *, const char *, const char *,
205e4b17023SJohn Marino int, int, int);
206e4b17023SJohn Marino static void add_sysrooted_prefix (struct path_prefix *, const char *,
207e4b17023SJohn Marino const char *, int, int, int);
208e4b17023SJohn Marino static char *skip_whitespace (char *);
209e4b17023SJohn Marino static void delete_if_ordinary (const char *);
210e4b17023SJohn Marino static void delete_temp_files (void);
211e4b17023SJohn Marino static void delete_failure_queue (void);
212e4b17023SJohn Marino static void clear_failure_queue (void);
213e4b17023SJohn Marino static int check_live_switch (int, int);
214e4b17023SJohn Marino static const char *handle_braces (const char *);
215e4b17023SJohn Marino static inline bool input_suffix_matches (const char *, const char *);
216e4b17023SJohn Marino static inline bool switch_matches (const char *, const char *, int);
217e4b17023SJohn Marino static inline void mark_matching_switches (const char *, const char *, int);
218e4b17023SJohn Marino static inline void process_marked_switches (void);
219e4b17023SJohn Marino static const char *process_brace_body (const char *, const char *, const char *, int, int);
220e4b17023SJohn Marino static const struct spec_function *lookup_spec_function (const char *);
221e4b17023SJohn Marino static const char *eval_spec_function (const char *, const char *);
222e4b17023SJohn Marino static const char *handle_spec_function (const char *);
223e4b17023SJohn Marino static char *save_string (const char *, int);
224e4b17023SJohn Marino static void set_collect_gcc_options (void);
225e4b17023SJohn Marino static int do_spec_1 (const char *, int, const char *);
226e4b17023SJohn Marino static int do_spec_2 (const char *);
227e4b17023SJohn Marino static void do_option_spec (const char *, const char *);
228e4b17023SJohn Marino static void do_self_spec (const char *);
229e4b17023SJohn Marino static const char *find_file (const char *);
230e4b17023SJohn Marino static int is_directory (const char *, bool);
231e4b17023SJohn Marino static const char *validate_switches (const char *);
232e4b17023SJohn Marino static void validate_all_switches (void);
233e4b17023SJohn Marino static inline void validate_switches_from_spec (const char *);
234e4b17023SJohn Marino static void give_switch (int, int);
235e4b17023SJohn Marino static int used_arg (const char *, int);
236e4b17023SJohn Marino static int default_arg (const char *, int);
237e4b17023SJohn Marino static void set_multilib_dir (void);
238e4b17023SJohn Marino static void print_multilib_info (void);
239e4b17023SJohn Marino static void perror_with_name (const char *);
240e4b17023SJohn Marino static void display_help (void);
241e4b17023SJohn Marino static void add_preprocessor_option (const char *, int);
242e4b17023SJohn Marino static void add_assembler_option (const char *, int);
243e4b17023SJohn Marino static void add_linker_option (const char *, int);
244e4b17023SJohn Marino static void process_command (unsigned int, struct cl_decoded_option *);
245e4b17023SJohn Marino static int execute (void);
246e4b17023SJohn Marino static void alloc_args (void);
247e4b17023SJohn Marino static void clear_args (void);
248e4b17023SJohn Marino static void fatal_signal (int);
249e4b17023SJohn Marino #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
250e4b17023SJohn Marino static void init_gcc_specs (struct obstack *, const char *, const char *,
251e4b17023SJohn Marino const char *);
252e4b17023SJohn Marino #endif
253e4b17023SJohn Marino #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
254e4b17023SJohn Marino static const char *convert_filename (const char *, int, int);
255e4b17023SJohn Marino #endif
256e4b17023SJohn Marino
257e4b17023SJohn Marino static const char *getenv_spec_function (int, const char **);
258e4b17023SJohn Marino static const char *if_exists_spec_function (int, const char **);
259e4b17023SJohn Marino static const char *if_exists_else_spec_function (int, const char **);
260e4b17023SJohn Marino static const char *replace_outfile_spec_function (int, const char **);
261e4b17023SJohn Marino static const char *remove_outfile_spec_function (int, const char **);
262e4b17023SJohn Marino static const char *version_compare_spec_function (int, const char **);
263e4b17023SJohn Marino static const char *include_spec_function (int, const char **);
264e4b17023SJohn Marino static const char *find_file_spec_function (int, const char **);
265e4b17023SJohn Marino static const char *find_plugindir_spec_function (int, const char **);
266e4b17023SJohn Marino static const char *print_asm_header_spec_function (int, const char **);
267e4b17023SJohn Marino static const char *compare_debug_dump_opt_spec_function (int, const char **);
268e4b17023SJohn Marino static const char *compare_debug_self_opt_spec_function (int, const char **);
269e4b17023SJohn Marino static const char *compare_debug_auxbase_opt_spec_function (int, const char **);
270e4b17023SJohn Marino static const char *pass_through_libs_spec_func (int, const char **);
2715ce9237cSJohn Marino static char *convert_white_space (char *);
272e4b17023SJohn Marino
273e4b17023SJohn Marino /* The Specs Language
274e4b17023SJohn Marino
275e4b17023SJohn Marino Specs are strings containing lines, each of which (if not blank)
276e4b17023SJohn Marino is made up of a program name, and arguments separated by spaces.
277e4b17023SJohn Marino The program name must be exact and start from root, since no path
278e4b17023SJohn Marino is searched and it is unreliable to depend on the current working directory.
279e4b17023SJohn Marino Redirection of input or output is not supported; the subprograms must
280e4b17023SJohn Marino accept filenames saying what files to read and write.
281e4b17023SJohn Marino
282e4b17023SJohn Marino In addition, the specs can contain %-sequences to substitute variable text
283e4b17023SJohn Marino or for conditional text. Here is a table of all defined %-sequences.
284e4b17023SJohn Marino Note that spaces are not generated automatically around the results of
285e4b17023SJohn Marino expanding these sequences; therefore, you can concatenate them together
286e4b17023SJohn Marino or with constant text in a single argument.
287e4b17023SJohn Marino
288e4b17023SJohn Marino %% substitute one % into the program name or argument.
289e4b17023SJohn Marino %i substitute the name of the input file being processed.
290e4b17023SJohn Marino %b substitute the basename of the input file being processed.
291e4b17023SJohn Marino This is the substring up to (and not including) the last period
292e4b17023SJohn Marino and not including the directory unless -save-temps was specified
293e4b17023SJohn Marino to put temporaries in a different location.
294e4b17023SJohn Marino %B same as %b, but include the file suffix (text after the last period).
295e4b17023SJohn Marino %gSUFFIX
296e4b17023SJohn Marino substitute a file name that has suffix SUFFIX and is chosen
297e4b17023SJohn Marino once per compilation, and mark the argument a la %d. To reduce
298e4b17023SJohn Marino exposure to denial-of-service attacks, the file name is now
299e4b17023SJohn Marino chosen in a way that is hard to predict even when previously
300e4b17023SJohn Marino chosen file names are known. For example, `%g.s ... %g.o ... %g.s'
301e4b17023SJohn Marino might turn into `ccUVUUAU.s ccXYAXZ12.o ccUVUUAU.s'. SUFFIX matches
302e4b17023SJohn Marino the regexp "[.0-9A-Za-z]*%O"; "%O" is treated exactly as if it
303e4b17023SJohn Marino had been pre-processed. Previously, %g was simply substituted
304e4b17023SJohn Marino with a file name chosen once per compilation, without regard
305e4b17023SJohn Marino to any appended suffix (which was therefore treated just like
306e4b17023SJohn Marino ordinary text), making such attacks more likely to succeed.
307e4b17023SJohn Marino %|SUFFIX
308e4b17023SJohn Marino like %g, but if -pipe is in effect, expands simply to "-".
309e4b17023SJohn Marino %mSUFFIX
310e4b17023SJohn Marino like %g, but if -pipe is in effect, expands to nothing. (We have both
311e4b17023SJohn Marino %| and %m to accommodate differences between system assemblers; see
312e4b17023SJohn Marino the AS_NEEDS_DASH_FOR_PIPED_INPUT target macro.)
313e4b17023SJohn Marino %uSUFFIX
314e4b17023SJohn Marino like %g, but generates a new temporary file name even if %uSUFFIX
315e4b17023SJohn Marino was already seen.
316e4b17023SJohn Marino %USUFFIX
317e4b17023SJohn Marino substitutes the last file name generated with %uSUFFIX, generating a
318e4b17023SJohn Marino new one if there is no such last file name. In the absence of any
319e4b17023SJohn Marino %uSUFFIX, this is just like %gSUFFIX, except they don't share
320e4b17023SJohn Marino the same suffix "space", so `%g.s ... %U.s ... %g.s ... %U.s'
321e4b17023SJohn Marino would involve the generation of two distinct file names, one
322e4b17023SJohn Marino for each `%g.s' and another for each `%U.s'. Previously, %U was
323e4b17023SJohn Marino simply substituted with a file name chosen for the previous %u,
324e4b17023SJohn Marino without regard to any appended suffix.
325e4b17023SJohn Marino %jSUFFIX
326e4b17023SJohn Marino substitutes the name of the HOST_BIT_BUCKET, if any, and if it is
327e4b17023SJohn Marino writable, and if save-temps is off; otherwise, substitute the name
328e4b17023SJohn Marino of a temporary file, just like %u. This temporary file is not
329e4b17023SJohn Marino meant for communication between processes, but rather as a junk
330e4b17023SJohn Marino disposal mechanism.
331e4b17023SJohn Marino %.SUFFIX
332e4b17023SJohn Marino substitutes .SUFFIX for the suffixes of a matched switch's args when
333e4b17023SJohn Marino it is subsequently output with %*. SUFFIX is terminated by the next
334e4b17023SJohn Marino space or %.
335e4b17023SJohn Marino %d marks the argument containing or following the %d as a
336e4b17023SJohn Marino temporary file name, so that that file will be deleted if GCC exits
337e4b17023SJohn Marino successfully. Unlike %g, this contributes no text to the argument.
338e4b17023SJohn Marino %w marks the argument containing or following the %w as the
339e4b17023SJohn Marino "output file" of this compilation. This puts the argument
340e4b17023SJohn Marino into the sequence of arguments that %o will substitute later.
341e4b17023SJohn Marino %V indicates that this compilation produces no "output file".
342e4b17023SJohn Marino %W{...}
343e4b17023SJohn Marino like %{...} but mark last argument supplied within
344e4b17023SJohn Marino as a file to be deleted on failure.
345e4b17023SJohn Marino %o substitutes the names of all the output files, with spaces
346e4b17023SJohn Marino automatically placed around them. You should write spaces
347e4b17023SJohn Marino around the %o as well or the results are undefined.
348e4b17023SJohn Marino %o is for use in the specs for running the linker.
349e4b17023SJohn Marino Input files whose names have no recognized suffix are not compiled
350e4b17023SJohn Marino at all, but they are included among the output files, so they will
351e4b17023SJohn Marino be linked.
352e4b17023SJohn Marino %O substitutes the suffix for object files. Note that this is
353e4b17023SJohn Marino handled specially when it immediately follows %g, %u, or %U
354e4b17023SJohn Marino (with or without a suffix argument) because of the need for
355e4b17023SJohn Marino those to form complete file names. The handling is such that
356e4b17023SJohn Marino %O is treated exactly as if it had already been substituted,
357e4b17023SJohn Marino except that %g, %u, and %U do not currently support additional
358e4b17023SJohn Marino SUFFIX characters following %O as they would following, for
359e4b17023SJohn Marino example, `.o'.
360e4b17023SJohn Marino %I Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
361e4b17023SJohn Marino (made from TARGET_SYSTEM_ROOT), -isystem (made from COMPILER_PATH
362e4b17023SJohn Marino and -B options) and -imultilib as necessary.
363e4b17023SJohn Marino %s current argument is the name of a library or startup file of some sort.
364e4b17023SJohn Marino Search for that file in a standard list of directories
365e4b17023SJohn Marino and substitute the full name found.
366e4b17023SJohn Marino %eSTR Print STR as an error message. STR is terminated by a newline.
367e4b17023SJohn Marino Use this when inconsistent options are detected.
368e4b17023SJohn Marino %nSTR Print STR as a notice. STR is terminated by a newline.
369e4b17023SJohn Marino %x{OPTION} Accumulate an option for %X.
370e4b17023SJohn Marino %X Output the accumulated linker options specified by compilations.
371e4b17023SJohn Marino %Y Output the accumulated assembler options specified by compilations.
372e4b17023SJohn Marino %Z Output the accumulated preprocessor options specified by compilations.
373e4b17023SJohn Marino %a process ASM_SPEC as a spec.
374e4b17023SJohn Marino This allows config.h to specify part of the spec for running as.
375e4b17023SJohn Marino %A process ASM_FINAL_SPEC as a spec. A capital A is actually
376e4b17023SJohn Marino used here. This can be used to run a post-processor after the
377e4b17023SJohn Marino assembler has done its job.
378e4b17023SJohn Marino %D Dump out a -L option for each directory in startfile_prefixes.
379e4b17023SJohn Marino If multilib_dir is set, extra entries are generated with it affixed.
380e4b17023SJohn Marino %l process LINK_SPEC as a spec.
381e4b17023SJohn Marino %L process LIB_SPEC as a spec.
382e4b17023SJohn Marino %G process LIBGCC_SPEC as a spec.
383e4b17023SJohn Marino %R Output the concatenation of target_system_root and
384e4b17023SJohn Marino target_sysroot_suffix.
385e4b17023SJohn Marino %S process STARTFILE_SPEC as a spec. A capital S is actually used here.
386e4b17023SJohn Marino %E process ENDFILE_SPEC as a spec. A capital E is actually used here.
387e4b17023SJohn Marino %C process CPP_SPEC as a spec.
388e4b17023SJohn Marino %1 process CC1_SPEC as a spec.
389e4b17023SJohn Marino %2 process CC1PLUS_SPEC as a spec.
390e4b17023SJohn Marino %* substitute the variable part of a matched option. (See below.)
391e4b17023SJohn Marino Note that each comma in the substituted string is replaced by
392e4b17023SJohn Marino a single space.
393e4b17023SJohn Marino %<S remove all occurrences of -S from the command line.
394e4b17023SJohn Marino Note - this command is position dependent. % commands in the
395e4b17023SJohn Marino spec string before this one will see -S, % commands in the
396e4b17023SJohn Marino spec string after this one will not.
397e4b17023SJohn Marino %>S Similar to "%<S", but keep it in the GCC command line.
398e4b17023SJohn Marino %<S* remove all occurrences of all switches beginning with -S from the
399e4b17023SJohn Marino command line.
400e4b17023SJohn Marino %:function(args)
401e4b17023SJohn Marino Call the named function FUNCTION, passing it ARGS. ARGS is
402e4b17023SJohn Marino first processed as a nested spec string, then split into an
403e4b17023SJohn Marino argument vector in the usual fashion. The function returns
404e4b17023SJohn Marino a string which is processed as if it had appeared literally
405e4b17023SJohn Marino as part of the current spec.
406e4b17023SJohn Marino %{S} substitutes the -S switch, if that switch was given to GCC.
407e4b17023SJohn Marino If that switch was not specified, this substitutes nothing.
408e4b17023SJohn Marino Here S is a metasyntactic variable.
409e4b17023SJohn Marino %{S*} substitutes all the switches specified to GCC whose names start
410e4b17023SJohn Marino with -S. This is used for -o, -I, etc; switches that take
411e4b17023SJohn Marino arguments. GCC considers `-o foo' as being one switch whose
412e4b17023SJohn Marino name starts with `o'. %{o*} would substitute this text,
413e4b17023SJohn Marino including the space; thus, two arguments would be generated.
414e4b17023SJohn Marino %{S*&T*} likewise, but preserve order of S and T options (the order
415e4b17023SJohn Marino of S and T in the spec is not significant). Can be any number
416e4b17023SJohn Marino of ampersand-separated variables; for each the wild card is
417e4b17023SJohn Marino optional. Useful for CPP as %{D*&U*&A*}.
418e4b17023SJohn Marino
419e4b17023SJohn Marino %{S:X} substitutes X, if the -S switch was given to GCC.
420e4b17023SJohn Marino %{!S:X} substitutes X, if the -S switch was NOT given to GCC.
421e4b17023SJohn Marino %{S*:X} substitutes X if one or more switches whose names start
422e4b17023SJohn Marino with -S was given to GCC. Normally X is substituted only
423e4b17023SJohn Marino once, no matter how many such switches appeared. However,
424e4b17023SJohn Marino if %* appears somewhere in X, then X will be substituted
425e4b17023SJohn Marino once for each matching switch, with the %* replaced by the
426e4b17023SJohn Marino part of that switch that matched the '*'.
427e4b17023SJohn Marino %{.S:X} substitutes X, if processing a file with suffix S.
428e4b17023SJohn Marino %{!.S:X} substitutes X, if NOT processing a file with suffix S.
429e4b17023SJohn Marino %{,S:X} substitutes X, if processing a file which will use spec S.
430e4b17023SJohn Marino %{!,S:X} substitutes X, if NOT processing a file which will use spec S.
431e4b17023SJohn Marino
432e4b17023SJohn Marino %{S|T:X} substitutes X if either -S or -T was given to GCC. This may be
433e4b17023SJohn Marino combined with '!', '.', ',', and '*' as above binding stronger
434e4b17023SJohn Marino than the OR.
435e4b17023SJohn Marino If %* appears in X, all of the alternatives must be starred, and
436e4b17023SJohn Marino only the first matching alternative is substituted.
437e4b17023SJohn Marino %{S:X; if S was given to GCC, substitutes X;
438e4b17023SJohn Marino T:Y; else if T was given to GCC, substitutes Y;
439e4b17023SJohn Marino :D} else substitutes D. There can be as many clauses as you need.
440e4b17023SJohn Marino This may be combined with '.', '!', ',', '|', and '*' as above.
441e4b17023SJohn Marino
442e4b17023SJohn Marino %(Spec) processes a specification defined in a specs file as *Spec:
443e4b17023SJohn Marino
444e4b17023SJohn Marino The conditional text X in a %{S:X} or similar construct may contain
445e4b17023SJohn Marino other nested % constructs or spaces, or even newlines. They are
446e4b17023SJohn Marino processed as usual, as described above. Trailing white space in X is
447e4b17023SJohn Marino ignored. White space may also appear anywhere on the left side of the
448e4b17023SJohn Marino colon in these constructs, except between . or * and the corresponding
449e4b17023SJohn Marino word.
450e4b17023SJohn Marino
451e4b17023SJohn Marino The -O, -f, -m, and -W switches are handled specifically in these
452e4b17023SJohn Marino constructs. If another value of -O or the negated form of a -f, -m, or
453e4b17023SJohn Marino -W switch is found later in the command line, the earlier switch
454e4b17023SJohn Marino value is ignored, except with {S*} where S is just one letter; this
455e4b17023SJohn Marino passes all matching options.
456e4b17023SJohn Marino
457e4b17023SJohn Marino The character | at the beginning of the predicate text is used to indicate
458e4b17023SJohn Marino that a command should be piped to the following command, but only if -pipe
459e4b17023SJohn Marino is specified.
460e4b17023SJohn Marino
461e4b17023SJohn Marino Note that it is built into GCC which switches take arguments and which
462e4b17023SJohn Marino do not. You might think it would be useful to generalize this to
463e4b17023SJohn Marino allow each compiler's spec to say which switches take arguments. But
464e4b17023SJohn Marino this cannot be done in a consistent fashion. GCC cannot even decide
465e4b17023SJohn Marino which input files have been specified without knowing which switches
466e4b17023SJohn Marino take arguments, and it must know which input files to compile in order
467e4b17023SJohn Marino to tell which compilers to run.
468e4b17023SJohn Marino
469e4b17023SJohn Marino GCC also knows implicitly that arguments starting in `-l' are to be
470e4b17023SJohn Marino treated as compiler output files, and passed to the linker in their
471e4b17023SJohn Marino proper position among the other output files. */
472e4b17023SJohn Marino
473e4b17023SJohn Marino /* Define the macros used for specs %a, %l, %L, %S, %C, %1. */
474e4b17023SJohn Marino
475e4b17023SJohn Marino /* config.h can define ASM_SPEC to provide extra args to the assembler
476e4b17023SJohn Marino or extra switch-translations. */
477e4b17023SJohn Marino #ifndef ASM_SPEC
478e4b17023SJohn Marino #define ASM_SPEC ""
479e4b17023SJohn Marino #endif
480e4b17023SJohn Marino
481e4b17023SJohn Marino /* config.h can define ASM_FINAL_SPEC to run a post processor after
482e4b17023SJohn Marino the assembler has run. */
483e4b17023SJohn Marino #ifndef ASM_FINAL_SPEC
484e4b17023SJohn Marino #define ASM_FINAL_SPEC ""
485e4b17023SJohn Marino #endif
486e4b17023SJohn Marino
487e4b17023SJohn Marino /* config.h can define CPP_SPEC to provide extra args to the C preprocessor
488e4b17023SJohn Marino or extra switch-translations. */
489e4b17023SJohn Marino #ifndef CPP_SPEC
490e4b17023SJohn Marino #define CPP_SPEC ""
491e4b17023SJohn Marino #endif
492e4b17023SJohn Marino
493e4b17023SJohn Marino /* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
494e4b17023SJohn Marino or extra switch-translations. */
495e4b17023SJohn Marino #ifndef CC1_SPEC
496e4b17023SJohn Marino #define CC1_SPEC ""
497e4b17023SJohn Marino #endif
498e4b17023SJohn Marino
499e4b17023SJohn Marino /* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
500e4b17023SJohn Marino or extra switch-translations. */
501e4b17023SJohn Marino #ifndef CC1PLUS_SPEC
502e4b17023SJohn Marino #define CC1PLUS_SPEC ""
503e4b17023SJohn Marino #endif
504e4b17023SJohn Marino
505e4b17023SJohn Marino /* config.h can define LINK_SPEC to provide extra args to the linker
506e4b17023SJohn Marino or extra switch-translations. */
507e4b17023SJohn Marino #ifndef LINK_SPEC
508e4b17023SJohn Marino #define LINK_SPEC ""
509e4b17023SJohn Marino #endif
510e4b17023SJohn Marino
511e4b17023SJohn Marino /* config.h can define LIB_SPEC to override the default libraries. */
512e4b17023SJohn Marino #ifndef LIB_SPEC
513e4b17023SJohn Marino #define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
514e4b17023SJohn Marino #endif
515e4b17023SJohn Marino
516e4b17023SJohn Marino /* mudflap specs */
517e4b17023SJohn Marino #ifndef MFWRAP_SPEC
518e4b17023SJohn Marino /* XXX: valid only for GNU ld */
519e4b17023SJohn Marino /* XXX: should exactly match hooks provided by libmudflap.a */
520e4b17023SJohn Marino #define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
521e4b17023SJohn Marino --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
522e4b17023SJohn Marino --wrap=mmap --wrap=mmap64 --wrap=munmap --wrap=alloca\
523e4b17023SJohn Marino } %{fmudflapth: --wrap=pthread_create\
524e4b17023SJohn Marino }} %{fmudflap|fmudflapth: --wrap=main}"
525e4b17023SJohn Marino #endif
526e4b17023SJohn Marino #ifndef MFLIB_SPEC
527e4b17023SJohn Marino #define MFLIB_SPEC "%{fmudflap|fmudflapth: -export-dynamic}"
528e4b17023SJohn Marino #endif
529e4b17023SJohn Marino
530e4b17023SJohn Marino /* When using -fsplit-stack we need to wrap pthread_create, in order
531e4b17023SJohn Marino to initialize the stack guard. We always use wrapping, rather than
532e4b17023SJohn Marino shared library ordering, and we keep the wrapper function in
533e4b17023SJohn Marino libgcc. This is not yet a real spec, though it could become one;
534e4b17023SJohn Marino it is currently just stuffed into LINK_SPEC. FIXME: This wrapping
535e4b17023SJohn Marino only works with GNU ld and gold. FIXME: This is incompatible with
536e4b17023SJohn Marino -fmudflap when linking statically, which wants to do its own
537e4b17023SJohn Marino wrapping. */
538e4b17023SJohn Marino #define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
539e4b17023SJohn Marino
540e4b17023SJohn Marino /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
541e4b17023SJohn Marino included. */
542e4b17023SJohn Marino #ifndef LIBGCC_SPEC
543e4b17023SJohn Marino #if defined(REAL_LIBGCC_SPEC)
544e4b17023SJohn Marino #define LIBGCC_SPEC REAL_LIBGCC_SPEC
545e4b17023SJohn Marino #elif defined(LINK_LIBGCC_SPECIAL_1)
546e4b17023SJohn Marino /* Have gcc do the search for libgcc.a. */
547e4b17023SJohn Marino #define LIBGCC_SPEC "libgcc.a%s"
548e4b17023SJohn Marino #else
549e4b17023SJohn Marino #define LIBGCC_SPEC "-lgcc"
550e4b17023SJohn Marino #endif
551e4b17023SJohn Marino #endif
552e4b17023SJohn Marino
553e4b17023SJohn Marino /* config.h can define STARTFILE_SPEC to override the default crt0 files. */
554e4b17023SJohn Marino #ifndef STARTFILE_SPEC
555e4b17023SJohn Marino #define STARTFILE_SPEC \
556e4b17023SJohn Marino "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
557e4b17023SJohn Marino #endif
558e4b17023SJohn Marino
559e4b17023SJohn Marino /* config.h can define ENDFILE_SPEC to override the default crtn files. */
560e4b17023SJohn Marino #ifndef ENDFILE_SPEC
561e4b17023SJohn Marino #define ENDFILE_SPEC ""
562e4b17023SJohn Marino #endif
563e4b17023SJohn Marino
564e4b17023SJohn Marino #ifndef LINKER_NAME
565e4b17023SJohn Marino #define LINKER_NAME "collect2"
566e4b17023SJohn Marino #endif
567e4b17023SJohn Marino
568e4b17023SJohn Marino #ifdef HAVE_AS_DEBUG_PREFIX_MAP
569e4b17023SJohn Marino #define ASM_MAP " %{fdebug-prefix-map=*:--debug-prefix-map %*}"
570e4b17023SJohn Marino #else
571e4b17023SJohn Marino #define ASM_MAP ""
572e4b17023SJohn Marino #endif
573e4b17023SJohn Marino
574e4b17023SJohn Marino /* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
575e4b17023SJohn Marino to the assembler. */
576e4b17023SJohn Marino #ifndef ASM_DEBUG_SPEC
577e4b17023SJohn Marino # if defined(DBX_DEBUGGING_INFO) && defined(DWARF2_DEBUGGING_INFO) \
578e4b17023SJohn Marino && defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
579e4b17023SJohn Marino # define ASM_DEBUG_SPEC \
580e4b17023SJohn Marino (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG \
581e4b17023SJohn Marino ? "%{!g0:%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}}" ASM_MAP \
582e4b17023SJohn Marino : "%{!g0:%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}}" ASM_MAP)
583e4b17023SJohn Marino # else
584e4b17023SJohn Marino # if defined(DBX_DEBUGGING_INFO) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
585e4b17023SJohn Marino # define ASM_DEBUG_SPEC "%{g*:%{!g0:--gstabs}}" ASM_MAP
586e4b17023SJohn Marino # endif
587e4b17023SJohn Marino # if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
588e4b17023SJohn Marino # define ASM_DEBUG_SPEC "%{g*:%{!g0:--gdwarf2}}" ASM_MAP
589e4b17023SJohn Marino # endif
590e4b17023SJohn Marino # endif
591e4b17023SJohn Marino #endif
592e4b17023SJohn Marino #ifndef ASM_DEBUG_SPEC
593e4b17023SJohn Marino # define ASM_DEBUG_SPEC ""
594e4b17023SJohn Marino #endif
595e4b17023SJohn Marino
596e4b17023SJohn Marino /* Here is the spec for running the linker, after compiling all files. */
597e4b17023SJohn Marino
598e4b17023SJohn Marino /* This is overridable by the target in case they need to specify the
599e4b17023SJohn Marino -lgcc and -lc order specially, yet not require them to override all
600e4b17023SJohn Marino of LINK_COMMAND_SPEC. */
601e4b17023SJohn Marino #ifndef LINK_GCC_C_SEQUENCE_SPEC
602e4b17023SJohn Marino #define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
603e4b17023SJohn Marino #endif
604e4b17023SJohn Marino
605e4b17023SJohn Marino #ifndef LINK_SSP_SPEC
606e4b17023SJohn Marino #ifdef TARGET_LIBC_PROVIDES_SSP
607e4b17023SJohn Marino #define LINK_SSP_SPEC "%{fstack-protector:}"
608e4b17023SJohn Marino #else
609e4b17023SJohn Marino #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}"
610e4b17023SJohn Marino #endif
611e4b17023SJohn Marino #endif
612e4b17023SJohn Marino
613e4b17023SJohn Marino #ifndef LINK_PIE_SPEC
614e4b17023SJohn Marino #ifdef HAVE_LD_PIE
615e4b17023SJohn Marino #define LINK_PIE_SPEC "%{pie:-pie} "
616e4b17023SJohn Marino #else
617e4b17023SJohn Marino #define LINK_PIE_SPEC "%{pie:} "
618e4b17023SJohn Marino #endif
619e4b17023SJohn Marino #endif
620e4b17023SJohn Marino
621e4b17023SJohn Marino #ifndef LINK_BUILDID_SPEC
622e4b17023SJohn Marino # if defined(HAVE_LD_BUILDID) && defined(ENABLE_LD_BUILDID)
623e4b17023SJohn Marino # define LINK_BUILDID_SPEC "%{!r:--build-id} "
624e4b17023SJohn Marino # endif
625e4b17023SJohn Marino #endif
626e4b17023SJohn Marino
627e4b17023SJohn Marino /* Conditional to test whether the LTO plugin is used or not.
628e4b17023SJohn Marino FIXME: For slim LTO we will need to enable plugin unconditionally. This
629e4b17023SJohn Marino still cause problems with PLUGIN_LD != LD and when plugin is built but
630e4b17023SJohn Marino not useable. For GCC 4.6 we don't support slim LTO and thus we can enable
631e4b17023SJohn Marino plugin only when LTO is enabled. We still honor explicit
632e4b17023SJohn Marino -fuse-linker-plugin if the linker used understands -plugin. */
633e4b17023SJohn Marino
634e4b17023SJohn Marino /* The linker has some plugin support. */
635e4b17023SJohn Marino #if HAVE_LTO_PLUGIN > 0
636e4b17023SJohn Marino /* The linker used has full plugin support, use LTO plugin by default. */
637e4b17023SJohn Marino #if HAVE_LTO_PLUGIN == 2
638e4b17023SJohn Marino #define PLUGIN_COND "!fno-use-linker-plugin:%{flto|flto=*|fuse-linker-plugin"
639e4b17023SJohn Marino #define PLUGIN_COND_CLOSE "}"
640e4b17023SJohn Marino #else
641e4b17023SJohn Marino /* The linker used has limited plugin support, use LTO plugin with explicit
642e4b17023SJohn Marino -fuse-linker-plugin. */
643e4b17023SJohn Marino #define PLUGIN_COND "fuse-linker-plugin"
644e4b17023SJohn Marino #define PLUGIN_COND_CLOSE ""
645e4b17023SJohn Marino #endif
646e4b17023SJohn Marino #define LINK_PLUGIN_SPEC \
647e4b17023SJohn Marino "%{"PLUGIN_COND": \
648e4b17023SJohn Marino -plugin %(linker_plugin_file) \
649e4b17023SJohn Marino -plugin-opt=%(lto_wrapper) \
650e4b17023SJohn Marino -plugin-opt=-fresolution=%u.res \
651e4b17023SJohn Marino %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
652e4b17023SJohn Marino }"PLUGIN_COND_CLOSE
653e4b17023SJohn Marino #else
654e4b17023SJohn Marino /* The linker used doesn't support -plugin, reject -fuse-linker-plugin. */
655e4b17023SJohn Marino #define LINK_PLUGIN_SPEC "%{fuse-linker-plugin:\
656e4b17023SJohn Marino %e-fuse-linker-plugin is not supported in this configuration}"
657e4b17023SJohn Marino #endif
658e4b17023SJohn Marino
659e4b17023SJohn Marino
660e4b17023SJohn Marino /* -u* was put back because both BSD and SysV seem to support it. */
661e4b17023SJohn Marino /* %{static:} simply prevents an error message if the target machine
662e4b17023SJohn Marino doesn't handle -static. */
663e4b17023SJohn Marino /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
664e4b17023SJohn Marino scripts which exist in user specified directories, or in standard
665e4b17023SJohn Marino directories. */
666e4b17023SJohn Marino /* We pass any -flto flags on to the linker, which is expected
667e4b17023SJohn Marino to understand them. In practice, this means it had better be collect2. */
668e4b17023SJohn Marino /* %{e*} includes -export-dynamic; see comment in common.opt. */
669e4b17023SJohn Marino #ifndef LINK_COMMAND_SPEC
670e4b17023SJohn Marino #define LINK_COMMAND_SPEC "\
671e4b17023SJohn Marino %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
672e4b17023SJohn Marino %(linker) " \
673e4b17023SJohn Marino LINK_PLUGIN_SPEC \
674e4b17023SJohn Marino "%{flto|flto=*:%<fcompare-debug*} \
675e4b17023SJohn Marino %{flto} %{flto=*} %l " LINK_PIE_SPEC \
676e4b17023SJohn Marino "%X %{o*} %{e*} %{N} %{n} %{r}\
677e4b17023SJohn Marino %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
678e4b17023SJohn Marino %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
679e4b17023SJohn Marino %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
680e4b17023SJohn Marino %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
681e4b17023SJohn Marino %(mflib) " STACK_SPLIT_SPEC "\
682e4b17023SJohn Marino %{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\
683e4b17023SJohn Marino %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
684e4b17023SJohn Marino %{!nostdlib:%{!nostartfiles:%E}} %{T*} }}}}}}"
685e4b17023SJohn Marino #endif
686e4b17023SJohn Marino
687e4b17023SJohn Marino #ifndef LINK_LIBGCC_SPEC
688e4b17023SJohn Marino /* Generate -L options for startfile prefix list. */
689e4b17023SJohn Marino # define LINK_LIBGCC_SPEC "%D"
690e4b17023SJohn Marino #endif
691e4b17023SJohn Marino
692e4b17023SJohn Marino #ifndef STARTFILE_PREFIX_SPEC
693e4b17023SJohn Marino # define STARTFILE_PREFIX_SPEC ""
694e4b17023SJohn Marino #endif
695e4b17023SJohn Marino
696e4b17023SJohn Marino #ifndef SYSROOT_SPEC
697e4b17023SJohn Marino # define SYSROOT_SPEC "--sysroot=%R"
698e4b17023SJohn Marino #endif
699e4b17023SJohn Marino
700e4b17023SJohn Marino #ifndef SYSROOT_SUFFIX_SPEC
701e4b17023SJohn Marino # define SYSROOT_SUFFIX_SPEC ""
702e4b17023SJohn Marino #endif
703e4b17023SJohn Marino
704e4b17023SJohn Marino #ifndef SYSROOT_HEADERS_SUFFIX_SPEC
705e4b17023SJohn Marino # define SYSROOT_HEADERS_SUFFIX_SPEC ""
706e4b17023SJohn Marino #endif
707e4b17023SJohn Marino
708e4b17023SJohn Marino static const char *asm_debug;
709e4b17023SJohn Marino static const char *cpp_spec = CPP_SPEC;
710e4b17023SJohn Marino static const char *cc1_spec = CC1_SPEC;
711e4b17023SJohn Marino static const char *cc1plus_spec = CC1PLUS_SPEC;
712e4b17023SJohn Marino static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
713e4b17023SJohn Marino static const char *link_ssp_spec = LINK_SSP_SPEC;
714e4b17023SJohn Marino static const char *asm_spec = ASM_SPEC;
715e4b17023SJohn Marino static const char *asm_final_spec = ASM_FINAL_SPEC;
716e4b17023SJohn Marino static const char *link_spec = LINK_SPEC;
717e4b17023SJohn Marino static const char *lib_spec = LIB_SPEC;
718e4b17023SJohn Marino static const char *mfwrap_spec = MFWRAP_SPEC;
719e4b17023SJohn Marino static const char *mflib_spec = MFLIB_SPEC;
720e4b17023SJohn Marino static const char *link_gomp_spec = "";
721e4b17023SJohn Marino static const char *libgcc_spec = LIBGCC_SPEC;
722e4b17023SJohn Marino static const char *endfile_spec = ENDFILE_SPEC;
723e4b17023SJohn Marino static const char *startfile_spec = STARTFILE_SPEC;
724e4b17023SJohn Marino static const char *linker_name_spec = LINKER_NAME;
725e4b17023SJohn Marino static const char *linker_plugin_file_spec = "";
726e4b17023SJohn Marino static const char *lto_wrapper_spec = "";
727e4b17023SJohn Marino static const char *lto_gcc_spec = "";
728e4b17023SJohn Marino static const char *link_command_spec = LINK_COMMAND_SPEC;
729e4b17023SJohn Marino static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
730e4b17023SJohn Marino static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
731e4b17023SJohn Marino static const char *sysroot_spec = SYSROOT_SPEC;
732e4b17023SJohn Marino static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
733e4b17023SJohn Marino static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
734e4b17023SJohn Marino static const char *self_spec = "";
735e4b17023SJohn Marino
736e4b17023SJohn Marino /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
737e4b17023SJohn Marino There should be no need to override these in target dependent files,
738e4b17023SJohn Marino but we need to copy them to the specs file so that newer versions
739e4b17023SJohn Marino of the GCC driver can correctly drive older tool chains with the
740e4b17023SJohn Marino appropriate -B options. */
741e4b17023SJohn Marino
742e4b17023SJohn Marino /* When cpplib handles traditional preprocessing, get rid of this, and
743e4b17023SJohn Marino call cc1 (or cc1obj in objc/lang-specs.h) from the main specs so
744e4b17023SJohn Marino that we default the front end language better. */
745e4b17023SJohn Marino static const char *trad_capable_cpp =
746e4b17023SJohn Marino "cc1 -E %{traditional|traditional-cpp:-traditional-cpp}";
747e4b17023SJohn Marino
748e4b17023SJohn Marino /* We don't wrap .d files in %W{} since a missing .d file, and
749e4b17023SJohn Marino therefore no dependency entry, confuses make into thinking a .o
750e4b17023SJohn Marino file that happens to exist is up-to-date. */
751e4b17023SJohn Marino static const char *cpp_unique_options =
752e4b17023SJohn Marino "%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I\
753e4b17023SJohn Marino %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
754e4b17023SJohn Marino %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
755e4b17023SJohn Marino %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
756e4b17023SJohn Marino %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
757e4b17023SJohn Marino %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD}\
758e4b17023SJohn Marino %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
759e4b17023SJohn Marino %{H} %C %{D*&U*&A*} %{i*} %Z %i\
760e4b17023SJohn Marino %{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
761e4b17023SJohn Marino %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\
762e4b17023SJohn Marino %{E|M|MM:%W{o*}}";
763e4b17023SJohn Marino
764e4b17023SJohn Marino /* This contains cpp options which are common with cc1_options and are passed
765e4b17023SJohn Marino only when preprocessing only to avoid duplication. We pass the cc1 spec
766e4b17023SJohn Marino options to the preprocessor so that it the cc1 spec may manipulate
767e4b17023SJohn Marino options used to set target flags. Those special target flags settings may
768e4b17023SJohn Marino in turn cause preprocessor symbols to be defined specially. */
769e4b17023SJohn Marino static const char *cpp_options =
770e4b17023SJohn Marino "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
771e4b17023SJohn Marino %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*}\
772e4b17023SJohn Marino %{undef} %{save-temps*:-fpch-preprocess}";
773e4b17023SJohn Marino
774e4b17023SJohn Marino /* This contains cpp options which are not passed when the preprocessor
775e4b17023SJohn Marino output will be used by another program. */
776e4b17023SJohn Marino static const char *cpp_debug_options = "%{d*}";
777e4b17023SJohn Marino
778e4b17023SJohn Marino /* NB: This is shared amongst all front-ends, except for Ada. */
779e4b17023SJohn Marino static const char *cc1_options =
780e4b17023SJohn Marino "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
781e4b17023SJohn Marino %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
782e4b17023SJohn Marino %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*}\
783e4b17023SJohn Marino %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} \
784e4b17023SJohn Marino %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}} \
785e4b17023SJohn Marino %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
786e4b17023SJohn Marino %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
787e4b17023SJohn Marino %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
788e4b17023SJohn Marino %{-target-help:--target-help}\
789e4b17023SJohn Marino %{-version:--version}\
790e4b17023SJohn Marino %{-help=*:--help=%*}\
791e4b17023SJohn Marino %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
792e4b17023SJohn Marino %{fsyntax-only:-o %j} %{-param*}\
793e4b17023SJohn Marino %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}\
794e4b17023SJohn Marino %{coverage:-fprofile-arcs -ftest-coverage}";
795e4b17023SJohn Marino
796e4b17023SJohn Marino static const char *asm_options =
797e4b17023SJohn Marino "%{-target-help:%:print-asm-header()} "
798e4b17023SJohn Marino #if HAVE_GNU_AS
799e4b17023SJohn Marino /* If GNU AS is used, then convert -w (no warnings), -I, and -v
800e4b17023SJohn Marino to the assembler equivalents. */
801e4b17023SJohn Marino "%{v} %{w:-W} %{I*} "
802e4b17023SJohn Marino #endif
803e4b17023SJohn Marino "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
804e4b17023SJohn Marino
805e4b17023SJohn Marino static const char *invoke_as =
806e4b17023SJohn Marino #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
807e4b17023SJohn Marino "%{!fwpa:\
808e4b17023SJohn Marino %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
809e4b17023SJohn Marino %{!S:-o %|.s |\n as %(asm_options) %|.s %A }\
810e4b17023SJohn Marino }";
811e4b17023SJohn Marino #else
812e4b17023SJohn Marino "%{!fwpa:\
813e4b17023SJohn Marino %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
814e4b17023SJohn Marino %{!S:-o %|.s |\n as %(asm_options) %m.s %A }\
815e4b17023SJohn Marino }";
816e4b17023SJohn Marino #endif
817e4b17023SJohn Marino
818e4b17023SJohn Marino /* Some compilers have limits on line lengths, and the multilib_select
819e4b17023SJohn Marino and/or multilib_matches strings can be very long, so we build them at
820e4b17023SJohn Marino run time. */
821e4b17023SJohn Marino static struct obstack multilib_obstack;
822e4b17023SJohn Marino static const char *multilib_select;
823e4b17023SJohn Marino static const char *multilib_matches;
824e4b17023SJohn Marino static const char *multilib_defaults;
825e4b17023SJohn Marino static const char *multilib_exclusions;
826e4b17023SJohn Marino
827e4b17023SJohn Marino /* Check whether a particular argument is a default argument. */
828e4b17023SJohn Marino
829e4b17023SJohn Marino #ifndef MULTILIB_DEFAULTS
830e4b17023SJohn Marino #define MULTILIB_DEFAULTS { "" }
831e4b17023SJohn Marino #endif
832e4b17023SJohn Marino
833e4b17023SJohn Marino static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
834e4b17023SJohn Marino
835e4b17023SJohn Marino #ifndef DRIVER_SELF_SPECS
836e4b17023SJohn Marino #define DRIVER_SELF_SPECS ""
837e4b17023SJohn Marino #endif
838e4b17023SJohn Marino
839e4b17023SJohn Marino /* Adding -fopenmp should imply pthreads. This is particularly important
840e4b17023SJohn Marino for targets that use different start files and suchlike. */
841e4b17023SJohn Marino #ifndef GOMP_SELF_SPECS
842e4b17023SJohn Marino #define GOMP_SELF_SPECS "%{fopenmp|ftree-parallelize-loops=*: -pthread}"
843e4b17023SJohn Marino #endif
844e4b17023SJohn Marino
845e4b17023SJohn Marino /* Likewise for -fgnu-tm. */
846e4b17023SJohn Marino #ifndef GTM_SELF_SPECS
847e4b17023SJohn Marino #define GTM_SELF_SPECS "%{fgnu-tm: -pthread}"
848e4b17023SJohn Marino #endif
849e4b17023SJohn Marino
850e4b17023SJohn Marino static const char *const driver_self_specs[] = {
851e4b17023SJohn Marino "%{fdump-final-insns:-fdump-final-insns=.} %<fdump-final-insns",
852e4b17023SJohn Marino DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS
853e4b17023SJohn Marino };
854e4b17023SJohn Marino
855e4b17023SJohn Marino #ifndef OPTION_DEFAULT_SPECS
856e4b17023SJohn Marino #define OPTION_DEFAULT_SPECS { "", "" }
857e4b17023SJohn Marino #endif
858e4b17023SJohn Marino
859e4b17023SJohn Marino struct default_spec
860e4b17023SJohn Marino {
861e4b17023SJohn Marino const char *name;
862e4b17023SJohn Marino const char *spec;
863e4b17023SJohn Marino };
864e4b17023SJohn Marino
865e4b17023SJohn Marino static const struct default_spec
866e4b17023SJohn Marino option_default_specs[] = { OPTION_DEFAULT_SPECS };
867e4b17023SJohn Marino
868e4b17023SJohn Marino struct user_specs
869e4b17023SJohn Marino {
870e4b17023SJohn Marino struct user_specs *next;
871e4b17023SJohn Marino const char *filename;
872e4b17023SJohn Marino };
873e4b17023SJohn Marino
874e4b17023SJohn Marino static struct user_specs *user_specs_head, *user_specs_tail;
875e4b17023SJohn Marino
876e4b17023SJohn Marino
877e4b17023SJohn Marino /* Record the mapping from file suffixes for compilation specs. */
878e4b17023SJohn Marino
879e4b17023SJohn Marino struct compiler
880e4b17023SJohn Marino {
881e4b17023SJohn Marino const char *suffix; /* Use this compiler for input files
882e4b17023SJohn Marino whose names end in this suffix. */
883e4b17023SJohn Marino
884e4b17023SJohn Marino const char *spec; /* To use this compiler, run this spec. */
885e4b17023SJohn Marino
886e4b17023SJohn Marino const char *cpp_spec; /* If non-NULL, substitute this spec
887e4b17023SJohn Marino for `%C', rather than the usual
888e4b17023SJohn Marino cpp_spec. */
889e4b17023SJohn Marino const int combinable; /* If nonzero, compiler can deal with
890e4b17023SJohn Marino multiple source files at once (IMA). */
891e4b17023SJohn Marino const int needs_preprocessing; /* If nonzero, source files need to
892e4b17023SJohn Marino be run through a preprocessor. */
893e4b17023SJohn Marino };
894e4b17023SJohn Marino
895e4b17023SJohn Marino /* Pointer to a vector of `struct compiler' that gives the spec for
896e4b17023SJohn Marino compiling a file, based on its suffix.
897e4b17023SJohn Marino A file that does not end in any of these suffixes will be passed
898e4b17023SJohn Marino unchanged to the loader and nothing else will be done to it.
899e4b17023SJohn Marino
900e4b17023SJohn Marino An entry containing two 0s is used to terminate the vector.
901e4b17023SJohn Marino
902e4b17023SJohn Marino If multiple entries match a file, the last matching one is used. */
903e4b17023SJohn Marino
904e4b17023SJohn Marino static struct compiler *compilers;
905e4b17023SJohn Marino
906e4b17023SJohn Marino /* Number of entries in `compilers', not counting the null terminator. */
907e4b17023SJohn Marino
908e4b17023SJohn Marino static int n_compilers;
909e4b17023SJohn Marino
910e4b17023SJohn Marino /* The default list of file name suffixes and their compilation specs. */
911e4b17023SJohn Marino
912e4b17023SJohn Marino static const struct compiler default_compilers[] =
913e4b17023SJohn Marino {
914e4b17023SJohn Marino /* Add lists of suffixes of known languages here. If those languages
915e4b17023SJohn Marino were not present when we built the driver, we will hit these copies
916e4b17023SJohn Marino and be given a more meaningful error than "file not used since
917e4b17023SJohn Marino linking is not done". */
918e4b17023SJohn Marino {".m", "#Objective-C", 0, 0, 0}, {".mi", "#Objective-C", 0, 0, 0},
919e4b17023SJohn Marino {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
920e4b17023SJohn Marino {".mii", "#Objective-C++", 0, 0, 0},
921e4b17023SJohn Marino {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
922e4b17023SJohn Marino {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
923e4b17023SJohn Marino {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
924e4b17023SJohn Marino {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
925e4b17023SJohn Marino {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
926e4b17023SJohn Marino {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
927e4b17023SJohn Marino {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
928e4b17023SJohn Marino {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0},
929e4b17023SJohn Marino {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
930e4b17023SJohn Marino {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0},
931e4b17023SJohn Marino {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
932e4b17023SJohn Marino {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0},
933e4b17023SJohn Marino {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0},
934e4b17023SJohn Marino {".r", "#Ratfor", 0, 0, 0},
935e4b17023SJohn Marino {".p", "#Pascal", 0, 0, 0}, {".pas", "#Pascal", 0, 0, 0},
936e4b17023SJohn Marino {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0},
937e4b17023SJohn Marino {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0},
938e4b17023SJohn Marino {".go", "#Go", 0, 1, 0},
939e4b17023SJohn Marino /* Next come the entries for C. */
940e4b17023SJohn Marino {".c", "@c", 0, 0, 1},
941e4b17023SJohn Marino {"@c",
942e4b17023SJohn Marino /* cc1 has an integrated ISO C preprocessor. We should invoke the
943e4b17023SJohn Marino external preprocessor if -save-temps is given. */
944e4b17023SJohn Marino "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
945e4b17023SJohn Marino %{!E:%{!M:%{!MM:\
946e4b17023SJohn Marino %{traditional:\
947e4b17023SJohn Marino %eGNU C no longer supports -traditional without -E}\
948e4b17023SJohn Marino %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
949e4b17023SJohn Marino %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
950e4b17023SJohn Marino cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
951e4b17023SJohn Marino %(cc1_options)}\
952e4b17023SJohn Marino %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
953e4b17023SJohn Marino cc1 %(cpp_unique_options) %(cc1_options)}}}\
954e4b17023SJohn Marino %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
955e4b17023SJohn Marino {"-",
956e4b17023SJohn Marino "%{!E:%e-E or -x required when input is from standard input}\
957e4b17023SJohn Marino %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
958e4b17023SJohn Marino {".h", "@c-header", 0, 0, 0},
959e4b17023SJohn Marino {"@c-header",
960e4b17023SJohn Marino /* cc1 has an integrated ISO C preprocessor. We should invoke the
961e4b17023SJohn Marino external preprocessor if -save-temps is given. */
962e4b17023SJohn Marino "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
963e4b17023SJohn Marino %{!E:%{!M:%{!MM:\
964e4b17023SJohn Marino %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
965e4b17023SJohn Marino %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
966e4b17023SJohn Marino cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
967e4b17023SJohn Marino %(cc1_options)\
968e4b17023SJohn Marino %{!fdump-ada-spec*:-o %g.s %{!o*:--output-pch=%i.gch}\
969e4b17023SJohn Marino %W{o*:--output-pch=%*}}%V}\
970e4b17023SJohn Marino %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
971e4b17023SJohn Marino cc1 %(cpp_unique_options) %(cc1_options)\
972e4b17023SJohn Marino %{!fdump-ada-spec*:-o %g.s %{!o*:--output-pch=%i.gch}\
973e4b17023SJohn Marino %W{o*:--output-pch=%*}}%V}}}}}}", 0, 0, 0},
974e4b17023SJohn Marino {".i", "@cpp-output", 0, 0, 0},
975e4b17023SJohn Marino {"@cpp-output",
976e4b17023SJohn Marino "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
977e4b17023SJohn Marino {".s", "@assembler", 0, 0, 0},
978e4b17023SJohn Marino {"@assembler",
979e4b17023SJohn Marino "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
980e4b17023SJohn Marino {".sx", "@assembler-with-cpp", 0, 0, 0},
981e4b17023SJohn Marino {".S", "@assembler-with-cpp", 0, 0, 0},
982e4b17023SJohn Marino {"@assembler-with-cpp",
983e4b17023SJohn Marino #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
984e4b17023SJohn Marino "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
985e4b17023SJohn Marino %{E|M|MM:%(cpp_debug_options)}\
986e4b17023SJohn Marino %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
987e4b17023SJohn Marino as %(asm_debug) %(asm_options) %|.s %A }}}}"
988e4b17023SJohn Marino #else
989e4b17023SJohn Marino "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
990e4b17023SJohn Marino %{E|M|MM:%(cpp_debug_options)}\
991e4b17023SJohn Marino %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
992e4b17023SJohn Marino as %(asm_debug) %(asm_options) %m.s %A }}}}"
993e4b17023SJohn Marino #endif
994e4b17023SJohn Marino , 0, 0, 0},
995e4b17023SJohn Marino
996e4b17023SJohn Marino #include "specs.h"
997e4b17023SJohn Marino /* Mark end of table. */
998e4b17023SJohn Marino {0, 0, 0, 0, 0}
999e4b17023SJohn Marino };
1000e4b17023SJohn Marino
1001e4b17023SJohn Marino /* Number of elements in default_compilers, not counting the terminator. */
1002e4b17023SJohn Marino
1003e4b17023SJohn Marino static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
1004e4b17023SJohn Marino
1005e4b17023SJohn Marino typedef char *char_p; /* For DEF_VEC_P. */
1006e4b17023SJohn Marino DEF_VEC_P(char_p);
1007e4b17023SJohn Marino DEF_VEC_ALLOC_P(char_p,heap);
1008e4b17023SJohn Marino
1009e4b17023SJohn Marino /* A vector of options to give to the linker.
1010e4b17023SJohn Marino These options are accumulated by %x,
1011e4b17023SJohn Marino and substituted into the linker command with %X. */
1012e4b17023SJohn Marino static VEC(char_p,heap) *linker_options;
1013e4b17023SJohn Marino
1014e4b17023SJohn Marino /* A vector of options to give to the assembler.
1015e4b17023SJohn Marino These options are accumulated by -Wa,
1016e4b17023SJohn Marino and substituted into the assembler command with %Y. */
1017e4b17023SJohn Marino static VEC(char_p,heap) *assembler_options;
1018e4b17023SJohn Marino
1019e4b17023SJohn Marino /* A vector of options to give to the preprocessor.
1020e4b17023SJohn Marino These options are accumulated by -Wp,
1021e4b17023SJohn Marino and substituted into the preprocessor command with %Z. */
1022e4b17023SJohn Marino static VEC(char_p,heap) *preprocessor_options;
1023e4b17023SJohn Marino
1024e4b17023SJohn Marino static char *
skip_whitespace(char * p)1025e4b17023SJohn Marino skip_whitespace (char *p)
1026e4b17023SJohn Marino {
1027e4b17023SJohn Marino while (1)
1028e4b17023SJohn Marino {
1029e4b17023SJohn Marino /* A fully-blank line is a delimiter in the SPEC file and shouldn't
1030e4b17023SJohn Marino be considered whitespace. */
1031e4b17023SJohn Marino if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
1032e4b17023SJohn Marino return p + 1;
1033e4b17023SJohn Marino else if (*p == '\n' || *p == ' ' || *p == '\t')
1034e4b17023SJohn Marino p++;
1035e4b17023SJohn Marino else if (*p == '#')
1036e4b17023SJohn Marino {
1037e4b17023SJohn Marino while (*p != '\n')
1038e4b17023SJohn Marino p++;
1039e4b17023SJohn Marino p++;
1040e4b17023SJohn Marino }
1041e4b17023SJohn Marino else
1042e4b17023SJohn Marino break;
1043e4b17023SJohn Marino }
1044e4b17023SJohn Marino
1045e4b17023SJohn Marino return p;
1046e4b17023SJohn Marino }
1047e4b17023SJohn Marino /* Structures to keep track of prefixes to try when looking for files. */
1048e4b17023SJohn Marino
1049e4b17023SJohn Marino struct prefix_list
1050e4b17023SJohn Marino {
1051e4b17023SJohn Marino const char *prefix; /* String to prepend to the path. */
1052e4b17023SJohn Marino struct prefix_list *next; /* Next in linked list. */
1053e4b17023SJohn Marino int require_machine_suffix; /* Don't use without machine_suffix. */
1054e4b17023SJohn Marino /* 2 means try both machine_suffix and just_machine_suffix. */
1055e4b17023SJohn Marino int priority; /* Sort key - priority within list. */
1056e4b17023SJohn Marino int os_multilib; /* 1 if OS multilib scheme should be used,
1057e4b17023SJohn Marino 0 for GCC multilib scheme. */
1058e4b17023SJohn Marino };
1059e4b17023SJohn Marino
1060e4b17023SJohn Marino struct path_prefix
1061e4b17023SJohn Marino {
1062e4b17023SJohn Marino struct prefix_list *plist; /* List of prefixes to try */
1063e4b17023SJohn Marino int max_len; /* Max length of a prefix in PLIST */
1064e4b17023SJohn Marino const char *name; /* Name of this list (used in config stuff) */
1065e4b17023SJohn Marino };
1066e4b17023SJohn Marino
1067e4b17023SJohn Marino /* List of prefixes to try when looking for executables. */
1068e4b17023SJohn Marino
1069e4b17023SJohn Marino static struct path_prefix exec_prefixes = { 0, 0, "exec" };
1070e4b17023SJohn Marino
1071e4b17023SJohn Marino /* List of prefixes to try when looking for startup (crt0) files. */
1072e4b17023SJohn Marino
1073e4b17023SJohn Marino static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };
1074e4b17023SJohn Marino
1075e4b17023SJohn Marino /* List of prefixes to try when looking for include files. */
1076e4b17023SJohn Marino
1077e4b17023SJohn Marino static struct path_prefix include_prefixes = { 0, 0, "include" };
1078e4b17023SJohn Marino
1079e4b17023SJohn Marino /* Suffix to attach to directories searched for commands.
1080e4b17023SJohn Marino This looks like `MACHINE/VERSION/'. */
1081e4b17023SJohn Marino
1082e4b17023SJohn Marino static const char *machine_suffix = 0;
1083e4b17023SJohn Marino
1084e4b17023SJohn Marino /* Suffix to attach to directories searched for commands.
1085e4b17023SJohn Marino This is just `MACHINE/'. */
1086e4b17023SJohn Marino
1087e4b17023SJohn Marino static const char *just_machine_suffix = 0;
1088e4b17023SJohn Marino
1089e4b17023SJohn Marino /* Adjusted value of GCC_EXEC_PREFIX envvar. */
1090e4b17023SJohn Marino
1091e4b17023SJohn Marino static const char *gcc_exec_prefix;
1092e4b17023SJohn Marino
1093e4b17023SJohn Marino /* Adjusted value of standard_libexec_prefix. */
1094e4b17023SJohn Marino
1095e4b17023SJohn Marino static const char *gcc_libexec_prefix;
1096e4b17023SJohn Marino
1097e4b17023SJohn Marino /* Default prefixes to attach to command names. */
1098e4b17023SJohn Marino
1099e4b17023SJohn Marino #ifndef STANDARD_STARTFILE_PREFIX_1
1100e4b17023SJohn Marino #define STANDARD_STARTFILE_PREFIX_1 "/lib/"
1101e4b17023SJohn Marino #endif
1102e4b17023SJohn Marino #ifndef STANDARD_STARTFILE_PREFIX_2
1103e4b17023SJohn Marino #define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
1104e4b17023SJohn Marino #endif
1105e4b17023SJohn Marino
1106e4b17023SJohn Marino #ifdef CROSS_DIRECTORY_STRUCTURE /* Don't use these prefixes for a cross compiler. */
1107e4b17023SJohn Marino #undef MD_EXEC_PREFIX
1108e4b17023SJohn Marino #undef MD_STARTFILE_PREFIX
1109e4b17023SJohn Marino #undef MD_STARTFILE_PREFIX_1
1110e4b17023SJohn Marino #endif
1111e4b17023SJohn Marino
1112e4b17023SJohn Marino /* If no prefixes defined, use the null string, which will disable them. */
1113e4b17023SJohn Marino #ifndef MD_EXEC_PREFIX
1114e4b17023SJohn Marino #define MD_EXEC_PREFIX ""
1115e4b17023SJohn Marino #endif
1116e4b17023SJohn Marino #ifndef MD_STARTFILE_PREFIX
1117e4b17023SJohn Marino #define MD_STARTFILE_PREFIX ""
1118e4b17023SJohn Marino #endif
1119e4b17023SJohn Marino #ifndef MD_STARTFILE_PREFIX_1
1120e4b17023SJohn Marino #define MD_STARTFILE_PREFIX_1 ""
1121e4b17023SJohn Marino #endif
1122e4b17023SJohn Marino
1123e4b17023SJohn Marino /* These directories are locations set at configure-time based on the
1124e4b17023SJohn Marino --prefix option provided to configure. Their initializers are
1125e4b17023SJohn Marino defined in Makefile.in. These paths are not *directly* used when
1126e4b17023SJohn Marino gcc_exec_prefix is set because, in that case, we know where the
1127e4b17023SJohn Marino compiler has been installed, and use paths relative to that
1128e4b17023SJohn Marino location instead. */
1129e4b17023SJohn Marino static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
1130e4b17023SJohn Marino static const char *const standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
1131e4b17023SJohn Marino static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
1132e4b17023SJohn Marino static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
1133e4b17023SJohn Marino
1134e4b17023SJohn Marino /* For native compilers, these are well-known paths containing
1135e4b17023SJohn Marino components that may be provided by the system. For cross
1136e4b17023SJohn Marino compilers, these paths are not used. */
1137e4b17023SJohn Marino static const char *md_exec_prefix = MD_EXEC_PREFIX;
1138e4b17023SJohn Marino static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
1139e4b17023SJohn Marino static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
1140e4b17023SJohn Marino static const char *const standard_startfile_prefix_1
1141e4b17023SJohn Marino = STANDARD_STARTFILE_PREFIX_1;
1142e4b17023SJohn Marino static const char *const standard_startfile_prefix_2
1143e4b17023SJohn Marino = STANDARD_STARTFILE_PREFIX_2;
1144e4b17023SJohn Marino
1145e4b17023SJohn Marino /* A relative path to be used in finding the location of tools
1146e4b17023SJohn Marino relative to the driver. */
1147e4b17023SJohn Marino static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
1148e4b17023SJohn Marino
1149e4b17023SJohn Marino /* Subdirectory to use for locating libraries. Set by
1150e4b17023SJohn Marino set_multilib_dir based on the compilation options. */
1151e4b17023SJohn Marino
1152e4b17023SJohn Marino static const char *multilib_dir;
1153e4b17023SJohn Marino
1154e4b17023SJohn Marino /* Subdirectory to use for locating libraries in OS conventions. Set by
1155e4b17023SJohn Marino set_multilib_dir based on the compilation options. */
1156e4b17023SJohn Marino
1157e4b17023SJohn Marino static const char *multilib_os_dir;
11585ce9237cSJohn Marino
11595ce9237cSJohn Marino /* Subdirectory to use for locating libraries in multiarch conventions. Set by
11605ce9237cSJohn Marino set_multilib_dir based on the compilation options. */
11615ce9237cSJohn Marino
11625ce9237cSJohn Marino static const char *multiarch_dir;
1163e4b17023SJohn Marino
1164e4b17023SJohn Marino /* Structure to keep track of the specs that have been defined so far.
1165e4b17023SJohn Marino These are accessed using %(specname) in a compiler or link
1166e4b17023SJohn Marino spec. */
1167e4b17023SJohn Marino
1168e4b17023SJohn Marino struct spec_list
1169e4b17023SJohn Marino {
1170e4b17023SJohn Marino /* The following 2 fields must be first */
1171e4b17023SJohn Marino /* to allow EXTRA_SPECS to be initialized */
1172e4b17023SJohn Marino const char *name; /* name of the spec. */
1173e4b17023SJohn Marino const char *ptr; /* available ptr if no static pointer */
1174e4b17023SJohn Marino
1175e4b17023SJohn Marino /* The following fields are not initialized */
1176e4b17023SJohn Marino /* by EXTRA_SPECS */
1177e4b17023SJohn Marino const char **ptr_spec; /* pointer to the spec itself. */
1178e4b17023SJohn Marino struct spec_list *next; /* Next spec in linked list. */
1179e4b17023SJohn Marino int name_len; /* length of the name */
1180e4b17023SJohn Marino int alloc_p; /* whether string was allocated */
1181e4b17023SJohn Marino };
1182e4b17023SJohn Marino
1183e4b17023SJohn Marino #define INIT_STATIC_SPEC(NAME,PTR) \
1184e4b17023SJohn Marino { NAME, NULL, PTR, (struct spec_list *) 0, sizeof (NAME) - 1, 0 }
1185e4b17023SJohn Marino
1186e4b17023SJohn Marino /* List of statically defined specs. */
1187e4b17023SJohn Marino static struct spec_list static_specs[] =
1188e4b17023SJohn Marino {
1189e4b17023SJohn Marino INIT_STATIC_SPEC ("asm", &asm_spec),
1190e4b17023SJohn Marino INIT_STATIC_SPEC ("asm_debug", &asm_debug),
1191e4b17023SJohn Marino INIT_STATIC_SPEC ("asm_final", &asm_final_spec),
1192e4b17023SJohn Marino INIT_STATIC_SPEC ("asm_options", &asm_options),
1193e4b17023SJohn Marino INIT_STATIC_SPEC ("invoke_as", &invoke_as),
1194e4b17023SJohn Marino INIT_STATIC_SPEC ("cpp", &cpp_spec),
1195e4b17023SJohn Marino INIT_STATIC_SPEC ("cpp_options", &cpp_options),
1196e4b17023SJohn Marino INIT_STATIC_SPEC ("cpp_debug_options", &cpp_debug_options),
1197e4b17023SJohn Marino INIT_STATIC_SPEC ("cpp_unique_options", &cpp_unique_options),
1198e4b17023SJohn Marino INIT_STATIC_SPEC ("trad_capable_cpp", &trad_capable_cpp),
1199e4b17023SJohn Marino INIT_STATIC_SPEC ("cc1", &cc1_spec),
1200e4b17023SJohn Marino INIT_STATIC_SPEC ("cc1_options", &cc1_options),
1201e4b17023SJohn Marino INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec),
1202e4b17023SJohn Marino INIT_STATIC_SPEC ("link_gcc_c_sequence", &link_gcc_c_sequence_spec),
1203e4b17023SJohn Marino INIT_STATIC_SPEC ("link_ssp", &link_ssp_spec),
1204e4b17023SJohn Marino INIT_STATIC_SPEC ("endfile", &endfile_spec),
1205e4b17023SJohn Marino INIT_STATIC_SPEC ("link", &link_spec),
1206e4b17023SJohn Marino INIT_STATIC_SPEC ("lib", &lib_spec),
1207e4b17023SJohn Marino INIT_STATIC_SPEC ("mfwrap", &mfwrap_spec),
1208e4b17023SJohn Marino INIT_STATIC_SPEC ("mflib", &mflib_spec),
1209e4b17023SJohn Marino INIT_STATIC_SPEC ("link_gomp", &link_gomp_spec),
1210e4b17023SJohn Marino INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
1211e4b17023SJohn Marino INIT_STATIC_SPEC ("startfile", &startfile_spec),
1212e4b17023SJohn Marino INIT_STATIC_SPEC ("cross_compile", &cross_compile),
1213e4b17023SJohn Marino INIT_STATIC_SPEC ("version", &compiler_version),
1214e4b17023SJohn Marino INIT_STATIC_SPEC ("multilib", &multilib_select),
1215e4b17023SJohn Marino INIT_STATIC_SPEC ("multilib_defaults", &multilib_defaults),
1216e4b17023SJohn Marino INIT_STATIC_SPEC ("multilib_extra", &multilib_extra),
1217e4b17023SJohn Marino INIT_STATIC_SPEC ("multilib_matches", &multilib_matches),
1218e4b17023SJohn Marino INIT_STATIC_SPEC ("multilib_exclusions", &multilib_exclusions),
1219e4b17023SJohn Marino INIT_STATIC_SPEC ("multilib_options", &multilib_options),
1220e4b17023SJohn Marino INIT_STATIC_SPEC ("linker", &linker_name_spec),
1221e4b17023SJohn Marino INIT_STATIC_SPEC ("linker_plugin_file", &linker_plugin_file_spec),
1222e4b17023SJohn Marino INIT_STATIC_SPEC ("lto_wrapper", <o_wrapper_spec),
1223e4b17023SJohn Marino INIT_STATIC_SPEC ("lto_gcc", <o_gcc_spec),
1224e4b17023SJohn Marino INIT_STATIC_SPEC ("link_libgcc", &link_libgcc_spec),
1225e4b17023SJohn Marino INIT_STATIC_SPEC ("md_exec_prefix", &md_exec_prefix),
1226e4b17023SJohn Marino INIT_STATIC_SPEC ("md_startfile_prefix", &md_startfile_prefix),
1227e4b17023SJohn Marino INIT_STATIC_SPEC ("md_startfile_prefix_1", &md_startfile_prefix_1),
1228e4b17023SJohn Marino INIT_STATIC_SPEC ("startfile_prefix_spec", &startfile_prefix_spec),
1229e4b17023SJohn Marino INIT_STATIC_SPEC ("sysroot_spec", &sysroot_spec),
1230e4b17023SJohn Marino INIT_STATIC_SPEC ("sysroot_suffix_spec", &sysroot_suffix_spec),
1231e4b17023SJohn Marino INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec", &sysroot_hdrs_suffix_spec),
1232e4b17023SJohn Marino INIT_STATIC_SPEC ("self_spec", &self_spec),
1233e4b17023SJohn Marino };
1234e4b17023SJohn Marino
1235e4b17023SJohn Marino #ifdef EXTRA_SPECS /* additional specs needed */
1236e4b17023SJohn Marino /* Structure to keep track of just the first two args of a spec_list.
1237e4b17023SJohn Marino That is all that the EXTRA_SPECS macro gives us. */
1238e4b17023SJohn Marino struct spec_list_1
1239e4b17023SJohn Marino {
1240e4b17023SJohn Marino const char *const name;
1241e4b17023SJohn Marino const char *const ptr;
1242e4b17023SJohn Marino };
1243e4b17023SJohn Marino
1244e4b17023SJohn Marino static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
1245e4b17023SJohn Marino static struct spec_list *extra_specs = (struct spec_list *) 0;
1246e4b17023SJohn Marino #endif
1247e4b17023SJohn Marino
1248e4b17023SJohn Marino /* List of dynamically allocates specs that have been defined so far. */
1249e4b17023SJohn Marino
1250e4b17023SJohn Marino static struct spec_list *specs = (struct spec_list *) 0;
1251e4b17023SJohn Marino
1252e4b17023SJohn Marino /* List of static spec functions. */
1253e4b17023SJohn Marino
1254e4b17023SJohn Marino static const struct spec_function static_spec_functions[] =
1255e4b17023SJohn Marino {
1256e4b17023SJohn Marino { "getenv", getenv_spec_function },
1257e4b17023SJohn Marino { "if-exists", if_exists_spec_function },
1258e4b17023SJohn Marino { "if-exists-else", if_exists_else_spec_function },
1259e4b17023SJohn Marino { "replace-outfile", replace_outfile_spec_function },
1260e4b17023SJohn Marino { "remove-outfile", remove_outfile_spec_function },
1261e4b17023SJohn Marino { "version-compare", version_compare_spec_function },
1262e4b17023SJohn Marino { "include", include_spec_function },
1263e4b17023SJohn Marino { "find-file", find_file_spec_function },
1264e4b17023SJohn Marino { "find-plugindir", find_plugindir_spec_function },
1265e4b17023SJohn Marino { "print-asm-header", print_asm_header_spec_function },
1266e4b17023SJohn Marino { "compare-debug-dump-opt", compare_debug_dump_opt_spec_function },
1267e4b17023SJohn Marino { "compare-debug-self-opt", compare_debug_self_opt_spec_function },
1268e4b17023SJohn Marino { "compare-debug-auxbase-opt", compare_debug_auxbase_opt_spec_function },
1269e4b17023SJohn Marino { "pass-through-libs", pass_through_libs_spec_func },
1270e4b17023SJohn Marino #ifdef EXTRA_SPEC_FUNCTIONS
1271e4b17023SJohn Marino EXTRA_SPEC_FUNCTIONS
1272e4b17023SJohn Marino #endif
1273e4b17023SJohn Marino { 0, 0 }
1274e4b17023SJohn Marino };
1275e4b17023SJohn Marino
1276e4b17023SJohn Marino static int processing_spec_function;
1277e4b17023SJohn Marino
1278e4b17023SJohn Marino /* Add appropriate libgcc specs to OBSTACK, taking into account
1279e4b17023SJohn Marino various permutations of -shared-libgcc, -shared, and such. */
1280e4b17023SJohn Marino
1281e4b17023SJohn Marino #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
1282e4b17023SJohn Marino
1283e4b17023SJohn Marino #ifndef USE_LD_AS_NEEDED
1284e4b17023SJohn Marino #define USE_LD_AS_NEEDED 0
1285e4b17023SJohn Marino #endif
1286e4b17023SJohn Marino
1287e4b17023SJohn Marino static void
init_gcc_specs(struct obstack * obstack,const char * shared_name,const char * static_name,const char * eh_name)1288e4b17023SJohn Marino init_gcc_specs (struct obstack *obstack, const char *shared_name,
1289e4b17023SJohn Marino const char *static_name, const char *eh_name)
1290e4b17023SJohn Marino {
1291e4b17023SJohn Marino char *buf;
1292e4b17023SJohn Marino
1293e4b17023SJohn Marino buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name, "}"
1294e4b17023SJohn Marino "%{!static:%{!static-libgcc:"
1295e4b17023SJohn Marino #if USE_LD_AS_NEEDED
1296e4b17023SJohn Marino "%{!shared-libgcc:",
1297e4b17023SJohn Marino static_name, " --as-needed ", shared_name, " --no-as-needed"
1298e4b17023SJohn Marino "}"
1299e4b17023SJohn Marino "%{shared-libgcc:",
1300e4b17023SJohn Marino shared_name, "%{!shared: ", static_name, "}"
1301e4b17023SJohn Marino "}"
1302e4b17023SJohn Marino #else
1303e4b17023SJohn Marino "%{!shared:"
1304e4b17023SJohn Marino "%{!shared-libgcc:", static_name, " ", eh_name, "}"
1305e4b17023SJohn Marino "%{shared-libgcc:", shared_name, " ", static_name, "}"
1306e4b17023SJohn Marino "}"
1307e4b17023SJohn Marino #ifdef LINK_EH_SPEC
1308e4b17023SJohn Marino "%{shared:"
1309e4b17023SJohn Marino "%{shared-libgcc:", shared_name, "}"
1310e4b17023SJohn Marino "%{!shared-libgcc:", static_name, "}"
1311e4b17023SJohn Marino "}"
1312e4b17023SJohn Marino #else
1313e4b17023SJohn Marino "%{shared:", shared_name, "}"
1314e4b17023SJohn Marino #endif
1315e4b17023SJohn Marino #endif
1316e4b17023SJohn Marino "}}", NULL);
1317e4b17023SJohn Marino
1318e4b17023SJohn Marino obstack_grow (obstack, buf, strlen (buf));
1319e4b17023SJohn Marino free (buf);
1320e4b17023SJohn Marino }
1321e4b17023SJohn Marino #endif /* ENABLE_SHARED_LIBGCC */
1322e4b17023SJohn Marino
1323e4b17023SJohn Marino /* Initialize the specs lookup routines. */
1324e4b17023SJohn Marino
1325e4b17023SJohn Marino static void
init_spec(void)1326e4b17023SJohn Marino init_spec (void)
1327e4b17023SJohn Marino {
1328e4b17023SJohn Marino struct spec_list *next = (struct spec_list *) 0;
1329e4b17023SJohn Marino struct spec_list *sl = (struct spec_list *) 0;
1330e4b17023SJohn Marino int i;
1331e4b17023SJohn Marino
1332e4b17023SJohn Marino if (specs)
1333e4b17023SJohn Marino return; /* Already initialized. */
1334e4b17023SJohn Marino
1335e4b17023SJohn Marino if (verbose_flag)
1336e4b17023SJohn Marino fnotice (stderr, "Using built-in specs.\n");
1337e4b17023SJohn Marino
1338e4b17023SJohn Marino #ifdef EXTRA_SPECS
1339e4b17023SJohn Marino extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1));
1340e4b17023SJohn Marino
1341e4b17023SJohn Marino for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
1342e4b17023SJohn Marino {
1343e4b17023SJohn Marino sl = &extra_specs[i];
1344e4b17023SJohn Marino sl->name = extra_specs_1[i].name;
1345e4b17023SJohn Marino sl->ptr = extra_specs_1[i].ptr;
1346e4b17023SJohn Marino sl->next = next;
1347e4b17023SJohn Marino sl->name_len = strlen (sl->name);
1348e4b17023SJohn Marino sl->ptr_spec = &sl->ptr;
1349e4b17023SJohn Marino next = sl;
1350e4b17023SJohn Marino }
1351e4b17023SJohn Marino #endif
1352e4b17023SJohn Marino
1353e4b17023SJohn Marino for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
1354e4b17023SJohn Marino {
1355e4b17023SJohn Marino sl = &static_specs[i];
1356e4b17023SJohn Marino sl->next = next;
1357e4b17023SJohn Marino next = sl;
1358e4b17023SJohn Marino }
1359e4b17023SJohn Marino
1360e4b17023SJohn Marino #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
1361e4b17023SJohn Marino /* ??? If neither -shared-libgcc nor --static-libgcc was
1362e4b17023SJohn Marino seen, then we should be making an educated guess. Some proposed
1363e4b17023SJohn Marino heuristics for ELF include:
1364e4b17023SJohn Marino
1365e4b17023SJohn Marino (1) If "-Wl,--export-dynamic", then it's a fair bet that the
1366e4b17023SJohn Marino program will be doing dynamic loading, which will likely
1367e4b17023SJohn Marino need the shared libgcc.
1368e4b17023SJohn Marino
1369e4b17023SJohn Marino (2) If "-ldl", then it's also a fair bet that we're doing
1370e4b17023SJohn Marino dynamic loading.
1371e4b17023SJohn Marino
1372e4b17023SJohn Marino (3) For each ET_DYN we're linking against (either through -lfoo
1373e4b17023SJohn Marino or /some/path/foo.so), check to see whether it or one of
1374e4b17023SJohn Marino its dependencies depends on a shared libgcc.
1375e4b17023SJohn Marino
1376e4b17023SJohn Marino (4) If "-shared"
1377e4b17023SJohn Marino
1378e4b17023SJohn Marino If the runtime is fixed to look for program headers instead
1379e4b17023SJohn Marino of calling __register_frame_info at all, for each object,
1380e4b17023SJohn Marino use the shared libgcc if any EH symbol referenced.
1381e4b17023SJohn Marino
1382e4b17023SJohn Marino If crtstuff is fixed to not invoke __register_frame_info
1383e4b17023SJohn Marino automatically, for each object, use the shared libgcc if
1384e4b17023SJohn Marino any non-empty unwind section found.
1385e4b17023SJohn Marino
1386e4b17023SJohn Marino Doing any of this probably requires invoking an external program to
1387e4b17023SJohn Marino do the actual object file scanning. */
1388e4b17023SJohn Marino {
1389e4b17023SJohn Marino const char *p = libgcc_spec;
1390e4b17023SJohn Marino int in_sep = 1;
1391e4b17023SJohn Marino
1392e4b17023SJohn Marino /* Transform the extant libgcc_spec into one that uses the shared libgcc
1393e4b17023SJohn Marino when given the proper command line arguments. */
1394e4b17023SJohn Marino while (*p)
1395e4b17023SJohn Marino {
1396e4b17023SJohn Marino if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
1397e4b17023SJohn Marino {
1398e4b17023SJohn Marino init_gcc_specs (&obstack,
1399e4b17023SJohn Marino "-lgcc_s"
1400e4b17023SJohn Marino #ifdef USE_LIBUNWIND_EXCEPTIONS
1401e4b17023SJohn Marino " -lunwind"
1402e4b17023SJohn Marino #endif
1403e4b17023SJohn Marino ,
1404e4b17023SJohn Marino "-lgcc",
1405e4b17023SJohn Marino "-lgcc_eh"
1406e4b17023SJohn Marino #ifdef USE_LIBUNWIND_EXCEPTIONS
1407e4b17023SJohn Marino # ifdef HAVE_LD_STATIC_DYNAMIC
1408e4b17023SJohn Marino " %{!static:" LD_STATIC_OPTION "} -lunwind"
1409e4b17023SJohn Marino " %{!static:" LD_DYNAMIC_OPTION "}"
1410e4b17023SJohn Marino # else
1411e4b17023SJohn Marino " -lunwind"
1412e4b17023SJohn Marino # endif
1413e4b17023SJohn Marino #endif
1414e4b17023SJohn Marino );
1415e4b17023SJohn Marino
1416e4b17023SJohn Marino p += 5;
1417e4b17023SJohn Marino in_sep = 0;
1418e4b17023SJohn Marino }
1419e4b17023SJohn Marino else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
1420e4b17023SJohn Marino {
1421e4b17023SJohn Marino /* Ug. We don't know shared library extensions. Hope that
1422e4b17023SJohn Marino systems that use this form don't do shared libraries. */
1423e4b17023SJohn Marino init_gcc_specs (&obstack,
1424e4b17023SJohn Marino "-lgcc_s",
1425e4b17023SJohn Marino "libgcc.a%s",
1426e4b17023SJohn Marino "libgcc_eh.a%s"
1427e4b17023SJohn Marino #ifdef USE_LIBUNWIND_EXCEPTIONS
1428e4b17023SJohn Marino " -lunwind"
1429e4b17023SJohn Marino #endif
1430e4b17023SJohn Marino );
1431e4b17023SJohn Marino p += 10;
1432e4b17023SJohn Marino in_sep = 0;
1433e4b17023SJohn Marino }
1434e4b17023SJohn Marino else
1435e4b17023SJohn Marino {
1436e4b17023SJohn Marino obstack_1grow (&obstack, *p);
1437e4b17023SJohn Marino in_sep = (*p == ' ');
1438e4b17023SJohn Marino p += 1;
1439e4b17023SJohn Marino }
1440e4b17023SJohn Marino }
1441e4b17023SJohn Marino
1442e4b17023SJohn Marino obstack_1grow (&obstack, '\0');
1443e4b17023SJohn Marino libgcc_spec = XOBFINISH (&obstack, const char *);
1444e4b17023SJohn Marino }
1445e4b17023SJohn Marino #endif
1446e4b17023SJohn Marino #ifdef USE_AS_TRADITIONAL_FORMAT
1447e4b17023SJohn Marino /* Prepend "--traditional-format" to whatever asm_spec we had before. */
1448e4b17023SJohn Marino {
1449e4b17023SJohn Marino static const char tf[] = "--traditional-format ";
1450e4b17023SJohn Marino obstack_grow (&obstack, tf, sizeof(tf) - 1);
1451e4b17023SJohn Marino obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
1452e4b17023SJohn Marino asm_spec = XOBFINISH (&obstack, const char *);
1453e4b17023SJohn Marino }
1454e4b17023SJohn Marino #endif
1455e4b17023SJohn Marino
1456e4b17023SJohn Marino #if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC || \
1457e4b17023SJohn Marino defined LINKER_HASH_STYLE
1458e4b17023SJohn Marino # ifdef LINK_BUILDID_SPEC
1459e4b17023SJohn Marino /* Prepend LINK_BUILDID_SPEC to whatever link_spec we had before. */
1460e4b17023SJohn Marino obstack_grow (&obstack, LINK_BUILDID_SPEC, sizeof(LINK_BUILDID_SPEC) - 1);
1461e4b17023SJohn Marino # endif
1462e4b17023SJohn Marino # ifdef LINK_EH_SPEC
1463e4b17023SJohn Marino /* Prepend LINK_EH_SPEC to whatever link_spec we had before. */
1464e4b17023SJohn Marino obstack_grow (&obstack, LINK_EH_SPEC, sizeof(LINK_EH_SPEC) - 1);
1465e4b17023SJohn Marino # endif
1466e4b17023SJohn Marino # ifdef LINKER_HASH_STYLE
1467e4b17023SJohn Marino /* Prepend --hash-style=LINKER_HASH_STYLE to whatever link_spec we had
1468e4b17023SJohn Marino before. */
1469e4b17023SJohn Marino {
1470e4b17023SJohn Marino static const char hash_style[] = "--hash-style=";
1471e4b17023SJohn Marino obstack_grow (&obstack, hash_style, sizeof(hash_style) - 1);
1472e4b17023SJohn Marino obstack_grow (&obstack, LINKER_HASH_STYLE, sizeof(LINKER_HASH_STYLE) - 1);
1473e4b17023SJohn Marino obstack_1grow (&obstack, ' ');
1474e4b17023SJohn Marino }
1475e4b17023SJohn Marino # endif
1476e4b17023SJohn Marino obstack_grow0 (&obstack, link_spec, strlen (link_spec));
1477e4b17023SJohn Marino link_spec = XOBFINISH (&obstack, const char *);
1478e4b17023SJohn Marino #endif
1479e4b17023SJohn Marino
1480e4b17023SJohn Marino specs = sl;
1481e4b17023SJohn Marino }
1482e4b17023SJohn Marino
1483e4b17023SJohn Marino /* Change the value of spec NAME to SPEC. If SPEC is empty, then the spec is
1484e4b17023SJohn Marino removed; If the spec starts with a + then SPEC is added to the end of the
1485e4b17023SJohn Marino current spec. */
1486e4b17023SJohn Marino
1487e4b17023SJohn Marino static void
set_spec(const char * name,const char * spec)1488e4b17023SJohn Marino set_spec (const char *name, const char *spec)
1489e4b17023SJohn Marino {
1490e4b17023SJohn Marino struct spec_list *sl;
1491e4b17023SJohn Marino const char *old_spec;
1492e4b17023SJohn Marino int name_len = strlen (name);
1493e4b17023SJohn Marino int i;
1494e4b17023SJohn Marino
1495e4b17023SJohn Marino /* If this is the first call, initialize the statically allocated specs. */
1496e4b17023SJohn Marino if (!specs)
1497e4b17023SJohn Marino {
1498e4b17023SJohn Marino struct spec_list *next = (struct spec_list *) 0;
1499e4b17023SJohn Marino for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
1500e4b17023SJohn Marino {
1501e4b17023SJohn Marino sl = &static_specs[i];
1502e4b17023SJohn Marino sl->next = next;
1503e4b17023SJohn Marino next = sl;
1504e4b17023SJohn Marino }
1505e4b17023SJohn Marino specs = sl;
1506e4b17023SJohn Marino }
1507e4b17023SJohn Marino
1508e4b17023SJohn Marino /* See if the spec already exists. */
1509e4b17023SJohn Marino for (sl = specs; sl; sl = sl->next)
1510e4b17023SJohn Marino if (name_len == sl->name_len && !strcmp (sl->name, name))
1511e4b17023SJohn Marino break;
1512e4b17023SJohn Marino
1513e4b17023SJohn Marino if (!sl)
1514e4b17023SJohn Marino {
1515e4b17023SJohn Marino /* Not found - make it. */
1516e4b17023SJohn Marino sl = XNEW (struct spec_list);
1517e4b17023SJohn Marino sl->name = xstrdup (name);
1518e4b17023SJohn Marino sl->name_len = name_len;
1519e4b17023SJohn Marino sl->ptr_spec = &sl->ptr;
1520e4b17023SJohn Marino sl->alloc_p = 0;
1521e4b17023SJohn Marino *(sl->ptr_spec) = "";
1522e4b17023SJohn Marino sl->next = specs;
1523e4b17023SJohn Marino specs = sl;
1524e4b17023SJohn Marino }
1525e4b17023SJohn Marino
1526e4b17023SJohn Marino old_spec = *(sl->ptr_spec);
1527e4b17023SJohn Marino *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
1528e4b17023SJohn Marino ? concat (old_spec, spec + 1, NULL)
1529e4b17023SJohn Marino : xstrdup (spec));
1530e4b17023SJohn Marino
1531e4b17023SJohn Marino #ifdef DEBUG_SPECS
1532e4b17023SJohn Marino if (verbose_flag)
1533e4b17023SJohn Marino fnotice (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
1534e4b17023SJohn Marino #endif
1535e4b17023SJohn Marino
1536e4b17023SJohn Marino /* Free the old spec. */
1537e4b17023SJohn Marino if (old_spec && sl->alloc_p)
1538e4b17023SJohn Marino free (CONST_CAST(char *, old_spec));
1539e4b17023SJohn Marino
1540e4b17023SJohn Marino sl->alloc_p = 1;
1541e4b17023SJohn Marino }
1542e4b17023SJohn Marino
1543e4b17023SJohn Marino /* Accumulate a command (program name and args), and run it. */
1544e4b17023SJohn Marino
1545e4b17023SJohn Marino typedef const char *const_char_p; /* For DEF_VEC_P. */
1546e4b17023SJohn Marino DEF_VEC_P(const_char_p);
1547e4b17023SJohn Marino DEF_VEC_ALLOC_P(const_char_p,heap);
1548e4b17023SJohn Marino
1549e4b17023SJohn Marino /* Vector of pointers to arguments in the current line of specifications. */
1550e4b17023SJohn Marino
1551e4b17023SJohn Marino static VEC(const_char_p,heap) *argbuf;
1552e4b17023SJohn Marino
1553e4b17023SJohn Marino /* Position in the argbuf vector containing the name of the output file
1554e4b17023SJohn Marino (the value associated with the "-o" flag). */
1555e4b17023SJohn Marino
1556e4b17023SJohn Marino static int have_o_argbuf_index = 0;
1557e4b17023SJohn Marino
1558e4b17023SJohn Marino /* Were the options -c, -S or -E passed. */
1559e4b17023SJohn Marino static int have_c = 0;
1560e4b17023SJohn Marino
1561e4b17023SJohn Marino /* Was the option -o passed. */
1562e4b17023SJohn Marino static int have_o = 0;
1563e4b17023SJohn Marino
1564e4b17023SJohn Marino /* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
1565e4b17023SJohn Marino temp file. If the HOST_BIT_BUCKET is used for %j, no entry is made for
1566e4b17023SJohn Marino it here. */
1567e4b17023SJohn Marino
1568e4b17023SJohn Marino static struct temp_name {
1569e4b17023SJohn Marino const char *suffix; /* suffix associated with the code. */
1570e4b17023SJohn Marino int length; /* strlen (suffix). */
1571e4b17023SJohn Marino int unique; /* Indicates whether %g or %u/%U was used. */
1572e4b17023SJohn Marino const char *filename; /* associated filename. */
1573e4b17023SJohn Marino int filename_length; /* strlen (filename). */
1574e4b17023SJohn Marino struct temp_name *next;
1575e4b17023SJohn Marino } *temp_names;
1576e4b17023SJohn Marino
1577e4b17023SJohn Marino /* Number of commands executed so far. */
1578e4b17023SJohn Marino
1579e4b17023SJohn Marino static int execution_count;
1580e4b17023SJohn Marino
1581e4b17023SJohn Marino /* Number of commands that exited with a signal. */
1582e4b17023SJohn Marino
1583e4b17023SJohn Marino static int signal_count;
1584e4b17023SJohn Marino
1585e4b17023SJohn Marino /* Allocate the argument vector. */
1586e4b17023SJohn Marino
1587e4b17023SJohn Marino static void
alloc_args(void)1588e4b17023SJohn Marino alloc_args (void)
1589e4b17023SJohn Marino {
1590e4b17023SJohn Marino argbuf = VEC_alloc (const_char_p, heap, 10);
1591e4b17023SJohn Marino }
1592e4b17023SJohn Marino
1593e4b17023SJohn Marino /* Clear out the vector of arguments (after a command is executed). */
1594e4b17023SJohn Marino
1595e4b17023SJohn Marino static void
clear_args(void)1596e4b17023SJohn Marino clear_args (void)
1597e4b17023SJohn Marino {
1598e4b17023SJohn Marino VEC_truncate (const_char_p, argbuf, 0);
1599e4b17023SJohn Marino }
1600e4b17023SJohn Marino
1601e4b17023SJohn Marino /* Add one argument to the vector at the end.
1602e4b17023SJohn Marino This is done when a space is seen or at the end of the line.
1603e4b17023SJohn Marino If DELETE_ALWAYS is nonzero, the arg is a filename
1604e4b17023SJohn Marino and the file should be deleted eventually.
1605e4b17023SJohn Marino If DELETE_FAILURE is nonzero, the arg is a filename
1606e4b17023SJohn Marino and the file should be deleted if this compilation fails. */
1607e4b17023SJohn Marino
1608e4b17023SJohn Marino static void
store_arg(const char * arg,int delete_always,int delete_failure)1609e4b17023SJohn Marino store_arg (const char *arg, int delete_always, int delete_failure)
1610e4b17023SJohn Marino {
1611e4b17023SJohn Marino VEC_safe_push (const_char_p, heap, argbuf, arg);
1612e4b17023SJohn Marino
1613e4b17023SJohn Marino if (strcmp (arg, "-o") == 0)
1614e4b17023SJohn Marino have_o_argbuf_index = VEC_length (const_char_p, argbuf);
1615e4b17023SJohn Marino if (delete_always || delete_failure)
1616e4b17023SJohn Marino {
1617e4b17023SJohn Marino const char *p;
1618e4b17023SJohn Marino /* If the temporary file we should delete is specified as
1619e4b17023SJohn Marino part of a joined argument extract the filename. */
1620e4b17023SJohn Marino if (arg[0] == '-'
1621e4b17023SJohn Marino && (p = strrchr (arg, '=')))
1622e4b17023SJohn Marino arg = p + 1;
1623e4b17023SJohn Marino record_temp_file (arg, delete_always, delete_failure);
1624e4b17023SJohn Marino }
1625e4b17023SJohn Marino }
1626e4b17023SJohn Marino
1627e4b17023SJohn Marino /* Load specs from a file name named FILENAME, replacing occurrences of
1628e4b17023SJohn Marino various different types of line-endings, \r\n, \n\r and just \r, with
1629e4b17023SJohn Marino a single \n. */
1630e4b17023SJohn Marino
1631e4b17023SJohn Marino static char *
load_specs(const char * filename)1632e4b17023SJohn Marino load_specs (const char *filename)
1633e4b17023SJohn Marino {
1634e4b17023SJohn Marino int desc;
1635e4b17023SJohn Marino int readlen;
1636e4b17023SJohn Marino struct stat statbuf;
1637e4b17023SJohn Marino char *buffer;
1638e4b17023SJohn Marino char *buffer_p;
1639e4b17023SJohn Marino char *specs;
1640e4b17023SJohn Marino char *specs_p;
1641e4b17023SJohn Marino
1642e4b17023SJohn Marino if (verbose_flag)
1643e4b17023SJohn Marino fnotice (stderr, "Reading specs from %s\n", filename);
1644e4b17023SJohn Marino
1645e4b17023SJohn Marino /* Open and stat the file. */
1646e4b17023SJohn Marino desc = open (filename, O_RDONLY, 0);
1647e4b17023SJohn Marino if (desc < 0)
1648e4b17023SJohn Marino pfatal_with_name (filename);
1649e4b17023SJohn Marino if (stat (filename, &statbuf) < 0)
1650e4b17023SJohn Marino pfatal_with_name (filename);
1651e4b17023SJohn Marino
1652e4b17023SJohn Marino /* Read contents of file into BUFFER. */
1653e4b17023SJohn Marino buffer = XNEWVEC (char, statbuf.st_size + 1);
1654e4b17023SJohn Marino readlen = read (desc, buffer, (unsigned) statbuf.st_size);
1655e4b17023SJohn Marino if (readlen < 0)
1656e4b17023SJohn Marino pfatal_with_name (filename);
1657e4b17023SJohn Marino buffer[readlen] = 0;
1658e4b17023SJohn Marino close (desc);
1659e4b17023SJohn Marino
1660e4b17023SJohn Marino specs = XNEWVEC (char, readlen + 1);
1661e4b17023SJohn Marino specs_p = specs;
1662e4b17023SJohn Marino for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
1663e4b17023SJohn Marino {
1664e4b17023SJohn Marino int skip = 0;
1665e4b17023SJohn Marino char c = *buffer_p;
1666e4b17023SJohn Marino if (c == '\r')
1667e4b17023SJohn Marino {
1668e4b17023SJohn Marino if (buffer_p > buffer && *(buffer_p - 1) == '\n') /* \n\r */
1669e4b17023SJohn Marino skip = 1;
1670e4b17023SJohn Marino else if (*(buffer_p + 1) == '\n') /* \r\n */
1671e4b17023SJohn Marino skip = 1;
1672e4b17023SJohn Marino else /* \r */
1673e4b17023SJohn Marino c = '\n';
1674e4b17023SJohn Marino }
1675e4b17023SJohn Marino if (! skip)
1676e4b17023SJohn Marino *specs_p++ = c;
1677e4b17023SJohn Marino }
1678e4b17023SJohn Marino *specs_p = '\0';
1679e4b17023SJohn Marino
1680e4b17023SJohn Marino free (buffer);
1681e4b17023SJohn Marino return (specs);
1682e4b17023SJohn Marino }
1683e4b17023SJohn Marino
1684e4b17023SJohn Marino /* Read compilation specs from a file named FILENAME,
1685e4b17023SJohn Marino replacing the default ones.
1686e4b17023SJohn Marino
1687e4b17023SJohn Marino A suffix which starts with `*' is a definition for
1688e4b17023SJohn Marino one of the machine-specific sub-specs. The "suffix" should be
1689e4b17023SJohn Marino *asm, *cc1, *cpp, *link, *startfile, etc.
1690e4b17023SJohn Marino The corresponding spec is stored in asm_spec, etc.,
1691e4b17023SJohn Marino rather than in the `compilers' vector.
1692e4b17023SJohn Marino
1693e4b17023SJohn Marino Anything invalid in the file is a fatal error. */
1694e4b17023SJohn Marino
1695e4b17023SJohn Marino static void
read_specs(const char * filename,int main_p)1696e4b17023SJohn Marino read_specs (const char *filename, int main_p)
1697e4b17023SJohn Marino {
1698e4b17023SJohn Marino char *buffer;
1699e4b17023SJohn Marino char *p;
1700e4b17023SJohn Marino
1701e4b17023SJohn Marino buffer = load_specs (filename);
1702e4b17023SJohn Marino
1703e4b17023SJohn Marino /* Scan BUFFER for specs, putting them in the vector. */
1704e4b17023SJohn Marino p = buffer;
1705e4b17023SJohn Marino while (1)
1706e4b17023SJohn Marino {
1707e4b17023SJohn Marino char *suffix;
1708e4b17023SJohn Marino char *spec;
1709e4b17023SJohn Marino char *in, *out, *p1, *p2, *p3;
1710e4b17023SJohn Marino
1711e4b17023SJohn Marino /* Advance P in BUFFER to the next nonblank nocomment line. */
1712e4b17023SJohn Marino p = skip_whitespace (p);
1713e4b17023SJohn Marino if (*p == 0)
1714e4b17023SJohn Marino break;
1715e4b17023SJohn Marino
1716e4b17023SJohn Marino /* Is this a special command that starts with '%'? */
1717e4b17023SJohn Marino /* Don't allow this for the main specs file, since it would
1718e4b17023SJohn Marino encourage people to overwrite it. */
1719e4b17023SJohn Marino if (*p == '%' && !main_p)
1720e4b17023SJohn Marino {
1721e4b17023SJohn Marino p1 = p;
1722e4b17023SJohn Marino while (*p && *p != '\n')
1723e4b17023SJohn Marino p++;
1724e4b17023SJohn Marino
1725e4b17023SJohn Marino /* Skip '\n'. */
1726e4b17023SJohn Marino p++;
1727e4b17023SJohn Marino
1728e4b17023SJohn Marino if (!strncmp (p1, "%include", sizeof ("%include") - 1)
1729e4b17023SJohn Marino && (p1[sizeof "%include" - 1] == ' '
1730e4b17023SJohn Marino || p1[sizeof "%include" - 1] == '\t'))
1731e4b17023SJohn Marino {
1732e4b17023SJohn Marino char *new_filename;
1733e4b17023SJohn Marino
1734e4b17023SJohn Marino p1 += sizeof ("%include");
1735e4b17023SJohn Marino while (*p1 == ' ' || *p1 == '\t')
1736e4b17023SJohn Marino p1++;
1737e4b17023SJohn Marino
1738e4b17023SJohn Marino if (*p1++ != '<' || p[-2] != '>')
1739e4b17023SJohn Marino fatal_error ("specs %%include syntax malformed after "
1740e4b17023SJohn Marino "%ld characters",
1741e4b17023SJohn Marino (long) (p1 - buffer + 1));
1742e4b17023SJohn Marino
1743e4b17023SJohn Marino p[-2] = '\0';
1744e4b17023SJohn Marino new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
1745e4b17023SJohn Marino read_specs (new_filename ? new_filename : p1, FALSE);
1746e4b17023SJohn Marino continue;
1747e4b17023SJohn Marino }
1748e4b17023SJohn Marino else if (!strncmp (p1, "%include_noerr", sizeof "%include_noerr" - 1)
1749e4b17023SJohn Marino && (p1[sizeof "%include_noerr" - 1] == ' '
1750e4b17023SJohn Marino || p1[sizeof "%include_noerr" - 1] == '\t'))
1751e4b17023SJohn Marino {
1752e4b17023SJohn Marino char *new_filename;
1753e4b17023SJohn Marino
1754e4b17023SJohn Marino p1 += sizeof "%include_noerr";
1755e4b17023SJohn Marino while (*p1 == ' ' || *p1 == '\t')
1756e4b17023SJohn Marino p1++;
1757e4b17023SJohn Marino
1758e4b17023SJohn Marino if (*p1++ != '<' || p[-2] != '>')
1759e4b17023SJohn Marino fatal_error ("specs %%include syntax malformed after "
1760e4b17023SJohn Marino "%ld characters",
1761e4b17023SJohn Marino (long) (p1 - buffer + 1));
1762e4b17023SJohn Marino
1763e4b17023SJohn Marino p[-2] = '\0';
1764e4b17023SJohn Marino new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
1765e4b17023SJohn Marino if (new_filename)
1766e4b17023SJohn Marino read_specs (new_filename, FALSE);
1767e4b17023SJohn Marino else if (verbose_flag)
1768e4b17023SJohn Marino fnotice (stderr, "could not find specs file %s\n", p1);
1769e4b17023SJohn Marino continue;
1770e4b17023SJohn Marino }
1771e4b17023SJohn Marino else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
1772e4b17023SJohn Marino && (p1[sizeof "%rename" - 1] == ' '
1773e4b17023SJohn Marino || p1[sizeof "%rename" - 1] == '\t'))
1774e4b17023SJohn Marino {
1775e4b17023SJohn Marino int name_len;
1776e4b17023SJohn Marino struct spec_list *sl;
1777e4b17023SJohn Marino struct spec_list *newsl;
1778e4b17023SJohn Marino
1779e4b17023SJohn Marino /* Get original name. */
1780e4b17023SJohn Marino p1 += sizeof "%rename";
1781e4b17023SJohn Marino while (*p1 == ' ' || *p1 == '\t')
1782e4b17023SJohn Marino p1++;
1783e4b17023SJohn Marino
1784e4b17023SJohn Marino if (! ISALPHA ((unsigned char) *p1))
1785e4b17023SJohn Marino fatal_error ("specs %%rename syntax malformed after "
1786e4b17023SJohn Marino "%ld characters",
1787e4b17023SJohn Marino (long) (p1 - buffer));
1788e4b17023SJohn Marino
1789e4b17023SJohn Marino p2 = p1;
1790e4b17023SJohn Marino while (*p2 && !ISSPACE ((unsigned char) *p2))
1791e4b17023SJohn Marino p2++;
1792e4b17023SJohn Marino
1793e4b17023SJohn Marino if (*p2 != ' ' && *p2 != '\t')
1794e4b17023SJohn Marino fatal_error ("specs %%rename syntax malformed after "
1795e4b17023SJohn Marino "%ld characters",
1796e4b17023SJohn Marino (long) (p2 - buffer));
1797e4b17023SJohn Marino
1798e4b17023SJohn Marino name_len = p2 - p1;
1799e4b17023SJohn Marino *p2++ = '\0';
1800e4b17023SJohn Marino while (*p2 == ' ' || *p2 == '\t')
1801e4b17023SJohn Marino p2++;
1802e4b17023SJohn Marino
1803e4b17023SJohn Marino if (! ISALPHA ((unsigned char) *p2))
1804e4b17023SJohn Marino fatal_error ("specs %%rename syntax malformed after "
1805e4b17023SJohn Marino "%ld characters",
1806e4b17023SJohn Marino (long) (p2 - buffer));
1807e4b17023SJohn Marino
1808e4b17023SJohn Marino /* Get new spec name. */
1809e4b17023SJohn Marino p3 = p2;
1810e4b17023SJohn Marino while (*p3 && !ISSPACE ((unsigned char) *p3))
1811e4b17023SJohn Marino p3++;
1812e4b17023SJohn Marino
1813e4b17023SJohn Marino if (p3 != p - 1)
1814e4b17023SJohn Marino fatal_error ("specs %%rename syntax malformed after "
1815e4b17023SJohn Marino "%ld characters",
1816e4b17023SJohn Marino (long) (p3 - buffer));
1817e4b17023SJohn Marino *p3 = '\0';
1818e4b17023SJohn Marino
1819e4b17023SJohn Marino for (sl = specs; sl; sl = sl->next)
1820e4b17023SJohn Marino if (name_len == sl->name_len && !strcmp (sl->name, p1))
1821e4b17023SJohn Marino break;
1822e4b17023SJohn Marino
1823e4b17023SJohn Marino if (!sl)
1824e4b17023SJohn Marino fatal_error ("specs %s spec was not found to be renamed", p1);
1825e4b17023SJohn Marino
1826e4b17023SJohn Marino if (strcmp (p1, p2) == 0)
1827e4b17023SJohn Marino continue;
1828e4b17023SJohn Marino
1829e4b17023SJohn Marino for (newsl = specs; newsl; newsl = newsl->next)
1830e4b17023SJohn Marino if (strcmp (newsl->name, p2) == 0)
1831e4b17023SJohn Marino fatal_error ("%s: attempt to rename spec %qs to "
1832e4b17023SJohn Marino "already defined spec %qs",
1833e4b17023SJohn Marino filename, p1, p2);
1834e4b17023SJohn Marino
1835e4b17023SJohn Marino if (verbose_flag)
1836e4b17023SJohn Marino {
1837e4b17023SJohn Marino fnotice (stderr, "rename spec %s to %s\n", p1, p2);
1838e4b17023SJohn Marino #ifdef DEBUG_SPECS
1839e4b17023SJohn Marino fnotice (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
1840e4b17023SJohn Marino #endif
1841e4b17023SJohn Marino }
1842e4b17023SJohn Marino
1843e4b17023SJohn Marino set_spec (p2, *(sl->ptr_spec));
1844e4b17023SJohn Marino if (sl->alloc_p)
1845e4b17023SJohn Marino free (CONST_CAST (char *, *(sl->ptr_spec)));
1846e4b17023SJohn Marino
1847e4b17023SJohn Marino *(sl->ptr_spec) = "";
1848e4b17023SJohn Marino sl->alloc_p = 0;
1849e4b17023SJohn Marino continue;
1850e4b17023SJohn Marino }
1851e4b17023SJohn Marino else
1852e4b17023SJohn Marino fatal_error ("specs unknown %% command after %ld characters",
1853e4b17023SJohn Marino (long) (p1 - buffer));
1854e4b17023SJohn Marino }
1855e4b17023SJohn Marino
1856e4b17023SJohn Marino /* Find the colon that should end the suffix. */
1857e4b17023SJohn Marino p1 = p;
1858e4b17023SJohn Marino while (*p1 && *p1 != ':' && *p1 != '\n')
1859e4b17023SJohn Marino p1++;
1860e4b17023SJohn Marino
1861e4b17023SJohn Marino /* The colon shouldn't be missing. */
1862e4b17023SJohn Marino if (*p1 != ':')
1863e4b17023SJohn Marino fatal_error ("specs file malformed after %ld characters",
1864e4b17023SJohn Marino (long) (p1 - buffer));
1865e4b17023SJohn Marino
1866e4b17023SJohn Marino /* Skip back over trailing whitespace. */
1867e4b17023SJohn Marino p2 = p1;
1868e4b17023SJohn Marino while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t'))
1869e4b17023SJohn Marino p2--;
1870e4b17023SJohn Marino
1871e4b17023SJohn Marino /* Copy the suffix to a string. */
1872e4b17023SJohn Marino suffix = save_string (p, p2 - p);
1873e4b17023SJohn Marino /* Find the next line. */
1874e4b17023SJohn Marino p = skip_whitespace (p1 + 1);
1875e4b17023SJohn Marino if (p[1] == 0)
1876e4b17023SJohn Marino fatal_error ("specs file malformed after %ld characters",
1877e4b17023SJohn Marino (long) (p - buffer));
1878e4b17023SJohn Marino
1879e4b17023SJohn Marino p1 = p;
1880e4b17023SJohn Marino /* Find next blank line or end of string. */
1881e4b17023SJohn Marino while (*p1 && !(*p1 == '\n' && (p1[1] == '\n' || p1[1] == '\0')))
1882e4b17023SJohn Marino p1++;
1883e4b17023SJohn Marino
1884e4b17023SJohn Marino /* Specs end at the blank line and do not include the newline. */
1885e4b17023SJohn Marino spec = save_string (p, p1 - p);
1886e4b17023SJohn Marino p = p1;
1887e4b17023SJohn Marino
1888e4b17023SJohn Marino /* Delete backslash-newline sequences from the spec. */
1889e4b17023SJohn Marino in = spec;
1890e4b17023SJohn Marino out = spec;
1891e4b17023SJohn Marino while (*in != 0)
1892e4b17023SJohn Marino {
1893e4b17023SJohn Marino if (in[0] == '\\' && in[1] == '\n')
1894e4b17023SJohn Marino in += 2;
1895e4b17023SJohn Marino else if (in[0] == '#')
1896e4b17023SJohn Marino while (*in && *in != '\n')
1897e4b17023SJohn Marino in++;
1898e4b17023SJohn Marino
1899e4b17023SJohn Marino else
1900e4b17023SJohn Marino *out++ = *in++;
1901e4b17023SJohn Marino }
1902e4b17023SJohn Marino *out = 0;
1903e4b17023SJohn Marino
1904e4b17023SJohn Marino if (suffix[0] == '*')
1905e4b17023SJohn Marino {
1906e4b17023SJohn Marino if (! strcmp (suffix, "*link_command"))
1907e4b17023SJohn Marino link_command_spec = spec;
1908e4b17023SJohn Marino else
1909e4b17023SJohn Marino set_spec (suffix + 1, spec);
1910e4b17023SJohn Marino }
1911e4b17023SJohn Marino else
1912e4b17023SJohn Marino {
1913e4b17023SJohn Marino /* Add this pair to the vector. */
1914e4b17023SJohn Marino compilers
1915e4b17023SJohn Marino = XRESIZEVEC (struct compiler, compilers, n_compilers + 2);
1916e4b17023SJohn Marino
1917e4b17023SJohn Marino compilers[n_compilers].suffix = suffix;
1918e4b17023SJohn Marino compilers[n_compilers].spec = spec;
1919e4b17023SJohn Marino n_compilers++;
1920e4b17023SJohn Marino memset (&compilers[n_compilers], 0, sizeof compilers[n_compilers]);
1921e4b17023SJohn Marino }
1922e4b17023SJohn Marino
1923e4b17023SJohn Marino if (*suffix == 0)
1924e4b17023SJohn Marino link_command_spec = spec;
1925e4b17023SJohn Marino }
1926e4b17023SJohn Marino
1927e4b17023SJohn Marino if (link_command_spec == 0)
1928e4b17023SJohn Marino fatal_error ("spec file has no spec for linking");
1929e4b17023SJohn Marino }
1930e4b17023SJohn Marino
1931e4b17023SJohn Marino /* Record the names of temporary files we tell compilers to write,
1932e4b17023SJohn Marino and delete them at the end of the run. */
1933e4b17023SJohn Marino
1934e4b17023SJohn Marino /* This is the common prefix we use to make temp file names.
1935e4b17023SJohn Marino It is chosen once for each run of this program.
1936e4b17023SJohn Marino It is substituted into a spec by %g or %j.
1937e4b17023SJohn Marino Thus, all temp file names contain this prefix.
1938e4b17023SJohn Marino In practice, all temp file names start with this prefix.
1939e4b17023SJohn Marino
1940e4b17023SJohn Marino This prefix comes from the envvar TMPDIR if it is defined;
1941e4b17023SJohn Marino otherwise, from the P_tmpdir macro if that is defined;
1942e4b17023SJohn Marino otherwise, in /usr/tmp or /tmp;
1943e4b17023SJohn Marino or finally the current directory if all else fails. */
1944e4b17023SJohn Marino
1945e4b17023SJohn Marino static const char *temp_filename;
1946e4b17023SJohn Marino
1947e4b17023SJohn Marino /* Length of the prefix. */
1948e4b17023SJohn Marino
1949e4b17023SJohn Marino static int temp_filename_length;
1950e4b17023SJohn Marino
1951e4b17023SJohn Marino /* Define the list of temporary files to delete. */
1952e4b17023SJohn Marino
1953e4b17023SJohn Marino struct temp_file
1954e4b17023SJohn Marino {
1955e4b17023SJohn Marino const char *name;
1956e4b17023SJohn Marino struct temp_file *next;
1957e4b17023SJohn Marino };
1958e4b17023SJohn Marino
1959e4b17023SJohn Marino /* Queue of files to delete on success or failure of compilation. */
1960e4b17023SJohn Marino static struct temp_file *always_delete_queue;
1961e4b17023SJohn Marino /* Queue of files to delete on failure of compilation. */
1962e4b17023SJohn Marino static struct temp_file *failure_delete_queue;
1963e4b17023SJohn Marino
1964e4b17023SJohn Marino /* Record FILENAME as a file to be deleted automatically.
1965e4b17023SJohn Marino ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
1966e4b17023SJohn Marino otherwise delete it in any case.
1967e4b17023SJohn Marino FAIL_DELETE nonzero means delete it if a compilation step fails;
1968e4b17023SJohn Marino otherwise delete it in any case. */
1969e4b17023SJohn Marino
1970e4b17023SJohn Marino void
record_temp_file(const char * filename,int always_delete,int fail_delete)1971e4b17023SJohn Marino record_temp_file (const char *filename, int always_delete, int fail_delete)
1972e4b17023SJohn Marino {
1973e4b17023SJohn Marino char *const name = xstrdup (filename);
1974e4b17023SJohn Marino
1975e4b17023SJohn Marino if (always_delete)
1976e4b17023SJohn Marino {
1977e4b17023SJohn Marino struct temp_file *temp;
1978e4b17023SJohn Marino for (temp = always_delete_queue; temp; temp = temp->next)
1979e4b17023SJohn Marino if (! filename_cmp (name, temp->name))
1980e4b17023SJohn Marino goto already1;
1981e4b17023SJohn Marino
1982e4b17023SJohn Marino temp = XNEW (struct temp_file);
1983e4b17023SJohn Marino temp->next = always_delete_queue;
1984e4b17023SJohn Marino temp->name = name;
1985e4b17023SJohn Marino always_delete_queue = temp;
1986e4b17023SJohn Marino
1987e4b17023SJohn Marino already1:;
1988e4b17023SJohn Marino }
1989e4b17023SJohn Marino
1990e4b17023SJohn Marino if (fail_delete)
1991e4b17023SJohn Marino {
1992e4b17023SJohn Marino struct temp_file *temp;
1993e4b17023SJohn Marino for (temp = failure_delete_queue; temp; temp = temp->next)
1994e4b17023SJohn Marino if (! filename_cmp (name, temp->name))
1995e4b17023SJohn Marino goto already2;
1996e4b17023SJohn Marino
1997e4b17023SJohn Marino temp = XNEW (struct temp_file);
1998e4b17023SJohn Marino temp->next = failure_delete_queue;
1999e4b17023SJohn Marino temp->name = name;
2000e4b17023SJohn Marino failure_delete_queue = temp;
2001e4b17023SJohn Marino
2002e4b17023SJohn Marino already2:;
2003e4b17023SJohn Marino }
2004e4b17023SJohn Marino }
2005e4b17023SJohn Marino
2006e4b17023SJohn Marino /* Delete all the temporary files whose names we previously recorded. */
2007e4b17023SJohn Marino
2008e4b17023SJohn Marino #ifndef DELETE_IF_ORDINARY
2009e4b17023SJohn Marino #define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG) \
2010e4b17023SJohn Marino do \
2011e4b17023SJohn Marino { \
2012e4b17023SJohn Marino if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode)) \
2013e4b17023SJohn Marino if (unlink (NAME) < 0) \
2014e4b17023SJohn Marino if (VERBOSE_FLAG) \
2015e4b17023SJohn Marino perror_with_name (NAME); \
2016e4b17023SJohn Marino } while (0)
2017e4b17023SJohn Marino #endif
2018e4b17023SJohn Marino
2019e4b17023SJohn Marino static void
delete_if_ordinary(const char * name)2020e4b17023SJohn Marino delete_if_ordinary (const char *name)
2021e4b17023SJohn Marino {
2022e4b17023SJohn Marino struct stat st;
2023e4b17023SJohn Marino #ifdef DEBUG
2024e4b17023SJohn Marino int i, c;
2025e4b17023SJohn Marino
2026e4b17023SJohn Marino printf ("Delete %s? (y or n) ", name);
2027e4b17023SJohn Marino fflush (stdout);
2028e4b17023SJohn Marino i = getchar ();
2029e4b17023SJohn Marino if (i != '\n')
2030e4b17023SJohn Marino while ((c = getchar ()) != '\n' && c != EOF)
2031e4b17023SJohn Marino ;
2032e4b17023SJohn Marino
2033e4b17023SJohn Marino if (i == 'y' || i == 'Y')
2034e4b17023SJohn Marino #endif /* DEBUG */
2035e4b17023SJohn Marino DELETE_IF_ORDINARY (name, st, verbose_flag);
2036e4b17023SJohn Marino }
2037e4b17023SJohn Marino
2038e4b17023SJohn Marino static void
delete_temp_files(void)2039e4b17023SJohn Marino delete_temp_files (void)
2040e4b17023SJohn Marino {
2041e4b17023SJohn Marino struct temp_file *temp;
2042e4b17023SJohn Marino
2043e4b17023SJohn Marino for (temp = always_delete_queue; temp; temp = temp->next)
2044e4b17023SJohn Marino delete_if_ordinary (temp->name);
2045e4b17023SJohn Marino always_delete_queue = 0;
2046e4b17023SJohn Marino }
2047e4b17023SJohn Marino
2048e4b17023SJohn Marino /* Delete all the files to be deleted on error. */
2049e4b17023SJohn Marino
2050e4b17023SJohn Marino static void
delete_failure_queue(void)2051e4b17023SJohn Marino delete_failure_queue (void)
2052e4b17023SJohn Marino {
2053e4b17023SJohn Marino struct temp_file *temp;
2054e4b17023SJohn Marino
2055e4b17023SJohn Marino for (temp = failure_delete_queue; temp; temp = temp->next)
2056e4b17023SJohn Marino delete_if_ordinary (temp->name);
2057e4b17023SJohn Marino }
2058e4b17023SJohn Marino
2059e4b17023SJohn Marino static void
clear_failure_queue(void)2060e4b17023SJohn Marino clear_failure_queue (void)
2061e4b17023SJohn Marino {
2062e4b17023SJohn Marino failure_delete_queue = 0;
2063e4b17023SJohn Marino }
2064e4b17023SJohn Marino
2065e4b17023SJohn Marino /* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
2066e4b17023SJohn Marino returns non-NULL.
2067e4b17023SJohn Marino If DO_MULTI is true iterate over the paths twice, first with multilib
2068e4b17023SJohn Marino suffix then without, otherwise iterate over the paths once without
2069e4b17023SJohn Marino adding a multilib suffix. When DO_MULTI is true, some attempt is made
2070e4b17023SJohn Marino to avoid visiting the same path twice, but we could do better. For
2071e4b17023SJohn Marino instance, /usr/lib/../lib is considered different from /usr/lib.
2072e4b17023SJohn Marino At least EXTRA_SPACE chars past the end of the path passed to
2073e4b17023SJohn Marino CALLBACK are available for use by the callback.
2074e4b17023SJohn Marino CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
2075e4b17023SJohn Marino
2076e4b17023SJohn Marino Returns the value returned by CALLBACK. */
2077e4b17023SJohn Marino
2078e4b17023SJohn Marino static void *
for_each_path(const struct path_prefix * paths,bool do_multi,size_t extra_space,void * (* callback)(char *,void *),void * callback_info)2079e4b17023SJohn Marino for_each_path (const struct path_prefix *paths,
2080e4b17023SJohn Marino bool do_multi,
2081e4b17023SJohn Marino size_t extra_space,
2082e4b17023SJohn Marino void *(*callback) (char *, void *),
2083e4b17023SJohn Marino void *callback_info)
2084e4b17023SJohn Marino {
2085e4b17023SJohn Marino struct prefix_list *pl;
2086e4b17023SJohn Marino const char *multi_dir = NULL;
2087e4b17023SJohn Marino const char *multi_os_dir = NULL;
20885ce9237cSJohn Marino const char *multiarch_suffix = NULL;
2089e4b17023SJohn Marino const char *multi_suffix;
2090e4b17023SJohn Marino const char *just_multi_suffix;
2091e4b17023SJohn Marino char *path = NULL;
2092e4b17023SJohn Marino void *ret = NULL;
2093e4b17023SJohn Marino bool skip_multi_dir = false;
2094e4b17023SJohn Marino bool skip_multi_os_dir = false;
2095e4b17023SJohn Marino
2096e4b17023SJohn Marino multi_suffix = machine_suffix;
2097e4b17023SJohn Marino just_multi_suffix = just_machine_suffix;
2098e4b17023SJohn Marino if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
2099e4b17023SJohn Marino {
2100e4b17023SJohn Marino multi_dir = concat (multilib_dir, dir_separator_str, NULL);
2101e4b17023SJohn Marino multi_suffix = concat (multi_suffix, multi_dir, NULL);
2102e4b17023SJohn Marino just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
2103e4b17023SJohn Marino }
2104e4b17023SJohn Marino if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
2105e4b17023SJohn Marino multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
21065ce9237cSJohn Marino if (multiarch_dir)
21075ce9237cSJohn Marino multiarch_suffix = concat (multiarch_dir, dir_separator_str, NULL);
2108e4b17023SJohn Marino
2109e4b17023SJohn Marino while (1)
2110e4b17023SJohn Marino {
2111e4b17023SJohn Marino size_t multi_dir_len = 0;
2112e4b17023SJohn Marino size_t multi_os_dir_len = 0;
21135ce9237cSJohn Marino size_t multiarch_len = 0;
2114e4b17023SJohn Marino size_t suffix_len;
2115e4b17023SJohn Marino size_t just_suffix_len;
2116e4b17023SJohn Marino size_t len;
2117e4b17023SJohn Marino
2118e4b17023SJohn Marino if (multi_dir)
2119e4b17023SJohn Marino multi_dir_len = strlen (multi_dir);
2120e4b17023SJohn Marino if (multi_os_dir)
2121e4b17023SJohn Marino multi_os_dir_len = strlen (multi_os_dir);
21225ce9237cSJohn Marino if (multiarch_suffix)
21235ce9237cSJohn Marino multiarch_len = strlen (multiarch_suffix);
2124e4b17023SJohn Marino suffix_len = strlen (multi_suffix);
2125e4b17023SJohn Marino just_suffix_len = strlen (just_multi_suffix);
2126e4b17023SJohn Marino
2127e4b17023SJohn Marino if (path == NULL)
2128e4b17023SJohn Marino {
2129e4b17023SJohn Marino len = paths->max_len + extra_space + 1;
21305ce9237cSJohn Marino len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len);
2131e4b17023SJohn Marino path = XNEWVEC (char, len);
2132e4b17023SJohn Marino }
2133e4b17023SJohn Marino
2134e4b17023SJohn Marino for (pl = paths->plist; pl != 0; pl = pl->next)
2135e4b17023SJohn Marino {
2136e4b17023SJohn Marino len = strlen (pl->prefix);
2137e4b17023SJohn Marino memcpy (path, pl->prefix, len);
2138e4b17023SJohn Marino
2139fdc4107cSJohn Marino #if 0 /* MACHINE/VERSION isn't used anywhere DragonFly */
2140e4b17023SJohn Marino /* Look first in MACHINE/VERSION subdirectory. */
2141e4b17023SJohn Marino if (!skip_multi_dir)
2142e4b17023SJohn Marino {
2143e4b17023SJohn Marino memcpy (path + len, multi_suffix, suffix_len + 1);
2144e4b17023SJohn Marino ret = callback (path, callback_info);
2145e4b17023SJohn Marino if (ret)
2146e4b17023SJohn Marino break;
2147e4b17023SJohn Marino }
2148fdc4107cSJohn Marino #endif
2149e4b17023SJohn Marino
2150e4b17023SJohn Marino /* Some paths are tried with just the machine (ie. target)
2151e4b17023SJohn Marino subdir. This is used for finding as, ld, etc. */
2152e4b17023SJohn Marino if (!skip_multi_dir
2153e4b17023SJohn Marino && pl->require_machine_suffix == 2)
2154e4b17023SJohn Marino {
2155e4b17023SJohn Marino memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
2156e4b17023SJohn Marino ret = callback (path, callback_info);
2157e4b17023SJohn Marino if (ret)
2158e4b17023SJohn Marino break;
2159e4b17023SJohn Marino }
2160e4b17023SJohn Marino
21615ce9237cSJohn Marino /* Now try the multiarch path. */
21625ce9237cSJohn Marino if (!skip_multi_dir
21635ce9237cSJohn Marino && !pl->require_machine_suffix && multiarch_dir)
21645ce9237cSJohn Marino {
21655ce9237cSJohn Marino memcpy (path + len, multiarch_suffix, multiarch_len + 1);
21665ce9237cSJohn Marino ret = callback (path, callback_info);
21675ce9237cSJohn Marino if (ret)
21685ce9237cSJohn Marino break;
21695ce9237cSJohn Marino }
21705ce9237cSJohn Marino
2171e4b17023SJohn Marino /* Now try the base path. */
2172e4b17023SJohn Marino if (!pl->require_machine_suffix
2173e4b17023SJohn Marino && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
2174e4b17023SJohn Marino {
2175e4b17023SJohn Marino const char *this_multi;
2176e4b17023SJohn Marino size_t this_multi_len;
2177e4b17023SJohn Marino
2178e4b17023SJohn Marino if (pl->os_multilib)
2179e4b17023SJohn Marino {
2180e4b17023SJohn Marino this_multi = multi_os_dir;
2181e4b17023SJohn Marino this_multi_len = multi_os_dir_len;
2182e4b17023SJohn Marino }
2183e4b17023SJohn Marino else
2184e4b17023SJohn Marino {
2185e4b17023SJohn Marino this_multi = multi_dir;
2186e4b17023SJohn Marino this_multi_len = multi_dir_len;
2187e4b17023SJohn Marino }
2188e4b17023SJohn Marino
2189e4b17023SJohn Marino if (this_multi_len)
2190e4b17023SJohn Marino memcpy (path + len, this_multi, this_multi_len + 1);
2191e4b17023SJohn Marino else
2192e4b17023SJohn Marino path[len] = '\0';
2193e4b17023SJohn Marino
2194e4b17023SJohn Marino ret = callback (path, callback_info);
2195e4b17023SJohn Marino if (ret)
2196e4b17023SJohn Marino break;
2197e4b17023SJohn Marino }
2198e4b17023SJohn Marino }
2199e4b17023SJohn Marino if (pl)
2200e4b17023SJohn Marino break;
2201e4b17023SJohn Marino
2202e4b17023SJohn Marino if (multi_dir == NULL && multi_os_dir == NULL)
2203e4b17023SJohn Marino break;
2204e4b17023SJohn Marino
2205e4b17023SJohn Marino /* Run through the paths again, this time without multilibs.
2206e4b17023SJohn Marino Don't repeat any we have already seen. */
2207e4b17023SJohn Marino if (multi_dir)
2208e4b17023SJohn Marino {
2209e4b17023SJohn Marino free (CONST_CAST (char *, multi_dir));
2210e4b17023SJohn Marino multi_dir = NULL;
2211e4b17023SJohn Marino free (CONST_CAST (char *, multi_suffix));
2212e4b17023SJohn Marino multi_suffix = machine_suffix;
2213e4b17023SJohn Marino free (CONST_CAST (char *, just_multi_suffix));
2214e4b17023SJohn Marino just_multi_suffix = just_machine_suffix;
2215e4b17023SJohn Marino }
2216e4b17023SJohn Marino else
2217e4b17023SJohn Marino skip_multi_dir = true;
2218e4b17023SJohn Marino if (multi_os_dir)
2219e4b17023SJohn Marino {
2220e4b17023SJohn Marino free (CONST_CAST (char *, multi_os_dir));
2221e4b17023SJohn Marino multi_os_dir = NULL;
2222e4b17023SJohn Marino }
2223e4b17023SJohn Marino else
2224e4b17023SJohn Marino skip_multi_os_dir = true;
2225e4b17023SJohn Marino }
2226e4b17023SJohn Marino
2227e4b17023SJohn Marino if (multi_dir)
2228e4b17023SJohn Marino {
2229e4b17023SJohn Marino free (CONST_CAST (char *, multi_dir));
2230e4b17023SJohn Marino free (CONST_CAST (char *, multi_suffix));
2231e4b17023SJohn Marino free (CONST_CAST (char *, just_multi_suffix));
2232e4b17023SJohn Marino }
2233e4b17023SJohn Marino if (multi_os_dir)
2234e4b17023SJohn Marino free (CONST_CAST (char *, multi_os_dir));
2235e4b17023SJohn Marino if (ret != path)
2236e4b17023SJohn Marino free (path);
2237e4b17023SJohn Marino return ret;
2238e4b17023SJohn Marino }
2239e4b17023SJohn Marino
2240e4b17023SJohn Marino /* Callback for build_search_list. Adds path to obstack being built. */
2241e4b17023SJohn Marino
2242e4b17023SJohn Marino struct add_to_obstack_info {
2243e4b17023SJohn Marino struct obstack *ob;
2244e4b17023SJohn Marino bool check_dir;
2245e4b17023SJohn Marino bool first_time;
2246e4b17023SJohn Marino };
2247e4b17023SJohn Marino
2248e4b17023SJohn Marino static void *
add_to_obstack(char * path,void * data)2249e4b17023SJohn Marino add_to_obstack (char *path, void *data)
2250e4b17023SJohn Marino {
2251e4b17023SJohn Marino struct add_to_obstack_info *info = (struct add_to_obstack_info *) data;
2252e4b17023SJohn Marino
2253e4b17023SJohn Marino if (info->check_dir && !is_directory (path, false))
2254e4b17023SJohn Marino return NULL;
2255e4b17023SJohn Marino
2256e4b17023SJohn Marino if (!info->first_time)
2257e4b17023SJohn Marino obstack_1grow (info->ob, PATH_SEPARATOR);
2258e4b17023SJohn Marino
2259e4b17023SJohn Marino obstack_grow (info->ob, path, strlen (path));
2260e4b17023SJohn Marino
2261e4b17023SJohn Marino info->first_time = false;
2262e4b17023SJohn Marino return NULL;
2263e4b17023SJohn Marino }
2264e4b17023SJohn Marino
2265e4b17023SJohn Marino /* Add or change the value of an environment variable, outputting the
2266e4b17023SJohn Marino change to standard error if in verbose mode. */
2267e4b17023SJohn Marino static void
xputenv(const char * string)2268e4b17023SJohn Marino xputenv (const char *string)
2269e4b17023SJohn Marino {
2270e4b17023SJohn Marino if (verbose_flag)
2271e4b17023SJohn Marino fnotice (stderr, "%s\n", string);
2272e4b17023SJohn Marino putenv (CONST_CAST (char *, string));
2273e4b17023SJohn Marino }
2274e4b17023SJohn Marino
2275e4b17023SJohn Marino /* Build a list of search directories from PATHS.
2276e4b17023SJohn Marino PREFIX is a string to prepend to the list.
2277e4b17023SJohn Marino If CHECK_DIR_P is true we ensure the directory exists.
2278e4b17023SJohn Marino If DO_MULTI is true, multilib paths are output first, then
2279e4b17023SJohn Marino non-multilib paths.
2280e4b17023SJohn Marino This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
2281e4b17023SJohn Marino It is also used by the --print-search-dirs flag. */
2282e4b17023SJohn Marino
2283e4b17023SJohn Marino static char *
build_search_list(const struct path_prefix * paths,const char * prefix,bool check_dir,bool do_multi)2284e4b17023SJohn Marino build_search_list (const struct path_prefix *paths, const char *prefix,
2285e4b17023SJohn Marino bool check_dir, bool do_multi)
2286e4b17023SJohn Marino {
2287e4b17023SJohn Marino struct add_to_obstack_info info;
2288e4b17023SJohn Marino
2289e4b17023SJohn Marino info.ob = &collect_obstack;
2290e4b17023SJohn Marino info.check_dir = check_dir;
2291e4b17023SJohn Marino info.first_time = true;
2292e4b17023SJohn Marino
2293e4b17023SJohn Marino obstack_grow (&collect_obstack, prefix, strlen (prefix));
2294e4b17023SJohn Marino obstack_1grow (&collect_obstack, '=');
2295e4b17023SJohn Marino
2296e4b17023SJohn Marino for_each_path (paths, do_multi, 0, add_to_obstack, &info);
2297e4b17023SJohn Marino
2298e4b17023SJohn Marino obstack_1grow (&collect_obstack, '\0');
2299e4b17023SJohn Marino return XOBFINISH (&collect_obstack, char *);
2300e4b17023SJohn Marino }
2301e4b17023SJohn Marino
2302e4b17023SJohn Marino /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
2303e4b17023SJohn Marino for collect. */
2304e4b17023SJohn Marino
2305e4b17023SJohn Marino static void
putenv_from_prefixes(const struct path_prefix * paths,const char * env_var,bool do_multi)2306e4b17023SJohn Marino putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
2307e4b17023SJohn Marino bool do_multi)
2308e4b17023SJohn Marino {
2309e4b17023SJohn Marino xputenv (build_search_list (paths, env_var, true, do_multi));
2310e4b17023SJohn Marino }
2311e4b17023SJohn Marino
2312e4b17023SJohn Marino /* Check whether NAME can be accessed in MODE. This is like access,
2313e4b17023SJohn Marino except that it never considers directories to be executable. */
2314e4b17023SJohn Marino
2315e4b17023SJohn Marino static int
access_check(const char * name,int mode)2316e4b17023SJohn Marino access_check (const char *name, int mode)
2317e4b17023SJohn Marino {
2318e4b17023SJohn Marino if (mode == X_OK)
2319e4b17023SJohn Marino {
2320e4b17023SJohn Marino struct stat st;
2321e4b17023SJohn Marino
2322e4b17023SJohn Marino if (stat (name, &st) < 0
2323e4b17023SJohn Marino || S_ISDIR (st.st_mode))
2324e4b17023SJohn Marino return -1;
2325e4b17023SJohn Marino }
2326e4b17023SJohn Marino
2327e4b17023SJohn Marino return access (name, mode);
2328e4b17023SJohn Marino }
2329e4b17023SJohn Marino
2330e4b17023SJohn Marino /* Callback for find_a_file. Appends the file name to the directory
2331e4b17023SJohn Marino path. If the resulting file exists in the right mode, return the
2332e4b17023SJohn Marino full pathname to the file. */
2333e4b17023SJohn Marino
2334e4b17023SJohn Marino struct file_at_path_info {
2335e4b17023SJohn Marino const char *name;
2336e4b17023SJohn Marino const char *suffix;
2337e4b17023SJohn Marino int name_len;
2338e4b17023SJohn Marino int suffix_len;
2339e4b17023SJohn Marino int mode;
2340e4b17023SJohn Marino };
2341e4b17023SJohn Marino
2342e4b17023SJohn Marino static void *
file_at_path(char * path,void * data)2343e4b17023SJohn Marino file_at_path (char *path, void *data)
2344e4b17023SJohn Marino {
2345e4b17023SJohn Marino struct file_at_path_info *info = (struct file_at_path_info *) data;
2346e4b17023SJohn Marino size_t len = strlen (path);
2347e4b17023SJohn Marino
2348e4b17023SJohn Marino memcpy (path + len, info->name, info->name_len);
2349e4b17023SJohn Marino len += info->name_len;
2350e4b17023SJohn Marino
2351e4b17023SJohn Marino /* Some systems have a suffix for executable files.
2352e4b17023SJohn Marino So try appending that first. */
2353e4b17023SJohn Marino if (info->suffix_len)
2354e4b17023SJohn Marino {
2355e4b17023SJohn Marino memcpy (path + len, info->suffix, info->suffix_len + 1);
2356e4b17023SJohn Marino if (access_check (path, info->mode) == 0)
2357e4b17023SJohn Marino return path;
2358e4b17023SJohn Marino }
2359e4b17023SJohn Marino
2360e4b17023SJohn Marino path[len] = '\0';
2361e4b17023SJohn Marino if (access_check (path, info->mode) == 0)
2362e4b17023SJohn Marino return path;
2363e4b17023SJohn Marino
2364e4b17023SJohn Marino return NULL;
2365e4b17023SJohn Marino }
2366e4b17023SJohn Marino
2367e4b17023SJohn Marino /* Search for NAME using the prefix list PREFIXES. MODE is passed to
2368e4b17023SJohn Marino access to check permissions. If DO_MULTI is true, search multilib
2369e4b17023SJohn Marino paths then non-multilib paths, otherwise do not search multilib paths.
2370e4b17023SJohn Marino Return 0 if not found, otherwise return its name, allocated with malloc. */
2371e4b17023SJohn Marino
2372e4b17023SJohn Marino static char *
find_a_file(const struct path_prefix * pprefix,const char * name,int mode,bool do_multi)2373e4b17023SJohn Marino find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
2374e4b17023SJohn Marino bool do_multi)
2375e4b17023SJohn Marino {
2376e4b17023SJohn Marino struct file_at_path_info info;
2377e4b17023SJohn Marino
2378e4b17023SJohn Marino #ifdef DEFAULT_ASSEMBLER
2379e4b17023SJohn Marino if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, mode) == 0)
2380e4b17023SJohn Marino return xstrdup (DEFAULT_ASSEMBLER);
2381e4b17023SJohn Marino #endif
2382e4b17023SJohn Marino
2383e4b17023SJohn Marino #ifdef DEFAULT_LINKER
2384e4b17023SJohn Marino if (! strcmp(name, "ld") && access (DEFAULT_LINKER, mode) == 0)
2385e4b17023SJohn Marino return xstrdup (DEFAULT_LINKER);
2386e4b17023SJohn Marino #endif
2387e4b17023SJohn Marino
2388e4b17023SJohn Marino /* Determine the filename to execute (special case for absolute paths). */
2389e4b17023SJohn Marino
2390e4b17023SJohn Marino if (IS_ABSOLUTE_PATH (name))
2391e4b17023SJohn Marino {
2392e4b17023SJohn Marino if (access (name, mode) == 0)
2393e4b17023SJohn Marino return xstrdup (name);
2394e4b17023SJohn Marino
2395e4b17023SJohn Marino return NULL;
2396e4b17023SJohn Marino }
2397e4b17023SJohn Marino
2398e4b17023SJohn Marino info.name = name;
2399e4b17023SJohn Marino info.suffix = (mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "";
2400e4b17023SJohn Marino info.name_len = strlen (info.name);
2401e4b17023SJohn Marino info.suffix_len = strlen (info.suffix);
2402e4b17023SJohn Marino info.mode = mode;
2403e4b17023SJohn Marino
2404e4b17023SJohn Marino return (char*) for_each_path (pprefix, do_multi,
2405e4b17023SJohn Marino info.name_len + info.suffix_len,
2406e4b17023SJohn Marino file_at_path, &info);
2407e4b17023SJohn Marino }
2408e4b17023SJohn Marino
2409e4b17023SJohn Marino /* Ranking of prefixes in the sort list. -B prefixes are put before
2410e4b17023SJohn Marino all others. */
2411e4b17023SJohn Marino
2412e4b17023SJohn Marino enum path_prefix_priority
2413e4b17023SJohn Marino {
2414e4b17023SJohn Marino PREFIX_PRIORITY_B_OPT,
2415e4b17023SJohn Marino PREFIX_PRIORITY_LAST
2416e4b17023SJohn Marino };
2417e4b17023SJohn Marino
2418e4b17023SJohn Marino /* Add an entry for PREFIX in PLIST. The PLIST is kept in ascending
2419e4b17023SJohn Marino order according to PRIORITY. Within each PRIORITY, new entries are
2420e4b17023SJohn Marino appended.
2421e4b17023SJohn Marino
2422e4b17023SJohn Marino If WARN is nonzero, we will warn if no file is found
2423e4b17023SJohn Marino through this prefix. WARN should point to an int
2424e4b17023SJohn Marino which will be set to 1 if this entry is used.
2425e4b17023SJohn Marino
2426e4b17023SJohn Marino COMPONENT is the value to be passed to update_path.
2427e4b17023SJohn Marino
2428e4b17023SJohn Marino REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
2429e4b17023SJohn Marino the complete value of machine_suffix.
2430e4b17023SJohn Marino 2 means try both machine_suffix and just_machine_suffix. */
2431e4b17023SJohn Marino
2432e4b17023SJohn Marino static void
add_prefix(struct path_prefix * pprefix,const char * prefix,const char * component,int priority,int require_machine_suffix,int os_multilib)2433e4b17023SJohn Marino add_prefix (struct path_prefix *pprefix, const char *prefix,
2434e4b17023SJohn Marino const char *component, /* enum prefix_priority */ int priority,
2435e4b17023SJohn Marino int require_machine_suffix, int os_multilib)
2436e4b17023SJohn Marino {
2437e4b17023SJohn Marino struct prefix_list *pl, **prev;
2438e4b17023SJohn Marino int len;
2439e4b17023SJohn Marino
2440e4b17023SJohn Marino for (prev = &pprefix->plist;
2441e4b17023SJohn Marino (*prev) != NULL && (*prev)->priority <= priority;
2442e4b17023SJohn Marino prev = &(*prev)->next)
2443e4b17023SJohn Marino ;
2444e4b17023SJohn Marino
2445e4b17023SJohn Marino /* Keep track of the longest prefix. */
2446e4b17023SJohn Marino
2447e4b17023SJohn Marino prefix = update_path (prefix, component);
2448e4b17023SJohn Marino len = strlen (prefix);
2449e4b17023SJohn Marino if (len > pprefix->max_len)
2450e4b17023SJohn Marino pprefix->max_len = len;
2451e4b17023SJohn Marino
2452e4b17023SJohn Marino pl = XNEW (struct prefix_list);
2453e4b17023SJohn Marino pl->prefix = prefix;
2454e4b17023SJohn Marino pl->require_machine_suffix = require_machine_suffix;
2455e4b17023SJohn Marino pl->priority = priority;
2456e4b17023SJohn Marino pl->os_multilib = os_multilib;
2457e4b17023SJohn Marino
2458e4b17023SJohn Marino /* Insert after PREV. */
2459e4b17023SJohn Marino pl->next = (*prev);
2460e4b17023SJohn Marino (*prev) = pl;
2461e4b17023SJohn Marino }
2462e4b17023SJohn Marino
2463e4b17023SJohn Marino /* Same as add_prefix, but prepending target_system_root to prefix. */
2464e4b17023SJohn Marino /* The target_system_root prefix has been relocated by gcc_exec_prefix. */
2465e4b17023SJohn Marino static void
add_sysrooted_prefix(struct path_prefix * pprefix,const char * prefix,const char * component,int priority,int require_machine_suffix,int os_multilib)2466e4b17023SJohn Marino add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
2467e4b17023SJohn Marino const char *component,
2468e4b17023SJohn Marino /* enum prefix_priority */ int priority,
2469e4b17023SJohn Marino int require_machine_suffix, int os_multilib)
2470e4b17023SJohn Marino {
2471e4b17023SJohn Marino if (!IS_ABSOLUTE_PATH (prefix))
2472e4b17023SJohn Marino fatal_error ("system path %qs is not absolute", prefix);
2473e4b17023SJohn Marino
2474e4b17023SJohn Marino if (target_system_root)
2475e4b17023SJohn Marino {
2476e4b17023SJohn Marino char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
2477e4b17023SJohn Marino size_t sysroot_len = strlen (target_system_root);
2478e4b17023SJohn Marino
2479e4b17023SJohn Marino if (sysroot_len > 0
2480e4b17023SJohn Marino && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
2481e4b17023SJohn Marino sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
2482e4b17023SJohn Marino
2483e4b17023SJohn Marino if (target_sysroot_suffix)
2484e4b17023SJohn Marino prefix = concat (target_sysroot_suffix, prefix, NULL);
2485e4b17023SJohn Marino prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
2486e4b17023SJohn Marino free (sysroot_no_trailing_dir_separator);
2487e4b17023SJohn Marino
2488e4b17023SJohn Marino /* We have to override this because GCC's notion of sysroot
2489e4b17023SJohn Marino moves along with GCC. */
2490e4b17023SJohn Marino component = "GCC";
2491e4b17023SJohn Marino }
2492e4b17023SJohn Marino
2493e4b17023SJohn Marino add_prefix (pprefix, prefix, component, priority,
2494e4b17023SJohn Marino require_machine_suffix, os_multilib);
2495e4b17023SJohn Marino }
2496e4b17023SJohn Marino
2497e4b17023SJohn Marino /* Execute the command specified by the arguments on the current line of spec.
2498e4b17023SJohn Marino When using pipes, this includes several piped-together commands
2499e4b17023SJohn Marino with `|' between them.
2500e4b17023SJohn Marino
2501e4b17023SJohn Marino Return 0 if successful, -1 if failed. */
2502e4b17023SJohn Marino
2503e4b17023SJohn Marino static int
execute(void)2504e4b17023SJohn Marino execute (void)
2505e4b17023SJohn Marino {
2506e4b17023SJohn Marino int i;
2507e4b17023SJohn Marino int n_commands; /* # of command. */
2508e4b17023SJohn Marino char *string;
2509e4b17023SJohn Marino struct pex_obj *pex;
2510e4b17023SJohn Marino struct command
2511e4b17023SJohn Marino {
2512e4b17023SJohn Marino const char *prog; /* program name. */
2513e4b17023SJohn Marino const char **argv; /* vector of args. */
2514e4b17023SJohn Marino };
2515e4b17023SJohn Marino const char *arg;
2516e4b17023SJohn Marino
2517e4b17023SJohn Marino struct command *commands; /* each command buffer with above info. */
2518e4b17023SJohn Marino
2519e4b17023SJohn Marino gcc_assert (!processing_spec_function);
2520e4b17023SJohn Marino
2521e4b17023SJohn Marino if (wrapper_string)
2522e4b17023SJohn Marino {
2523e4b17023SJohn Marino string = find_a_file (&exec_prefixes,
2524e4b17023SJohn Marino VEC_index (const_char_p, argbuf, 0), X_OK, false);
2525e4b17023SJohn Marino if (string)
2526e4b17023SJohn Marino VEC_replace (const_char_p, argbuf, 0, string);
2527e4b17023SJohn Marino insert_wrapper (wrapper_string);
2528e4b17023SJohn Marino }
2529e4b17023SJohn Marino
2530e4b17023SJohn Marino /* Count # of piped commands. */
2531e4b17023SJohn Marino for (n_commands = 1, i = 0; VEC_iterate (const_char_p, argbuf, i, arg); i++)
2532e4b17023SJohn Marino if (strcmp (arg, "|") == 0)
2533e4b17023SJohn Marino n_commands++;
2534e4b17023SJohn Marino
2535e4b17023SJohn Marino /* Get storage for each command. */
2536e4b17023SJohn Marino commands = (struct command *) alloca (n_commands * sizeof (struct command));
2537e4b17023SJohn Marino
2538e4b17023SJohn Marino /* Split argbuf into its separate piped processes,
2539e4b17023SJohn Marino and record info about each one.
2540e4b17023SJohn Marino Also search for the programs that are to be run. */
2541e4b17023SJohn Marino
2542e4b17023SJohn Marino VEC_safe_push (const_char_p, heap, argbuf, 0);
2543e4b17023SJohn Marino
2544e4b17023SJohn Marino commands[0].prog = VEC_index (const_char_p, argbuf, 0); /* first command. */
2545e4b17023SJohn Marino commands[0].argv = VEC_address (const_char_p, argbuf);
2546e4b17023SJohn Marino
2547e4b17023SJohn Marino if (!wrapper_string)
2548e4b17023SJohn Marino {
2549e4b17023SJohn Marino string = find_a_file (&exec_prefixes, commands[0].prog, X_OK, false);
2550e4b17023SJohn Marino commands[0].argv[0] = (string) ? string : commands[0].argv[0];
2551e4b17023SJohn Marino }
2552e4b17023SJohn Marino
2553e4b17023SJohn Marino for (n_commands = 1, i = 0; VEC_iterate (const_char_p, argbuf, i, arg); i++)
2554e4b17023SJohn Marino if (arg && strcmp (arg, "|") == 0)
2555e4b17023SJohn Marino { /* each command. */
2556e4b17023SJohn Marino #if defined (__MSDOS__) || defined (OS2) || defined (VMS)
2557e4b17023SJohn Marino fatal_error ("-pipe not supported");
2558e4b17023SJohn Marino #endif
2559e4b17023SJohn Marino VEC_replace (const_char_p, argbuf, i, 0); /* Termination of
2560e4b17023SJohn Marino command args. */
2561e4b17023SJohn Marino commands[n_commands].prog = VEC_index (const_char_p, argbuf, i + 1);
2562e4b17023SJohn Marino commands[n_commands].argv
2563e4b17023SJohn Marino = &(VEC_address (const_char_p, argbuf))[i + 1];
2564e4b17023SJohn Marino string = find_a_file (&exec_prefixes, commands[n_commands].prog,
2565e4b17023SJohn Marino X_OK, false);
2566e4b17023SJohn Marino if (string)
2567e4b17023SJohn Marino commands[n_commands].argv[0] = string;
2568e4b17023SJohn Marino n_commands++;
2569e4b17023SJohn Marino }
2570e4b17023SJohn Marino
2571e4b17023SJohn Marino /* If -v, print what we are about to do, and maybe query. */
2572e4b17023SJohn Marino
2573e4b17023SJohn Marino if (verbose_flag)
2574e4b17023SJohn Marino {
2575e4b17023SJohn Marino /* For help listings, put a blank line between sub-processes. */
2576e4b17023SJohn Marino if (print_help_list)
2577e4b17023SJohn Marino fputc ('\n', stderr);
2578e4b17023SJohn Marino
2579e4b17023SJohn Marino /* Print each piped command as a separate line. */
2580e4b17023SJohn Marino for (i = 0; i < n_commands; i++)
2581e4b17023SJohn Marino {
2582e4b17023SJohn Marino const char *const *j;
2583e4b17023SJohn Marino
2584e4b17023SJohn Marino if (verbose_only_flag)
2585e4b17023SJohn Marino {
2586e4b17023SJohn Marino for (j = commands[i].argv; *j; j++)
2587e4b17023SJohn Marino {
2588e4b17023SJohn Marino const char *p;
2589e4b17023SJohn Marino for (p = *j; *p; ++p)
2590e4b17023SJohn Marino if (!ISALNUM ((unsigned char) *p)
2591e4b17023SJohn Marino && *p != '_' && *p != '/' && *p != '-' && *p != '.')
2592e4b17023SJohn Marino break;
2593e4b17023SJohn Marino if (*p || !*j)
2594e4b17023SJohn Marino {
2595e4b17023SJohn Marino fprintf (stderr, " \"");
2596e4b17023SJohn Marino for (p = *j; *p; ++p)
2597e4b17023SJohn Marino {
2598e4b17023SJohn Marino if (*p == '"' || *p == '\\' || *p == '$')
2599e4b17023SJohn Marino fputc ('\\', stderr);
2600e4b17023SJohn Marino fputc (*p, stderr);
2601e4b17023SJohn Marino }
2602e4b17023SJohn Marino fputc ('"', stderr);
2603e4b17023SJohn Marino }
2604e4b17023SJohn Marino /* If it's empty, print "". */
2605e4b17023SJohn Marino else if (!**j)
2606e4b17023SJohn Marino fprintf (stderr, " \"\"");
2607e4b17023SJohn Marino else
2608e4b17023SJohn Marino fprintf (stderr, " %s", *j);
2609e4b17023SJohn Marino }
2610e4b17023SJohn Marino }
2611e4b17023SJohn Marino else
2612e4b17023SJohn Marino for (j = commands[i].argv; *j; j++)
2613e4b17023SJohn Marino /* If it's empty, print "". */
2614e4b17023SJohn Marino if (!**j)
2615e4b17023SJohn Marino fprintf (stderr, " \"\"");
2616e4b17023SJohn Marino else
2617e4b17023SJohn Marino fprintf (stderr, " %s", *j);
2618e4b17023SJohn Marino
2619e4b17023SJohn Marino /* Print a pipe symbol after all but the last command. */
2620e4b17023SJohn Marino if (i + 1 != n_commands)
2621e4b17023SJohn Marino fprintf (stderr, " |");
2622e4b17023SJohn Marino fprintf (stderr, "\n");
2623e4b17023SJohn Marino }
2624e4b17023SJohn Marino fflush (stderr);
2625e4b17023SJohn Marino if (verbose_only_flag != 0)
2626e4b17023SJohn Marino {
2627e4b17023SJohn Marino /* verbose_only_flag should act as if the spec was
2628e4b17023SJohn Marino executed, so increment execution_count before
2629e4b17023SJohn Marino returning. This prevents spurious warnings about
2630e4b17023SJohn Marino unused linker input files, etc. */
2631e4b17023SJohn Marino execution_count++;
2632e4b17023SJohn Marino return 0;
2633e4b17023SJohn Marino }
2634e4b17023SJohn Marino #ifdef DEBUG
2635e4b17023SJohn Marino fnotice (stderr, "\nGo ahead? (y or n) ");
2636e4b17023SJohn Marino fflush (stderr);
2637e4b17023SJohn Marino i = getchar ();
2638e4b17023SJohn Marino if (i != '\n')
2639e4b17023SJohn Marino while (getchar () != '\n')
2640e4b17023SJohn Marino ;
2641e4b17023SJohn Marino
2642e4b17023SJohn Marino if (i != 'y' && i != 'Y')
2643e4b17023SJohn Marino return 0;
2644e4b17023SJohn Marino #endif /* DEBUG */
2645e4b17023SJohn Marino }
2646e4b17023SJohn Marino
2647e4b17023SJohn Marino #ifdef ENABLE_VALGRIND_CHECKING
2648e4b17023SJohn Marino /* Run the each command through valgrind. To simplify prepending the
2649e4b17023SJohn Marino path to valgrind and the option "-q" (for quiet operation unless
2650e4b17023SJohn Marino something triggers), we allocate a separate argv array. */
2651e4b17023SJohn Marino
2652e4b17023SJohn Marino for (i = 0; i < n_commands; i++)
2653e4b17023SJohn Marino {
2654e4b17023SJohn Marino const char **argv;
2655e4b17023SJohn Marino int argc;
2656e4b17023SJohn Marino int j;
2657e4b17023SJohn Marino
2658e4b17023SJohn Marino for (argc = 0; commands[i].argv[argc] != NULL; argc++)
2659e4b17023SJohn Marino ;
2660e4b17023SJohn Marino
2661e4b17023SJohn Marino argv = XALLOCAVEC (const char *, argc + 3);
2662e4b17023SJohn Marino
2663e4b17023SJohn Marino argv[0] = VALGRIND_PATH;
2664e4b17023SJohn Marino argv[1] = "-q";
2665e4b17023SJohn Marino for (j = 2; j < argc + 2; j++)
2666e4b17023SJohn Marino argv[j] = commands[i].argv[j - 2];
2667e4b17023SJohn Marino argv[j] = NULL;
2668e4b17023SJohn Marino
2669e4b17023SJohn Marino commands[i].argv = argv;
2670e4b17023SJohn Marino commands[i].prog = argv[0];
2671e4b17023SJohn Marino }
2672e4b17023SJohn Marino #endif
2673e4b17023SJohn Marino
2674e4b17023SJohn Marino /* Run each piped subprocess. */
2675e4b17023SJohn Marino
2676e4b17023SJohn Marino pex = pex_init (PEX_USE_PIPES | ((report_times || report_times_to_file)
2677e4b17023SJohn Marino ? PEX_RECORD_TIMES : 0),
2678e4b17023SJohn Marino progname, temp_filename);
2679e4b17023SJohn Marino if (pex == NULL)
2680e4b17023SJohn Marino fatal_error ("pex_init failed: %m");
2681e4b17023SJohn Marino
2682e4b17023SJohn Marino for (i = 0; i < n_commands; i++)
2683e4b17023SJohn Marino {
2684e4b17023SJohn Marino const char *errmsg;
2685e4b17023SJohn Marino int err;
2686e4b17023SJohn Marino const char *string = commands[i].argv[0];
2687e4b17023SJohn Marino
2688e4b17023SJohn Marino errmsg = pex_run (pex,
2689e4b17023SJohn Marino ((i + 1 == n_commands ? PEX_LAST : 0)
2690e4b17023SJohn Marino | (string == commands[i].prog ? PEX_SEARCH : 0)),
2691e4b17023SJohn Marino string, CONST_CAST (char **, commands[i].argv),
2692e4b17023SJohn Marino NULL, NULL, &err);
2693e4b17023SJohn Marino if (errmsg != NULL)
2694e4b17023SJohn Marino {
2695e4b17023SJohn Marino if (err == 0)
2696e4b17023SJohn Marino fatal_error (errmsg);
2697e4b17023SJohn Marino else
2698e4b17023SJohn Marino {
2699e4b17023SJohn Marino errno = err;
2700e4b17023SJohn Marino pfatal_with_name (errmsg);
2701e4b17023SJohn Marino }
2702e4b17023SJohn Marino }
2703e4b17023SJohn Marino
2704e4b17023SJohn Marino if (string != commands[i].prog)
2705e4b17023SJohn Marino free (CONST_CAST (char *, string));
2706e4b17023SJohn Marino }
2707e4b17023SJohn Marino
2708e4b17023SJohn Marino execution_count++;
2709e4b17023SJohn Marino
2710e4b17023SJohn Marino /* Wait for all the subprocesses to finish. */
2711e4b17023SJohn Marino
2712e4b17023SJohn Marino {
2713e4b17023SJohn Marino int *statuses;
2714e4b17023SJohn Marino struct pex_time *times = NULL;
2715e4b17023SJohn Marino int ret_code = 0;
2716e4b17023SJohn Marino
2717e4b17023SJohn Marino statuses = (int *) alloca (n_commands * sizeof (int));
2718e4b17023SJohn Marino if (!pex_get_status (pex, n_commands, statuses))
2719e4b17023SJohn Marino fatal_error ("failed to get exit status: %m");
2720e4b17023SJohn Marino
2721e4b17023SJohn Marino if (report_times || report_times_to_file)
2722e4b17023SJohn Marino {
2723e4b17023SJohn Marino times = (struct pex_time *) alloca (n_commands * sizeof (struct pex_time));
2724e4b17023SJohn Marino if (!pex_get_times (pex, n_commands, times))
2725e4b17023SJohn Marino fatal_error ("failed to get process times: %m");
2726e4b17023SJohn Marino }
2727e4b17023SJohn Marino
2728e4b17023SJohn Marino pex_free (pex);
2729e4b17023SJohn Marino
2730e4b17023SJohn Marino for (i = 0; i < n_commands; ++i)
2731e4b17023SJohn Marino {
2732e4b17023SJohn Marino int status = statuses[i];
2733e4b17023SJohn Marino
2734e4b17023SJohn Marino if (WIFSIGNALED (status))
2735e4b17023SJohn Marino {
2736e4b17023SJohn Marino #ifdef SIGPIPE
2737e4b17023SJohn Marino /* SIGPIPE is a special case. It happens in -pipe mode
2738e4b17023SJohn Marino when the compiler dies before the preprocessor is done,
2739e4b17023SJohn Marino or the assembler dies before the compiler is done.
2740e4b17023SJohn Marino There's generally been an error already, and this is
2741e4b17023SJohn Marino just fallout. So don't generate another error unless
2742e4b17023SJohn Marino we would otherwise have succeeded. */
2743e4b17023SJohn Marino if (WTERMSIG (status) == SIGPIPE
2744e4b17023SJohn Marino && (signal_count || greatest_status >= MIN_FATAL_STATUS))
2745e4b17023SJohn Marino {
2746e4b17023SJohn Marino signal_count++;
2747e4b17023SJohn Marino ret_code = -1;
2748e4b17023SJohn Marino }
2749e4b17023SJohn Marino else
2750e4b17023SJohn Marino #endif
2751e4b17023SJohn Marino internal_error ("%s (program %s)",
2752e4b17023SJohn Marino strsignal (WTERMSIG (status)), commands[i].prog);
2753e4b17023SJohn Marino }
2754e4b17023SJohn Marino else if (WIFEXITED (status)
2755e4b17023SJohn Marino && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
2756e4b17023SJohn Marino {
2757e4b17023SJohn Marino if (WEXITSTATUS (status) > greatest_status)
2758e4b17023SJohn Marino greatest_status = WEXITSTATUS (status);
2759e4b17023SJohn Marino ret_code = -1;
2760e4b17023SJohn Marino }
2761e4b17023SJohn Marino
2762e4b17023SJohn Marino if (report_times || report_times_to_file)
2763e4b17023SJohn Marino {
2764e4b17023SJohn Marino struct pex_time *pt = ×[i];
2765e4b17023SJohn Marino double ut, st;
2766e4b17023SJohn Marino
2767e4b17023SJohn Marino ut = ((double) pt->user_seconds
2768e4b17023SJohn Marino + (double) pt->user_microseconds / 1.0e6);
2769e4b17023SJohn Marino st = ((double) pt->system_seconds
2770e4b17023SJohn Marino + (double) pt->system_microseconds / 1.0e6);
2771e4b17023SJohn Marino
2772e4b17023SJohn Marino if (ut + st != 0)
2773e4b17023SJohn Marino {
2774e4b17023SJohn Marino if (report_times)
2775e4b17023SJohn Marino fnotice (stderr, "# %s %.2f %.2f\n",
2776e4b17023SJohn Marino commands[i].prog, ut, st);
2777e4b17023SJohn Marino
2778e4b17023SJohn Marino if (report_times_to_file)
2779e4b17023SJohn Marino {
2780e4b17023SJohn Marino int c = 0;
2781e4b17023SJohn Marino const char *const *j;
2782e4b17023SJohn Marino
2783e4b17023SJohn Marino fprintf (report_times_to_file, "%g %g", ut, st);
2784e4b17023SJohn Marino
2785e4b17023SJohn Marino for (j = &commands[i].prog; *j; j = &commands[i].argv[++c])
2786e4b17023SJohn Marino {
2787e4b17023SJohn Marino const char *p;
2788e4b17023SJohn Marino for (p = *j; *p; ++p)
2789e4b17023SJohn Marino if (*p == '"' || *p == '\\' || *p == '$'
2790e4b17023SJohn Marino || ISSPACE (*p))
2791e4b17023SJohn Marino break;
2792e4b17023SJohn Marino
2793e4b17023SJohn Marino if (*p)
2794e4b17023SJohn Marino {
2795e4b17023SJohn Marino fprintf (report_times_to_file, " \"");
2796e4b17023SJohn Marino for (p = *j; *p; ++p)
2797e4b17023SJohn Marino {
2798e4b17023SJohn Marino if (*p == '"' || *p == '\\' || *p == '$')
2799e4b17023SJohn Marino fputc ('\\', report_times_to_file);
2800e4b17023SJohn Marino fputc (*p, report_times_to_file);
2801e4b17023SJohn Marino }
2802e4b17023SJohn Marino fputc ('"', report_times_to_file);
2803e4b17023SJohn Marino }
2804e4b17023SJohn Marino else
2805e4b17023SJohn Marino fprintf (report_times_to_file, " %s", *j);
2806e4b17023SJohn Marino }
2807e4b17023SJohn Marino
2808e4b17023SJohn Marino fputc ('\n', report_times_to_file);
2809e4b17023SJohn Marino }
2810e4b17023SJohn Marino }
2811e4b17023SJohn Marino }
2812e4b17023SJohn Marino }
2813e4b17023SJohn Marino
2814e4b17023SJohn Marino return ret_code;
2815e4b17023SJohn Marino }
2816e4b17023SJohn Marino }
2817e4b17023SJohn Marino
2818e4b17023SJohn Marino /* Find all the switches given to us
2819e4b17023SJohn Marino and make a vector describing them.
2820e4b17023SJohn Marino The elements of the vector are strings, one per switch given.
2821e4b17023SJohn Marino If a switch uses following arguments, then the `part1' field
2822e4b17023SJohn Marino is the switch itself and the `args' field
2823e4b17023SJohn Marino is a null-terminated vector containing the following arguments.
2824e4b17023SJohn Marino Bits in the `live_cond' field are:
2825e4b17023SJohn Marino SWITCH_LIVE to indicate this switch is true in a conditional spec.
2826e4b17023SJohn Marino SWITCH_FALSE to indicate this switch is overridden by a later switch.
2827e4b17023SJohn Marino SWITCH_IGNORE to indicate this switch should be ignored (used in %<S).
2828e4b17023SJohn Marino SWITCH_IGNORE_PERMANENTLY to indicate this switch should be ignored
2829e4b17023SJohn Marino in all do_spec calls afterwards. Used for %<S from self specs.
2830e4b17023SJohn Marino The `validated' field is nonzero if any spec has looked at this switch;
2831e4b17023SJohn Marino if it remains zero at the end of the run, it must be meaningless. */
2832e4b17023SJohn Marino
2833e4b17023SJohn Marino #define SWITCH_LIVE (1 << 0)
2834e4b17023SJohn Marino #define SWITCH_FALSE (1 << 1)
2835e4b17023SJohn Marino #define SWITCH_IGNORE (1 << 2)
2836e4b17023SJohn Marino #define SWITCH_IGNORE_PERMANENTLY (1 << 3)
2837e4b17023SJohn Marino #define SWITCH_KEEP_FOR_GCC (1 << 4)
2838e4b17023SJohn Marino
2839e4b17023SJohn Marino struct switchstr
2840e4b17023SJohn Marino {
2841e4b17023SJohn Marino const char *part1;
2842e4b17023SJohn Marino const char **args;
2843e4b17023SJohn Marino unsigned int live_cond;
2844e4b17023SJohn Marino unsigned char validated;
2845e4b17023SJohn Marino unsigned char ordering;
2846e4b17023SJohn Marino };
2847e4b17023SJohn Marino
2848e4b17023SJohn Marino static struct switchstr *switches;
2849e4b17023SJohn Marino
2850e4b17023SJohn Marino static int n_switches;
2851e4b17023SJohn Marino
2852e4b17023SJohn Marino static int n_switches_alloc;
2853e4b17023SJohn Marino
2854e4b17023SJohn Marino /* Set to zero if -fcompare-debug is disabled, positive if it's
2855e4b17023SJohn Marino enabled and we're running the first compilation, negative if it's
2856e4b17023SJohn Marino enabled and we're running the second compilation. For most of the
2857e4b17023SJohn Marino time, it's in the range -1..1, but it can be temporarily set to 2
2858e4b17023SJohn Marino or 3 to indicate that the -fcompare-debug flags didn't come from
2859e4b17023SJohn Marino the command-line, but rather from the GCC_COMPARE_DEBUG environment
2860e4b17023SJohn Marino variable, until a synthesized -fcompare-debug flag is added to the
2861e4b17023SJohn Marino command line. */
2862e4b17023SJohn Marino int compare_debug;
2863e4b17023SJohn Marino
2864e4b17023SJohn Marino /* Set to nonzero if we've seen the -fcompare-debug-second flag. */
2865e4b17023SJohn Marino int compare_debug_second;
2866e4b17023SJohn Marino
2867e4b17023SJohn Marino /* Set to the flags that should be passed to the second compilation in
2868e4b17023SJohn Marino a -fcompare-debug compilation. */
2869e4b17023SJohn Marino const char *compare_debug_opt;
2870e4b17023SJohn Marino
2871e4b17023SJohn Marino static struct switchstr *switches_debug_check[2];
2872e4b17023SJohn Marino
2873e4b17023SJohn Marino static int n_switches_debug_check[2];
2874e4b17023SJohn Marino
2875e4b17023SJohn Marino static int n_switches_alloc_debug_check[2];
2876e4b17023SJohn Marino
2877e4b17023SJohn Marino static char *debug_check_temp_file[2];
2878e4b17023SJohn Marino
2879e4b17023SJohn Marino /* Language is one of three things:
2880e4b17023SJohn Marino
2881e4b17023SJohn Marino 1) The name of a real programming language.
2882e4b17023SJohn Marino 2) NULL, indicating that no one has figured out
2883e4b17023SJohn Marino what it is yet.
2884e4b17023SJohn Marino 3) '*', indicating that the file should be passed
2885e4b17023SJohn Marino to the linker. */
2886e4b17023SJohn Marino struct infile
2887e4b17023SJohn Marino {
2888e4b17023SJohn Marino const char *name;
2889e4b17023SJohn Marino const char *language;
2890e4b17023SJohn Marino struct compiler *incompiler;
2891e4b17023SJohn Marino bool compiled;
2892e4b17023SJohn Marino bool preprocessed;
2893e4b17023SJohn Marino };
2894e4b17023SJohn Marino
2895e4b17023SJohn Marino /* Also a vector of input files specified. */
2896e4b17023SJohn Marino
2897e4b17023SJohn Marino static struct infile *infiles;
2898e4b17023SJohn Marino
2899e4b17023SJohn Marino int n_infiles;
2900e4b17023SJohn Marino
2901e4b17023SJohn Marino static int n_infiles_alloc;
2902e4b17023SJohn Marino
2903e4b17023SJohn Marino /* True if multiple input files are being compiled to a single
2904e4b17023SJohn Marino assembly file. */
2905e4b17023SJohn Marino
2906e4b17023SJohn Marino static bool combine_inputs;
2907e4b17023SJohn Marino
2908e4b17023SJohn Marino /* This counts the number of libraries added by lang_specific_driver, so that
2909e4b17023SJohn Marino we can tell if there were any user supplied any files or libraries. */
2910e4b17023SJohn Marino
2911e4b17023SJohn Marino static int added_libraries;
2912e4b17023SJohn Marino
2913e4b17023SJohn Marino /* And a vector of corresponding output files is made up later. */
2914e4b17023SJohn Marino
2915e4b17023SJohn Marino const char **outfiles;
2916e4b17023SJohn Marino
2917e4b17023SJohn Marino #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
2918e4b17023SJohn Marino
2919e4b17023SJohn Marino /* Convert NAME to a new name if it is the standard suffix. DO_EXE
2920e4b17023SJohn Marino is true if we should look for an executable suffix. DO_OBJ
2921e4b17023SJohn Marino is true if we should look for an object suffix. */
2922e4b17023SJohn Marino
2923e4b17023SJohn Marino static const char *
convert_filename(const char * name,int do_exe ATTRIBUTE_UNUSED,int do_obj ATTRIBUTE_UNUSED)2924e4b17023SJohn Marino convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
2925e4b17023SJohn Marino int do_obj ATTRIBUTE_UNUSED)
2926e4b17023SJohn Marino {
2927e4b17023SJohn Marino #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
2928e4b17023SJohn Marino int i;
2929e4b17023SJohn Marino #endif
2930e4b17023SJohn Marino int len;
2931e4b17023SJohn Marino
2932e4b17023SJohn Marino if (name == NULL)
2933e4b17023SJohn Marino return NULL;
2934e4b17023SJohn Marino
2935e4b17023SJohn Marino len = strlen (name);
2936e4b17023SJohn Marino
2937e4b17023SJohn Marino #ifdef HAVE_TARGET_OBJECT_SUFFIX
2938e4b17023SJohn Marino /* Convert x.o to x.obj if TARGET_OBJECT_SUFFIX is ".obj". */
2939e4b17023SJohn Marino if (do_obj && len > 2
2940e4b17023SJohn Marino && name[len - 2] == '.'
2941e4b17023SJohn Marino && name[len - 1] == 'o')
2942e4b17023SJohn Marino {
2943e4b17023SJohn Marino obstack_grow (&obstack, name, len - 2);
2944e4b17023SJohn Marino obstack_grow0 (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
2945e4b17023SJohn Marino name = XOBFINISH (&obstack, const char *);
2946e4b17023SJohn Marino }
2947e4b17023SJohn Marino #endif
2948e4b17023SJohn Marino
2949e4b17023SJohn Marino #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
2950e4b17023SJohn Marino /* If there is no filetype, make it the executable suffix (which includes
2951e4b17023SJohn Marino the "."). But don't get confused if we have just "-o". */
2952e4b17023SJohn Marino if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || (len == 2 && name[0] == '-'))
2953e4b17023SJohn Marino return name;
2954e4b17023SJohn Marino
2955e4b17023SJohn Marino for (i = len - 1; i >= 0; i--)
2956e4b17023SJohn Marino if (IS_DIR_SEPARATOR (name[i]))
2957e4b17023SJohn Marino break;
2958e4b17023SJohn Marino
2959e4b17023SJohn Marino for (i++; i < len; i++)
2960e4b17023SJohn Marino if (name[i] == '.')
2961e4b17023SJohn Marino return name;
2962e4b17023SJohn Marino
2963e4b17023SJohn Marino obstack_grow (&obstack, name, len);
2964e4b17023SJohn Marino obstack_grow0 (&obstack, TARGET_EXECUTABLE_SUFFIX,
2965e4b17023SJohn Marino strlen (TARGET_EXECUTABLE_SUFFIX));
2966e4b17023SJohn Marino name = XOBFINISH (&obstack, const char *);
2967e4b17023SJohn Marino #endif
2968e4b17023SJohn Marino
2969e4b17023SJohn Marino return name;
2970e4b17023SJohn Marino }
2971e4b17023SJohn Marino #endif
2972e4b17023SJohn Marino
2973e4b17023SJohn Marino /* Display the command line switches accepted by gcc. */
2974e4b17023SJohn Marino static void
display_help(void)2975e4b17023SJohn Marino display_help (void)
2976e4b17023SJohn Marino {
2977e4b17023SJohn Marino printf (_("Usage: %s [options] file...\n"), progname);
2978e4b17023SJohn Marino fputs (_("Options:\n"), stdout);
2979e4b17023SJohn Marino
2980e4b17023SJohn Marino fputs (_(" -pass-exit-codes Exit with highest error code from a phase\n"), stdout);
2981e4b17023SJohn Marino fputs (_(" --help Display this information\n"), stdout);
2982e4b17023SJohn Marino fputs (_(" --target-help Display target specific command line options\n"), stdout);
2983e4b17023SJohn Marino fputs (_(" --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]\n"), stdout);
2984e4b17023SJohn Marino fputs (_(" Display specific types of command line options\n"), stdout);
2985e4b17023SJohn Marino if (! verbose_flag)
2986e4b17023SJohn Marino fputs (_(" (Use '-v --help' to display command line options of sub-processes)\n"), stdout);
2987e4b17023SJohn Marino fputs (_(" --version Display compiler version information\n"), stdout);
2988e4b17023SJohn Marino fputs (_(" -dumpspecs Display all of the built in spec strings\n"), stdout);
2989e4b17023SJohn Marino fputs (_(" -dumpversion Display the version of the compiler\n"), stdout);
2990e4b17023SJohn Marino fputs (_(" -dumpmachine Display the compiler's target processor\n"), stdout);
2991e4b17023SJohn Marino fputs (_(" -print-search-dirs Display the directories in the compiler's search path\n"), stdout);
2992e4b17023SJohn Marino fputs (_(" -print-libgcc-file-name Display the name of the compiler's companion library\n"), stdout);
2993e4b17023SJohn Marino fputs (_(" -print-file-name=<lib> Display the full path to library <lib>\n"), stdout);
2994e4b17023SJohn Marino fputs (_(" -print-prog-name=<prog> Display the full path to compiler component <prog>\n"), stdout);
29955ce9237cSJohn Marino fputs (_("\
29965ce9237cSJohn Marino -print-multiarch Display the target's normalized GNU triplet, used as\n\
29975ce9237cSJohn Marino a component in the library path\n"), stdout);
2998e4b17023SJohn Marino fputs (_(" -print-multi-directory Display the root directory for versions of libgcc\n"), stdout);
2999e4b17023SJohn Marino fputs (_("\
3000e4b17023SJohn Marino -print-multi-lib Display the mapping between command line options and\n\
3001e4b17023SJohn Marino multiple library search directories\n"), stdout);
3002e4b17023SJohn Marino fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout);
3003e4b17023SJohn Marino fputs (_(" -print-sysroot Display the target libraries directory\n"), stdout);
3004e4b17023SJohn Marino fputs (_(" -print-sysroot-headers-suffix Display the sysroot suffix used to find headers\n"), stdout);
3005e4b17023SJohn Marino fputs (_(" -Wa,<options> Pass comma-separated <options> on to the assembler\n"), stdout);
3006e4b17023SJohn Marino fputs (_(" -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"), stdout);
3007e4b17023SJohn Marino fputs (_(" -Wl,<options> Pass comma-separated <options> on to the linker\n"), stdout);
3008e4b17023SJohn Marino fputs (_(" -Xassembler <arg> Pass <arg> on to the assembler\n"), stdout);
3009e4b17023SJohn Marino fputs (_(" -Xpreprocessor <arg> Pass <arg> on to the preprocessor\n"), stdout);
3010e4b17023SJohn Marino fputs (_(" -Xlinker <arg> Pass <arg> on to the linker\n"), stdout);
3011e4b17023SJohn Marino fputs (_(" -save-temps Do not delete intermediate files\n"), stdout);
3012e4b17023SJohn Marino fputs (_(" -save-temps=<arg> Do not delete intermediate files\n"), stdout);
3013e4b17023SJohn Marino fputs (_("\
3014e4b17023SJohn Marino -no-canonical-prefixes Do not canonicalize paths when building relative\n\
3015e4b17023SJohn Marino prefixes to other gcc components\n"), stdout);
3016e4b17023SJohn Marino fputs (_(" -pipe Use pipes rather than intermediate files\n"), stdout);
3017e4b17023SJohn Marino fputs (_(" -time Time the execution of each subprocess\n"), stdout);
3018e4b17023SJohn Marino fputs (_(" -specs=<file> Override built-in specs with the contents of <file>\n"), stdout);
3019e4b17023SJohn Marino fputs (_(" -std=<standard> Assume that the input sources are for <standard>\n"), stdout);
3020e4b17023SJohn Marino fputs (_("\
3021e4b17023SJohn Marino --sysroot=<directory> Use <directory> as the root directory for headers\n\
3022e4b17023SJohn Marino and libraries\n"), stdout);
3023e4b17023SJohn Marino fputs (_(" -B <directory> Add <directory> to the compiler's search paths\n"), stdout);
3024e4b17023SJohn Marino fputs (_(" -v Display the programs invoked by the compiler\n"), stdout);
3025e4b17023SJohn Marino fputs (_(" -### Like -v but options quoted and commands not executed\n"), stdout);
3026e4b17023SJohn Marino fputs (_(" -E Preprocess only; do not compile, assemble or link\n"), stdout);
3027e4b17023SJohn Marino fputs (_(" -S Compile only; do not assemble or link\n"), stdout);
3028e4b17023SJohn Marino fputs (_(" -c Compile and assemble, but do not link\n"), stdout);
3029e4b17023SJohn Marino fputs (_(" -o <file> Place the output into <file>\n"), stdout);
3030e4b17023SJohn Marino fputs (_(" -pie Create a position independent executable\n"), stdout);
3031e4b17023SJohn Marino fputs (_(" -shared Create a shared library\n"), stdout);
3032e4b17023SJohn Marino fputs (_("\
3033e4b17023SJohn Marino -x <language> Specify the language of the following input files\n\
3034e4b17023SJohn Marino Permissible languages include: c c++ assembler none\n\
3035e4b17023SJohn Marino 'none' means revert to the default behavior of\n\
3036e4b17023SJohn Marino guessing the language based on the file's extension\n\
3037e4b17023SJohn Marino "), stdout);
3038e4b17023SJohn Marino
3039e4b17023SJohn Marino printf (_("\
3040e4b17023SJohn Marino \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
3041e4b17023SJohn Marino passed on to the various sub-processes invoked by %s. In order to pass\n\
3042e4b17023SJohn Marino other options on to these processes the -W<letter> options must be used.\n\
3043e4b17023SJohn Marino "), progname);
3044e4b17023SJohn Marino
3045e4b17023SJohn Marino /* The rest of the options are displayed by invocations of the various
3046e4b17023SJohn Marino sub-processes. */
3047e4b17023SJohn Marino }
3048e4b17023SJohn Marino
3049e4b17023SJohn Marino static void
add_preprocessor_option(const char * option,int len)3050e4b17023SJohn Marino add_preprocessor_option (const char *option, int len)
3051e4b17023SJohn Marino {
3052e4b17023SJohn Marino VEC_safe_push (char_p, heap, preprocessor_options,
3053e4b17023SJohn Marino save_string (option, len));
3054e4b17023SJohn Marino }
3055e4b17023SJohn Marino
3056e4b17023SJohn Marino static void
add_assembler_option(const char * option,int len)3057e4b17023SJohn Marino add_assembler_option (const char *option, int len)
3058e4b17023SJohn Marino {
3059e4b17023SJohn Marino VEC_safe_push (char_p, heap, assembler_options, save_string (option, len));
3060e4b17023SJohn Marino }
3061e4b17023SJohn Marino
3062e4b17023SJohn Marino static void
add_linker_option(const char * option,int len)3063e4b17023SJohn Marino add_linker_option (const char *option, int len)
3064e4b17023SJohn Marino {
3065e4b17023SJohn Marino VEC_safe_push (char_p, heap, linker_options, save_string (option, len));
3066e4b17023SJohn Marino }
3067e4b17023SJohn Marino
3068e4b17023SJohn Marino /* Allocate space for an input file in infiles. */
3069e4b17023SJohn Marino
3070e4b17023SJohn Marino static void
alloc_infile(void)3071e4b17023SJohn Marino alloc_infile (void)
3072e4b17023SJohn Marino {
3073e4b17023SJohn Marino if (n_infiles_alloc == 0)
3074e4b17023SJohn Marino {
3075e4b17023SJohn Marino n_infiles_alloc = 16;
3076e4b17023SJohn Marino infiles = XNEWVEC (struct infile, n_infiles_alloc);
3077e4b17023SJohn Marino }
3078e4b17023SJohn Marino else if (n_infiles_alloc == n_infiles)
3079e4b17023SJohn Marino {
3080e4b17023SJohn Marino n_infiles_alloc *= 2;
3081e4b17023SJohn Marino infiles = XRESIZEVEC (struct infile, infiles, n_infiles_alloc);
3082e4b17023SJohn Marino }
3083e4b17023SJohn Marino }
3084e4b17023SJohn Marino
3085e4b17023SJohn Marino /* Store an input file with the given NAME and LANGUAGE in
3086e4b17023SJohn Marino infiles. */
3087e4b17023SJohn Marino
3088e4b17023SJohn Marino static void
add_infile(const char * name,const char * language)3089e4b17023SJohn Marino add_infile (const char *name, const char *language)
3090e4b17023SJohn Marino {
3091e4b17023SJohn Marino alloc_infile ();
3092e4b17023SJohn Marino infiles[n_infiles].name = name;
3093e4b17023SJohn Marino infiles[n_infiles++].language = language;
3094e4b17023SJohn Marino }
3095e4b17023SJohn Marino
3096e4b17023SJohn Marino /* Allocate space for a switch in switches. */
3097e4b17023SJohn Marino
3098e4b17023SJohn Marino static void
alloc_switch(void)3099e4b17023SJohn Marino alloc_switch (void)
3100e4b17023SJohn Marino {
3101e4b17023SJohn Marino if (n_switches_alloc == 0)
3102e4b17023SJohn Marino {
3103e4b17023SJohn Marino n_switches_alloc = 16;
3104e4b17023SJohn Marino switches = XNEWVEC (struct switchstr, n_switches_alloc);
3105e4b17023SJohn Marino }
3106e4b17023SJohn Marino else if (n_switches_alloc == n_switches)
3107e4b17023SJohn Marino {
3108e4b17023SJohn Marino n_switches_alloc *= 2;
3109e4b17023SJohn Marino switches = XRESIZEVEC (struct switchstr, switches, n_switches_alloc);
3110e4b17023SJohn Marino }
3111e4b17023SJohn Marino }
3112e4b17023SJohn Marino
3113e4b17023SJohn Marino /* Save an option OPT with N_ARGS arguments in array ARGS, marking it
3114e4b17023SJohn Marino as validated if VALIDATED. */
3115e4b17023SJohn Marino
3116e4b17023SJohn Marino static void
save_switch(const char * opt,size_t n_args,const char * const * args,bool validated)3117e4b17023SJohn Marino save_switch (const char *opt, size_t n_args, const char *const *args,
3118e4b17023SJohn Marino bool validated)
3119e4b17023SJohn Marino {
3120e4b17023SJohn Marino alloc_switch ();
3121e4b17023SJohn Marino switches[n_switches].part1 = opt + 1;
3122e4b17023SJohn Marino if (n_args == 0)
3123e4b17023SJohn Marino switches[n_switches].args = 0;
3124e4b17023SJohn Marino else
3125e4b17023SJohn Marino {
3126e4b17023SJohn Marino switches[n_switches].args = XNEWVEC (const char *, n_args + 1);
3127e4b17023SJohn Marino memcpy (switches[n_switches].args, args, n_args * sizeof (const char *));
3128e4b17023SJohn Marino switches[n_switches].args[n_args] = NULL;
3129e4b17023SJohn Marino }
3130e4b17023SJohn Marino
3131e4b17023SJohn Marino switches[n_switches].live_cond = 0;
3132e4b17023SJohn Marino switches[n_switches].validated = validated;
3133e4b17023SJohn Marino switches[n_switches].ordering = 0;
3134e4b17023SJohn Marino n_switches++;
3135e4b17023SJohn Marino }
3136e4b17023SJohn Marino
3137e4b17023SJohn Marino /* Handle an option DECODED that is unknown to the option-processing
3138e4b17023SJohn Marino machinery. */
3139e4b17023SJohn Marino
3140e4b17023SJohn Marino static bool
driver_unknown_option_callback(const struct cl_decoded_option * decoded)3141e4b17023SJohn Marino driver_unknown_option_callback (const struct cl_decoded_option *decoded)
3142e4b17023SJohn Marino {
3143e4b17023SJohn Marino const char *opt = decoded->arg;
3144e4b17023SJohn Marino if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
3145e4b17023SJohn Marino && !(decoded->errors & CL_ERR_NEGATIVE))
3146e4b17023SJohn Marino {
3147e4b17023SJohn Marino /* Leave unknown -Wno-* options for the compiler proper, to be
3148e4b17023SJohn Marino diagnosed only if there are warnings. */
3149e4b17023SJohn Marino save_switch (decoded->canonical_option[0],
3150e4b17023SJohn Marino decoded->canonical_option_num_elements - 1,
3151e4b17023SJohn Marino &decoded->canonical_option[1], false);
3152e4b17023SJohn Marino return false;
3153e4b17023SJohn Marino }
3154e4b17023SJohn Marino else
3155e4b17023SJohn Marino return true;
3156e4b17023SJohn Marino }
3157e4b17023SJohn Marino
3158e4b17023SJohn Marino /* Handle an option DECODED that is not marked as CL_DRIVER.
3159e4b17023SJohn Marino LANG_MASK will always be CL_DRIVER. */
3160e4b17023SJohn Marino
3161e4b17023SJohn Marino static void
driver_wrong_lang_callback(const struct cl_decoded_option * decoded,unsigned int lang_mask ATTRIBUTE_UNUSED)3162e4b17023SJohn Marino driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
3163e4b17023SJohn Marino unsigned int lang_mask ATTRIBUTE_UNUSED)
3164e4b17023SJohn Marino {
3165e4b17023SJohn Marino /* At this point, non-driver options are accepted (and expected to
3166e4b17023SJohn Marino be passed down by specs) unless marked to be rejected by the
3167e4b17023SJohn Marino driver. Options to be rejected by the driver but accepted by the
3168e4b17023SJohn Marino compilers proper are treated just like completely unknown
3169e4b17023SJohn Marino options. */
3170e4b17023SJohn Marino const struct cl_option *option = &cl_options[decoded->opt_index];
3171e4b17023SJohn Marino
3172e4b17023SJohn Marino if (option->cl_reject_driver)
3173e4b17023SJohn Marino error ("unrecognized command line option %qs",
3174e4b17023SJohn Marino decoded->orig_option_with_args_text);
3175e4b17023SJohn Marino else
3176e4b17023SJohn Marino save_switch (decoded->canonical_option[0],
3177e4b17023SJohn Marino decoded->canonical_option_num_elements - 1,
3178e4b17023SJohn Marino &decoded->canonical_option[1], false);
3179e4b17023SJohn Marino }
3180e4b17023SJohn Marino
3181e4b17023SJohn Marino static const char *spec_lang = 0;
3182e4b17023SJohn Marino static int last_language_n_infiles;
3183e4b17023SJohn Marino
3184e4b17023SJohn Marino /* Handle a driver option; arguments and return value as for
3185e4b17023SJohn Marino handle_option. */
3186e4b17023SJohn Marino
3187e4b17023SJohn Marino static bool
driver_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,unsigned int lang_mask ATTRIBUTE_UNUSED,int kind,location_t loc,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED,diagnostic_context * dc)3188e4b17023SJohn Marino driver_handle_option (struct gcc_options *opts,
3189e4b17023SJohn Marino struct gcc_options *opts_set,
3190e4b17023SJohn Marino const struct cl_decoded_option *decoded,
3191e4b17023SJohn Marino unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
3192e4b17023SJohn Marino location_t loc,
3193e4b17023SJohn Marino const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
3194e4b17023SJohn Marino diagnostic_context *dc)
3195e4b17023SJohn Marino {
3196e4b17023SJohn Marino size_t opt_index = decoded->opt_index;
3197e4b17023SJohn Marino const char *arg = decoded->arg;
3198e4b17023SJohn Marino const char *compare_debug_replacement_opt;
3199e4b17023SJohn Marino int value = decoded->value;
3200e4b17023SJohn Marino bool validated = false;
3201e4b17023SJohn Marino bool do_save = true;
3202e4b17023SJohn Marino
3203e4b17023SJohn Marino gcc_assert (opts == &global_options);
3204e4b17023SJohn Marino gcc_assert (opts_set == &global_options_set);
3205e4b17023SJohn Marino gcc_assert (kind == DK_UNSPECIFIED);
3206e4b17023SJohn Marino gcc_assert (loc == UNKNOWN_LOCATION);
3207e4b17023SJohn Marino gcc_assert (dc == global_dc);
3208e4b17023SJohn Marino
3209e4b17023SJohn Marino switch (opt_index)
3210e4b17023SJohn Marino {
3211e4b17023SJohn Marino case OPT_dumpspecs:
3212e4b17023SJohn Marino {
3213e4b17023SJohn Marino struct spec_list *sl;
3214e4b17023SJohn Marino init_spec ();
3215e4b17023SJohn Marino for (sl = specs; sl; sl = sl->next)
3216e4b17023SJohn Marino printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
3217e4b17023SJohn Marino if (link_command_spec)
3218e4b17023SJohn Marino printf ("*link_command:\n%s\n\n", link_command_spec);
3219e4b17023SJohn Marino exit (0);
3220e4b17023SJohn Marino }
3221e4b17023SJohn Marino
3222e4b17023SJohn Marino case OPT_dumpversion:
3223e4b17023SJohn Marino printf ("%s\n", spec_version);
3224e4b17023SJohn Marino exit (0);
3225e4b17023SJohn Marino
3226e4b17023SJohn Marino case OPT_dumpmachine:
3227e4b17023SJohn Marino printf ("%s\n", spec_machine);
3228e4b17023SJohn Marino exit (0);
3229e4b17023SJohn Marino
3230e4b17023SJohn Marino case OPT__version:
3231e4b17023SJohn Marino print_version = 1;
3232e4b17023SJohn Marino
3233e4b17023SJohn Marino /* CPP driver cannot obtain switch from cc1_options. */
3234e4b17023SJohn Marino if (is_cpp_driver)
3235e4b17023SJohn Marino add_preprocessor_option ("--version", strlen ("--version"));
3236e4b17023SJohn Marino add_assembler_option ("--version", strlen ("--version"));
3237e4b17023SJohn Marino add_linker_option ("--version", strlen ("--version"));
3238e4b17023SJohn Marino break;
3239e4b17023SJohn Marino
3240e4b17023SJohn Marino case OPT__help:
3241e4b17023SJohn Marino print_help_list = 1;
3242e4b17023SJohn Marino
3243e4b17023SJohn Marino /* CPP driver cannot obtain switch from cc1_options. */
3244e4b17023SJohn Marino if (is_cpp_driver)
3245e4b17023SJohn Marino add_preprocessor_option ("--help", 6);
3246e4b17023SJohn Marino add_assembler_option ("--help", 6);
3247e4b17023SJohn Marino add_linker_option ("--help", 6);
3248e4b17023SJohn Marino break;
3249e4b17023SJohn Marino
3250e4b17023SJohn Marino case OPT__help_:
3251e4b17023SJohn Marino print_subprocess_help = 2;
3252e4b17023SJohn Marino break;
3253e4b17023SJohn Marino
3254e4b17023SJohn Marino case OPT__target_help:
3255e4b17023SJohn Marino print_subprocess_help = 1;
3256e4b17023SJohn Marino
3257e4b17023SJohn Marino /* CPP driver cannot obtain switch from cc1_options. */
3258e4b17023SJohn Marino if (is_cpp_driver)
3259e4b17023SJohn Marino add_preprocessor_option ("--target-help", 13);
3260e4b17023SJohn Marino add_assembler_option ("--target-help", 13);
3261e4b17023SJohn Marino add_linker_option ("--target-help", 13);
3262e4b17023SJohn Marino break;
3263e4b17023SJohn Marino
3264e4b17023SJohn Marino case OPT_pass_exit_codes:
3265e4b17023SJohn Marino case OPT_print_search_dirs:
3266e4b17023SJohn Marino case OPT_print_file_name_:
3267e4b17023SJohn Marino case OPT_print_prog_name_:
3268e4b17023SJohn Marino case OPT_print_multi_lib:
3269e4b17023SJohn Marino case OPT_print_multi_directory:
3270e4b17023SJohn Marino case OPT_print_sysroot:
3271e4b17023SJohn Marino case OPT_print_multi_os_directory:
32725ce9237cSJohn Marino case OPT_print_multiarch:
3273e4b17023SJohn Marino case OPT_print_sysroot_headers_suffix:
3274e4b17023SJohn Marino case OPT_time:
3275e4b17023SJohn Marino case OPT_wrapper:
3276e4b17023SJohn Marino /* These options set the variables specified in common.opt
3277e4b17023SJohn Marino automatically, and do not need to be saved for spec
3278e4b17023SJohn Marino processing. */
3279e4b17023SJohn Marino do_save = false;
3280e4b17023SJohn Marino break;
3281e4b17023SJohn Marino
3282e4b17023SJohn Marino case OPT_print_libgcc_file_name:
3283e4b17023SJohn Marino print_file_name = "libgcc.a";
3284e4b17023SJohn Marino do_save = false;
3285e4b17023SJohn Marino break;
3286e4b17023SJohn Marino
3287e4b17023SJohn Marino case OPT_fcompare_debug_second:
3288e4b17023SJohn Marino compare_debug_second = 1;
3289e4b17023SJohn Marino break;
3290e4b17023SJohn Marino
3291e4b17023SJohn Marino case OPT_fcompare_debug:
3292e4b17023SJohn Marino switch (value)
3293e4b17023SJohn Marino {
3294e4b17023SJohn Marino case 0:
3295e4b17023SJohn Marino compare_debug_replacement_opt = "-fcompare-debug=";
3296e4b17023SJohn Marino arg = "";
3297e4b17023SJohn Marino goto compare_debug_with_arg;
3298e4b17023SJohn Marino
3299e4b17023SJohn Marino case 1:
3300e4b17023SJohn Marino compare_debug_replacement_opt = "-fcompare-debug=-gtoggle";
3301e4b17023SJohn Marino arg = "-gtoggle";
3302e4b17023SJohn Marino goto compare_debug_with_arg;
3303e4b17023SJohn Marino
3304e4b17023SJohn Marino default:
3305e4b17023SJohn Marino gcc_unreachable ();
3306e4b17023SJohn Marino }
3307e4b17023SJohn Marino break;
3308e4b17023SJohn Marino
3309e4b17023SJohn Marino case OPT_fcompare_debug_:
3310e4b17023SJohn Marino compare_debug_replacement_opt = decoded->canonical_option[0];
3311e4b17023SJohn Marino compare_debug_with_arg:
3312e4b17023SJohn Marino gcc_assert (decoded->canonical_option_num_elements == 1);
3313e4b17023SJohn Marino gcc_assert (arg != NULL);
3314e4b17023SJohn Marino if (*arg)
3315e4b17023SJohn Marino compare_debug = 1;
3316e4b17023SJohn Marino else
3317e4b17023SJohn Marino compare_debug = -1;
3318e4b17023SJohn Marino if (compare_debug < 0)
3319e4b17023SJohn Marino compare_debug_opt = NULL;
3320e4b17023SJohn Marino else
3321e4b17023SJohn Marino compare_debug_opt = arg;
3322e4b17023SJohn Marino save_switch (compare_debug_replacement_opt, 0, NULL, validated);
3323e4b17023SJohn Marino return true;
3324e4b17023SJohn Marino
3325e4b17023SJohn Marino case OPT_Wa_:
3326e4b17023SJohn Marino {
3327e4b17023SJohn Marino int prev, j;
3328e4b17023SJohn Marino /* Pass the rest of this option to the assembler. */
3329e4b17023SJohn Marino
3330e4b17023SJohn Marino /* Split the argument at commas. */
3331e4b17023SJohn Marino prev = 0;
3332e4b17023SJohn Marino for (j = 0; arg[j]; j++)
3333e4b17023SJohn Marino if (arg[j] == ',')
3334e4b17023SJohn Marino {
3335e4b17023SJohn Marino add_assembler_option (arg + prev, j - prev);
3336e4b17023SJohn Marino prev = j + 1;
3337e4b17023SJohn Marino }
3338e4b17023SJohn Marino
3339e4b17023SJohn Marino /* Record the part after the last comma. */
3340e4b17023SJohn Marino add_assembler_option (arg + prev, j - prev);
3341e4b17023SJohn Marino }
3342e4b17023SJohn Marino do_save = false;
3343e4b17023SJohn Marino break;
3344e4b17023SJohn Marino
3345e4b17023SJohn Marino case OPT_Wp_:
3346e4b17023SJohn Marino {
3347e4b17023SJohn Marino int prev, j;
3348e4b17023SJohn Marino /* Pass the rest of this option to the preprocessor. */
3349e4b17023SJohn Marino
3350e4b17023SJohn Marino /* Split the argument at commas. */
3351e4b17023SJohn Marino prev = 0;
3352e4b17023SJohn Marino for (j = 0; arg[j]; j++)
3353e4b17023SJohn Marino if (arg[j] == ',')
3354e4b17023SJohn Marino {
3355e4b17023SJohn Marino add_preprocessor_option (arg + prev, j - prev);
3356e4b17023SJohn Marino prev = j + 1;
3357e4b17023SJohn Marino }
3358e4b17023SJohn Marino
3359e4b17023SJohn Marino /* Record the part after the last comma. */
3360e4b17023SJohn Marino add_preprocessor_option (arg + prev, j - prev);
3361e4b17023SJohn Marino }
3362e4b17023SJohn Marino do_save = false;
3363e4b17023SJohn Marino break;
3364e4b17023SJohn Marino
3365e4b17023SJohn Marino case OPT_Wl_:
3366e4b17023SJohn Marino {
3367e4b17023SJohn Marino int prev, j;
3368e4b17023SJohn Marino /* Split the argument at commas. */
3369e4b17023SJohn Marino prev = 0;
3370e4b17023SJohn Marino for (j = 0; arg[j]; j++)
3371e4b17023SJohn Marino if (arg[j] == ',')
3372e4b17023SJohn Marino {
3373e4b17023SJohn Marino add_infile (save_string (arg + prev, j - prev), "*");
3374e4b17023SJohn Marino prev = j + 1;
3375e4b17023SJohn Marino }
3376e4b17023SJohn Marino /* Record the part after the last comma. */
3377e4b17023SJohn Marino add_infile (arg + prev, "*");
3378e4b17023SJohn Marino }
3379e4b17023SJohn Marino do_save = false;
3380e4b17023SJohn Marino break;
3381e4b17023SJohn Marino
3382e4b17023SJohn Marino case OPT_Xlinker:
3383e4b17023SJohn Marino add_infile (arg, "*");
3384e4b17023SJohn Marino do_save = false;
3385e4b17023SJohn Marino break;
3386e4b17023SJohn Marino
3387e4b17023SJohn Marino case OPT_Xpreprocessor:
3388e4b17023SJohn Marino add_preprocessor_option (arg, strlen (arg));
3389e4b17023SJohn Marino do_save = false;
3390e4b17023SJohn Marino break;
3391e4b17023SJohn Marino
3392e4b17023SJohn Marino case OPT_Xassembler:
3393e4b17023SJohn Marino add_assembler_option (arg, strlen (arg));
3394e4b17023SJohn Marino do_save = false;
3395e4b17023SJohn Marino break;
3396e4b17023SJohn Marino
3397e4b17023SJohn Marino case OPT_l:
3398e4b17023SJohn Marino /* POSIX allows separation of -l and the lib arg; canonicalize
3399e4b17023SJohn Marino by concatenating -l with its arg */
3400e4b17023SJohn Marino add_infile (concat ("-l", arg, NULL), "*");
3401e4b17023SJohn Marino do_save = false;
3402e4b17023SJohn Marino break;
3403e4b17023SJohn Marino
3404e4b17023SJohn Marino case OPT_L:
3405e4b17023SJohn Marino /* Similarly, canonicalize -L for linkers that may not accept
3406e4b17023SJohn Marino separate arguments. */
3407e4b17023SJohn Marino save_switch (concat ("-L", arg, NULL), 0, NULL, validated);
3408e4b17023SJohn Marino return true;
3409e4b17023SJohn Marino
3410e4b17023SJohn Marino case OPT_F:
3411e4b17023SJohn Marino /* Likewise -F. */
3412e4b17023SJohn Marino save_switch (concat ("-F", arg, NULL), 0, NULL, validated);
3413e4b17023SJohn Marino return true;
3414e4b17023SJohn Marino
3415e4b17023SJohn Marino case OPT_save_temps:
3416e4b17023SJohn Marino save_temps_flag = SAVE_TEMPS_CWD;
3417e4b17023SJohn Marino validated = true;
3418e4b17023SJohn Marino break;
3419e4b17023SJohn Marino
3420e4b17023SJohn Marino case OPT_save_temps_:
3421e4b17023SJohn Marino if (strcmp (arg, "cwd") == 0)
3422e4b17023SJohn Marino save_temps_flag = SAVE_TEMPS_CWD;
3423e4b17023SJohn Marino else if (strcmp (arg, "obj") == 0
3424e4b17023SJohn Marino || strcmp (arg, "object") == 0)
3425e4b17023SJohn Marino save_temps_flag = SAVE_TEMPS_OBJ;
3426*2bbc7733Szrj else if (strcmp (arg, "objects") == 0)
3427*2bbc7733Szrj save_temps_flag = SAVE_TEMPS_OBJZ;
3428e4b17023SJohn Marino else
3429e4b17023SJohn Marino fatal_error ("%qs is an unknown -save-temps option",
3430e4b17023SJohn Marino decoded->orig_option_with_args_text);
3431e4b17023SJohn Marino break;
3432e4b17023SJohn Marino
3433e4b17023SJohn Marino case OPT_no_canonical_prefixes:
3434e4b17023SJohn Marino /* Already handled as a special case, so ignored here. */
3435e4b17023SJohn Marino do_save = false;
3436e4b17023SJohn Marino break;
3437e4b17023SJohn Marino
3438e4b17023SJohn Marino case OPT_pipe:
3439e4b17023SJohn Marino validated = true;
3440e4b17023SJohn Marino /* These options set the variables specified in common.opt
3441e4b17023SJohn Marino automatically, but do need to be saved for spec
3442e4b17023SJohn Marino processing. */
3443e4b17023SJohn Marino break;
3444e4b17023SJohn Marino
3445e4b17023SJohn Marino case OPT_specs_:
3446e4b17023SJohn Marino {
3447e4b17023SJohn Marino struct user_specs *user = XNEW (struct user_specs);
3448e4b17023SJohn Marino
3449e4b17023SJohn Marino user->next = (struct user_specs *) 0;
3450e4b17023SJohn Marino user->filename = arg;
3451e4b17023SJohn Marino if (user_specs_tail)
3452e4b17023SJohn Marino user_specs_tail->next = user;
3453e4b17023SJohn Marino else
3454e4b17023SJohn Marino user_specs_head = user;
3455e4b17023SJohn Marino user_specs_tail = user;
3456e4b17023SJohn Marino }
3457e4b17023SJohn Marino do_save = false;
3458e4b17023SJohn Marino break;
3459e4b17023SJohn Marino
3460e4b17023SJohn Marino case OPT__sysroot_:
3461e4b17023SJohn Marino target_system_root = arg;
3462e4b17023SJohn Marino target_system_root_changed = 1;
3463e4b17023SJohn Marino do_save = false;
3464e4b17023SJohn Marino break;
3465e4b17023SJohn Marino
3466e4b17023SJohn Marino case OPT_time_:
3467e4b17023SJohn Marino if (report_times_to_file)
3468e4b17023SJohn Marino fclose (report_times_to_file);
3469e4b17023SJohn Marino report_times_to_file = fopen (arg, "a");
3470e4b17023SJohn Marino do_save = false;
3471e4b17023SJohn Marino break;
3472e4b17023SJohn Marino
3473e4b17023SJohn Marino case OPT____:
3474e4b17023SJohn Marino /* "-###"
3475e4b17023SJohn Marino This is similar to -v except that there is no execution
3476e4b17023SJohn Marino of the commands and the echoed arguments are quoted. It
3477e4b17023SJohn Marino is intended for use in shell scripts to capture the
3478e4b17023SJohn Marino driver-generated command line. */
3479e4b17023SJohn Marino verbose_only_flag++;
3480e4b17023SJohn Marino verbose_flag = 1;
3481e4b17023SJohn Marino do_save = false;
3482e4b17023SJohn Marino break;
3483e4b17023SJohn Marino
3484e4b17023SJohn Marino case OPT_B:
3485e4b17023SJohn Marino {
3486e4b17023SJohn Marino size_t len = strlen (arg);
3487e4b17023SJohn Marino
3488e4b17023SJohn Marino /* Catch the case where the user has forgotten to append a
3489e4b17023SJohn Marino directory separator to the path. Note, they may be using
3490e4b17023SJohn Marino -B to add an executable name prefix, eg "i386-elf-", in
3491e4b17023SJohn Marino order to distinguish between multiple installations of
3492e4b17023SJohn Marino GCC in the same directory. Hence we must check to see
3493e4b17023SJohn Marino if appending a directory separator actually makes a
3494e4b17023SJohn Marino valid directory name. */
3495e4b17023SJohn Marino if (!IS_DIR_SEPARATOR (arg[len - 1])
3496e4b17023SJohn Marino && is_directory (arg, false))
3497e4b17023SJohn Marino {
3498e4b17023SJohn Marino char *tmp = XNEWVEC (char, len + 2);
3499e4b17023SJohn Marino strcpy (tmp, arg);
3500e4b17023SJohn Marino tmp[len] = DIR_SEPARATOR;
3501e4b17023SJohn Marino tmp[++len] = 0;
3502e4b17023SJohn Marino arg = tmp;
3503e4b17023SJohn Marino }
3504e4b17023SJohn Marino
3505e4b17023SJohn Marino add_prefix (&exec_prefixes, arg, NULL,
3506e4b17023SJohn Marino PREFIX_PRIORITY_B_OPT, 0, 0);
3507e4b17023SJohn Marino add_prefix (&startfile_prefixes, arg, NULL,
3508e4b17023SJohn Marino PREFIX_PRIORITY_B_OPT, 0, 0);
3509e4b17023SJohn Marino add_prefix (&include_prefixes, arg, NULL,
3510e4b17023SJohn Marino PREFIX_PRIORITY_B_OPT, 0, 0);
3511e4b17023SJohn Marino }
3512e4b17023SJohn Marino validated = true;
3513e4b17023SJohn Marino break;
3514e4b17023SJohn Marino
3515e4b17023SJohn Marino case OPT_x:
3516e4b17023SJohn Marino spec_lang = arg;
3517e4b17023SJohn Marino if (!strcmp (spec_lang, "none"))
3518e4b17023SJohn Marino /* Suppress the warning if -xnone comes after the last input
3519e4b17023SJohn Marino file, because alternate command interfaces like g++ might
3520e4b17023SJohn Marino find it useful to place -xnone after each input file. */
3521e4b17023SJohn Marino spec_lang = 0;
3522e4b17023SJohn Marino else
3523e4b17023SJohn Marino last_language_n_infiles = n_infiles;
3524e4b17023SJohn Marino do_save = false;
3525e4b17023SJohn Marino break;
3526e4b17023SJohn Marino
3527e4b17023SJohn Marino case OPT_o:
3528e4b17023SJohn Marino have_o = 1;
3529e4b17023SJohn Marino #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
3530e4b17023SJohn Marino arg = convert_filename (arg, ! have_c, 0);
3531e4b17023SJohn Marino #endif
3532e4b17023SJohn Marino /* Save the output name in case -save-temps=obj was used. */
3533e4b17023SJohn Marino save_temps_prefix = xstrdup (arg);
3534e4b17023SJohn Marino /* On some systems, ld cannot handle "-o" without a space. So
3535e4b17023SJohn Marino split the option from its argument. */
3536e4b17023SJohn Marino save_switch ("-o", 1, &arg, validated);
3537e4b17023SJohn Marino return true;
3538e4b17023SJohn Marino
3539e4b17023SJohn Marino case OPT_static_libgcc:
3540e4b17023SJohn Marino case OPT_shared_libgcc:
3541e4b17023SJohn Marino case OPT_static_libgfortran:
3542e4b17023SJohn Marino case OPT_static_libstdc__:
3543e4b17023SJohn Marino /* These are always valid, since gcc.c itself understands the
3544e4b17023SJohn Marino first two, gfortranspec.c understands -static-libgfortran and
3545e4b17023SJohn Marino g++spec.c understands -static-libstdc++ */
3546e4b17023SJohn Marino validated = true;
3547e4b17023SJohn Marino break;
3548e4b17023SJohn Marino
3549e4b17023SJohn Marino default:
3550e4b17023SJohn Marino /* Various driver options need no special processing at this
3551e4b17023SJohn Marino point, having been handled in a prescan above or being
3552e4b17023SJohn Marino handled by specs. */
3553e4b17023SJohn Marino break;
3554e4b17023SJohn Marino }
3555e4b17023SJohn Marino
3556e4b17023SJohn Marino if (do_save)
3557e4b17023SJohn Marino save_switch (decoded->canonical_option[0],
3558e4b17023SJohn Marino decoded->canonical_option_num_elements - 1,
3559e4b17023SJohn Marino &decoded->canonical_option[1], validated);
3560e4b17023SJohn Marino return true;
3561e4b17023SJohn Marino }
3562e4b17023SJohn Marino
3563e4b17023SJohn Marino /* Put the driver's standard set of option handlers in *HANDLERS. */
3564e4b17023SJohn Marino
3565e4b17023SJohn Marino static void
set_option_handlers(struct cl_option_handlers * handlers)3566e4b17023SJohn Marino set_option_handlers (struct cl_option_handlers *handlers)
3567e4b17023SJohn Marino {
3568e4b17023SJohn Marino handlers->unknown_option_callback = driver_unknown_option_callback;
3569e4b17023SJohn Marino handlers->wrong_lang_callback = driver_wrong_lang_callback;
3570e4b17023SJohn Marino handlers->num_handlers = 3;
3571e4b17023SJohn Marino handlers->handlers[0].handler = driver_handle_option;
3572e4b17023SJohn Marino handlers->handlers[0].mask = CL_DRIVER;
3573e4b17023SJohn Marino handlers->handlers[1].handler = common_handle_option;
3574e4b17023SJohn Marino handlers->handlers[1].mask = CL_COMMON;
3575e4b17023SJohn Marino handlers->handlers[2].handler = target_handle_option;
3576e4b17023SJohn Marino handlers->handlers[2].mask = CL_TARGET;
3577e4b17023SJohn Marino }
3578e4b17023SJohn Marino
3579e4b17023SJohn Marino /* Create the vector `switches' and its contents.
3580e4b17023SJohn Marino Store its length in `n_switches'. */
3581e4b17023SJohn Marino
3582e4b17023SJohn Marino static void
process_command(unsigned int decoded_options_count,struct cl_decoded_option * decoded_options)3583e4b17023SJohn Marino process_command (unsigned int decoded_options_count,
3584e4b17023SJohn Marino struct cl_decoded_option *decoded_options)
3585e4b17023SJohn Marino {
3586e4b17023SJohn Marino const char *temp;
3587e4b17023SJohn Marino char *temp1;
3588e4b17023SJohn Marino const char *tooldir_prefix;
3589e4b17023SJohn Marino char *(*get_relative_prefix) (const char *, const char *,
3590e4b17023SJohn Marino const char *) = NULL;
3591e4b17023SJohn Marino struct cl_option_handlers handlers;
3592e4b17023SJohn Marino unsigned int j;
3593e4b17023SJohn Marino
3594e4b17023SJohn Marino gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX");
3595e4b17023SJohn Marino
3596e4b17023SJohn Marino n_switches = 0;
3597e4b17023SJohn Marino n_infiles = 0;
3598e4b17023SJohn Marino added_libraries = 0;
3599e4b17023SJohn Marino
3600e4b17023SJohn Marino /* Figure compiler version from version string. */
3601e4b17023SJohn Marino
3602e4b17023SJohn Marino compiler_version = temp1 = xstrdup (version_string);
3603e4b17023SJohn Marino
3604e4b17023SJohn Marino for (; *temp1; ++temp1)
3605e4b17023SJohn Marino {
3606e4b17023SJohn Marino if (*temp1 == ' ')
3607e4b17023SJohn Marino {
3608e4b17023SJohn Marino *temp1 = '\0';
3609e4b17023SJohn Marino break;
3610e4b17023SJohn Marino }
3611e4b17023SJohn Marino }
3612e4b17023SJohn Marino
3613e4b17023SJohn Marino /* Handle any -no-canonical-prefixes flag early, to assign the function
3614e4b17023SJohn Marino that builds relative prefixes. This function creates default search
3615e4b17023SJohn Marino paths that are needed later in normal option handling. */
3616e4b17023SJohn Marino
3617e4b17023SJohn Marino for (j = 1; j < decoded_options_count; j++)
3618e4b17023SJohn Marino {
3619e4b17023SJohn Marino if (decoded_options[j].opt_index == OPT_no_canonical_prefixes)
3620e4b17023SJohn Marino {
3621e4b17023SJohn Marino get_relative_prefix = make_relative_prefix_ignore_links;
3622e4b17023SJohn Marino break;
3623e4b17023SJohn Marino }
3624e4b17023SJohn Marino }
3625e4b17023SJohn Marino if (! get_relative_prefix)
3626e4b17023SJohn Marino get_relative_prefix = make_relative_prefix;
3627e4b17023SJohn Marino
3628e4b17023SJohn Marino /* Set up the default search paths. If there is no GCC_EXEC_PREFIX,
3629e4b17023SJohn Marino see if we can create it from the pathname specified in
3630e4b17023SJohn Marino decoded_options[0].arg. */
3631e4b17023SJohn Marino
3632e4b17023SJohn Marino gcc_libexec_prefix = standard_libexec_prefix;
3633e4b17023SJohn Marino #ifndef VMS
3634e4b17023SJohn Marino /* FIXME: make_relative_prefix doesn't yet work for VMS. */
3635e4b17023SJohn Marino if (!gcc_exec_prefix)
3636e4b17023SJohn Marino {
3637fdc4107cSJohn Marino #if 0 /* Never use relative prefix (not bootstrapped) */
3638e4b17023SJohn Marino gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg,
3639e4b17023SJohn Marino standard_bindir_prefix,
3640e4b17023SJohn Marino standard_exec_prefix);
3641e4b17023SJohn Marino gcc_libexec_prefix = get_relative_prefix (decoded_options[0].arg,
3642e4b17023SJohn Marino standard_bindir_prefix,
3643e4b17023SJohn Marino standard_libexec_prefix);
3644e4b17023SJohn Marino if (gcc_exec_prefix)
3645e4b17023SJohn Marino xputenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
3646fdc4107cSJohn Marino #endif
3647e4b17023SJohn Marino }
3648e4b17023SJohn Marino else
3649e4b17023SJohn Marino {
3650e4b17023SJohn Marino /* make_relative_prefix requires a program name, but
3651e4b17023SJohn Marino GCC_EXEC_PREFIX is typically a directory name with a trailing
3652e4b17023SJohn Marino / (which is ignored by make_relative_prefix), so append a
3653e4b17023SJohn Marino program name. */
3654e4b17023SJohn Marino char *tmp_prefix = concat (gcc_exec_prefix, "gcc", NULL);
3655e4b17023SJohn Marino gcc_libexec_prefix = get_relative_prefix (tmp_prefix,
3656e4b17023SJohn Marino standard_exec_prefix,
3657e4b17023SJohn Marino standard_libexec_prefix);
3658e4b17023SJohn Marino
3659e4b17023SJohn Marino /* The path is unrelocated, so fallback to the original setting. */
3660e4b17023SJohn Marino if (!gcc_libexec_prefix)
3661e4b17023SJohn Marino gcc_libexec_prefix = standard_libexec_prefix;
3662e4b17023SJohn Marino
3663e4b17023SJohn Marino free (tmp_prefix);
3664e4b17023SJohn Marino }
3665e4b17023SJohn Marino #else
3666e4b17023SJohn Marino #endif
3667e4b17023SJohn Marino /* From this point onward, gcc_exec_prefix is non-null if the toolchain
3668e4b17023SJohn Marino is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX
3669e4b17023SJohn Marino or an automatically created GCC_EXEC_PREFIX from
3670e4b17023SJohn Marino decoded_options[0].arg. */
3671e4b17023SJohn Marino
3672e4b17023SJohn Marino /* Do language-specific adjustment/addition of flags. */
3673e4b17023SJohn Marino lang_specific_driver (&decoded_options, &decoded_options_count,
3674e4b17023SJohn Marino &added_libraries);
3675e4b17023SJohn Marino
3676e4b17023SJohn Marino if (gcc_exec_prefix)
3677e4b17023SJohn Marino {
3678e4b17023SJohn Marino int len = strlen (gcc_exec_prefix);
3679e4b17023SJohn Marino
3680e4b17023SJohn Marino if (len > (int) sizeof ("/lib/gcc/") - 1
3681e4b17023SJohn Marino && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
3682e4b17023SJohn Marino {
3683e4b17023SJohn Marino temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
3684e4b17023SJohn Marino if (IS_DIR_SEPARATOR (*temp)
3685e4b17023SJohn Marino && filename_ncmp (temp + 1, "lib", 3) == 0
3686e4b17023SJohn Marino && IS_DIR_SEPARATOR (temp[4])
3687e4b17023SJohn Marino && filename_ncmp (temp + 5, "gcc", 3) == 0)
3688e4b17023SJohn Marino len -= sizeof ("/lib/gcc/") - 1;
3689e4b17023SJohn Marino }
3690e4b17023SJohn Marino
3691fdc4107cSJohn Marino #if 0 /* Bad Paths */
3692e4b17023SJohn Marino set_std_prefix (gcc_exec_prefix, len);
3693e4b17023SJohn Marino add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
3694e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 0);
3695e4b17023SJohn Marino add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
3696e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 0);
3697fdc4107cSJohn Marino #endif
3698e4b17023SJohn Marino }
3699e4b17023SJohn Marino
3700e4b17023SJohn Marino /* COMPILER_PATH and LIBRARY_PATH have values
3701e4b17023SJohn Marino that are lists of directory names with colons. */
3702e4b17023SJohn Marino
3703e4b17023SJohn Marino temp = getenv ("COMPILER_PATH");
3704e4b17023SJohn Marino if (temp)
3705e4b17023SJohn Marino {
3706e4b17023SJohn Marino const char *startp, *endp;
3707e4b17023SJohn Marino char *nstore = (char *) alloca (strlen (temp) + 3);
3708e4b17023SJohn Marino
3709e4b17023SJohn Marino startp = endp = temp;
3710e4b17023SJohn Marino while (1)
3711e4b17023SJohn Marino {
3712e4b17023SJohn Marino if (*endp == PATH_SEPARATOR || *endp == 0)
3713e4b17023SJohn Marino {
3714e4b17023SJohn Marino strncpy (nstore, startp, endp - startp);
3715e4b17023SJohn Marino if (endp == startp)
3716e4b17023SJohn Marino strcpy (nstore, concat (".", dir_separator_str, NULL));
3717e4b17023SJohn Marino else if (!IS_DIR_SEPARATOR (endp[-1]))
3718e4b17023SJohn Marino {
3719e4b17023SJohn Marino nstore[endp - startp] = DIR_SEPARATOR;
3720e4b17023SJohn Marino nstore[endp - startp + 1] = 0;
3721e4b17023SJohn Marino }
3722e4b17023SJohn Marino else
3723e4b17023SJohn Marino nstore[endp - startp] = 0;
3724e4b17023SJohn Marino add_prefix (&exec_prefixes, nstore, 0,
3725e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 0);
3726e4b17023SJohn Marino add_prefix (&include_prefixes, nstore, 0,
3727e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 0);
3728e4b17023SJohn Marino if (*endp == 0)
3729e4b17023SJohn Marino break;
3730e4b17023SJohn Marino endp = startp = endp + 1;
3731e4b17023SJohn Marino }
3732e4b17023SJohn Marino else
3733e4b17023SJohn Marino endp++;
3734e4b17023SJohn Marino }
3735e4b17023SJohn Marino }
3736e4b17023SJohn Marino
3737e4b17023SJohn Marino temp = getenv (LIBRARY_PATH_ENV);
3738e4b17023SJohn Marino if (temp && *cross_compile == '0')
3739e4b17023SJohn Marino {
3740e4b17023SJohn Marino const char *startp, *endp;
3741e4b17023SJohn Marino char *nstore = (char *) alloca (strlen (temp) + 3);
3742e4b17023SJohn Marino
3743e4b17023SJohn Marino startp = endp = temp;
3744e4b17023SJohn Marino while (1)
3745e4b17023SJohn Marino {
3746e4b17023SJohn Marino if (*endp == PATH_SEPARATOR || *endp == 0)
3747e4b17023SJohn Marino {
3748e4b17023SJohn Marino strncpy (nstore, startp, endp - startp);
3749e4b17023SJohn Marino if (endp == startp)
3750e4b17023SJohn Marino strcpy (nstore, concat (".", dir_separator_str, NULL));
3751e4b17023SJohn Marino else if (!IS_DIR_SEPARATOR (endp[-1]))
3752e4b17023SJohn Marino {
3753e4b17023SJohn Marino nstore[endp - startp] = DIR_SEPARATOR;
3754e4b17023SJohn Marino nstore[endp - startp + 1] = 0;
3755e4b17023SJohn Marino }
3756e4b17023SJohn Marino else
3757e4b17023SJohn Marino nstore[endp - startp] = 0;
3758e4b17023SJohn Marino add_prefix (&startfile_prefixes, nstore, NULL,
3759e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 1);
3760e4b17023SJohn Marino if (*endp == 0)
3761e4b17023SJohn Marino break;
3762e4b17023SJohn Marino endp = startp = endp + 1;
3763e4b17023SJohn Marino }
3764e4b17023SJohn Marino else
3765e4b17023SJohn Marino endp++;
3766e4b17023SJohn Marino }
3767e4b17023SJohn Marino }
3768e4b17023SJohn Marino
3769e4b17023SJohn Marino /* Use LPATH like LIBRARY_PATH (for the CMU build program). */
3770e4b17023SJohn Marino temp = getenv ("LPATH");
3771e4b17023SJohn Marino if (temp && *cross_compile == '0')
3772e4b17023SJohn Marino {
3773e4b17023SJohn Marino const char *startp, *endp;
3774e4b17023SJohn Marino char *nstore = (char *) alloca (strlen (temp) + 3);
3775e4b17023SJohn Marino
3776e4b17023SJohn Marino startp = endp = temp;
3777e4b17023SJohn Marino while (1)
3778e4b17023SJohn Marino {
3779e4b17023SJohn Marino if (*endp == PATH_SEPARATOR || *endp == 0)
3780e4b17023SJohn Marino {
3781e4b17023SJohn Marino strncpy (nstore, startp, endp - startp);
3782e4b17023SJohn Marino if (endp == startp)
3783e4b17023SJohn Marino strcpy (nstore, concat (".", dir_separator_str, NULL));
3784e4b17023SJohn Marino else if (!IS_DIR_SEPARATOR (endp[-1]))
3785e4b17023SJohn Marino {
3786e4b17023SJohn Marino nstore[endp - startp] = DIR_SEPARATOR;
3787e4b17023SJohn Marino nstore[endp - startp + 1] = 0;
3788e4b17023SJohn Marino }
3789e4b17023SJohn Marino else
3790e4b17023SJohn Marino nstore[endp - startp] = 0;
3791e4b17023SJohn Marino add_prefix (&startfile_prefixes, nstore, NULL,
3792e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 1);
3793e4b17023SJohn Marino if (*endp == 0)
3794e4b17023SJohn Marino break;
3795e4b17023SJohn Marino endp = startp = endp + 1;
3796e4b17023SJohn Marino }
3797e4b17023SJohn Marino else
3798e4b17023SJohn Marino endp++;
3799e4b17023SJohn Marino }
3800e4b17023SJohn Marino }
3801e4b17023SJohn Marino
3802e4b17023SJohn Marino /* Process the options and store input files and switches in their
3803e4b17023SJohn Marino vectors. */
3804e4b17023SJohn Marino
3805e4b17023SJohn Marino last_language_n_infiles = -1;
3806e4b17023SJohn Marino
3807e4b17023SJohn Marino set_option_handlers (&handlers);
3808e4b17023SJohn Marino
3809e4b17023SJohn Marino for (j = 1; j < decoded_options_count; j++)
3810e4b17023SJohn Marino {
3811e4b17023SJohn Marino switch (decoded_options[j].opt_index)
3812e4b17023SJohn Marino {
3813e4b17023SJohn Marino case OPT_S:
3814e4b17023SJohn Marino case OPT_c:
3815e4b17023SJohn Marino case OPT_E:
3816e4b17023SJohn Marino have_c = 1;
3817e4b17023SJohn Marino break;
3818e4b17023SJohn Marino }
3819e4b17023SJohn Marino if (have_c)
3820e4b17023SJohn Marino break;
3821e4b17023SJohn Marino }
3822e4b17023SJohn Marino
3823e4b17023SJohn Marino for (j = 1; j < decoded_options_count; j++)
3824e4b17023SJohn Marino {
3825e4b17023SJohn Marino if (decoded_options[j].opt_index == OPT_SPECIAL_input_file)
3826e4b17023SJohn Marino {
3827e4b17023SJohn Marino const char *arg = decoded_options[j].arg;
3828e4b17023SJohn Marino const char *p = strrchr (arg, '@');
3829e4b17023SJohn Marino char *fname;
3830e4b17023SJohn Marino long offset;
3831e4b17023SJohn Marino int consumed;
3832e4b17023SJohn Marino #ifdef HAVE_TARGET_OBJECT_SUFFIX
3833e4b17023SJohn Marino arg = convert_filename (arg, 0, access (arg, F_OK));
3834e4b17023SJohn Marino #endif
3835e4b17023SJohn Marino /* For LTO static archive support we handle input file
3836e4b17023SJohn Marino specifications that are composed of a filename and
3837e4b17023SJohn Marino an offset like FNAME@OFFSET. */
3838e4b17023SJohn Marino if (p
3839e4b17023SJohn Marino && p != arg
3840e4b17023SJohn Marino && sscanf (p, "@%li%n", &offset, &consumed) >= 1
3841e4b17023SJohn Marino && strlen (p) == (unsigned int)consumed)
3842e4b17023SJohn Marino {
3843e4b17023SJohn Marino fname = (char *)xmalloc (p - arg + 1);
3844e4b17023SJohn Marino memcpy (fname, arg, p - arg);
3845e4b17023SJohn Marino fname[p - arg] = '\0';
3846e4b17023SJohn Marino /* Only accept non-stdin and existing FNAME parts, otherwise
3847e4b17023SJohn Marino try with the full name. */
3848e4b17023SJohn Marino if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0)
3849e4b17023SJohn Marino {
3850e4b17023SJohn Marino free (fname);
3851e4b17023SJohn Marino fname = xstrdup (arg);
3852e4b17023SJohn Marino }
3853e4b17023SJohn Marino }
3854e4b17023SJohn Marino else
3855e4b17023SJohn Marino fname = xstrdup (arg);
3856e4b17023SJohn Marino
3857e4b17023SJohn Marino if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
3858e4b17023SJohn Marino perror_with_name (fname);
3859e4b17023SJohn Marino else
3860e4b17023SJohn Marino add_infile (arg, spec_lang);
3861e4b17023SJohn Marino
3862e4b17023SJohn Marino free (fname);
3863e4b17023SJohn Marino continue;
3864e4b17023SJohn Marino }
3865e4b17023SJohn Marino
3866e4b17023SJohn Marino read_cmdline_option (&global_options, &global_options_set,
3867e4b17023SJohn Marino decoded_options + j, UNKNOWN_LOCATION,
3868e4b17023SJohn Marino CL_DRIVER, &handlers, global_dc);
3869e4b17023SJohn Marino }
3870e4b17023SJohn Marino
3871e4b17023SJohn Marino /* If -save-temps=obj and -o name, create the prefix to use for %b.
3872e4b17023SJohn Marino Otherwise just make -save-temps=obj the same as -save-temps=cwd. */
3873e4b17023SJohn Marino if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL)
3874e4b17023SJohn Marino {
3875e4b17023SJohn Marino save_temps_length = strlen (save_temps_prefix);
3876e4b17023SJohn Marino temp = strrchr (lbasename (save_temps_prefix), '.');
3877e4b17023SJohn Marino if (temp)
3878e4b17023SJohn Marino {
3879e4b17023SJohn Marino save_temps_length -= strlen (temp);
3880e4b17023SJohn Marino save_temps_prefix[save_temps_length] = '\0';
3881e4b17023SJohn Marino }
3882e4b17023SJohn Marino
3883e4b17023SJohn Marino }
3884*2bbc7733Szrj else if (save_temps_flag == SAVE_TEMPS_OBJZ && save_temps_prefix != NULL)
3885*2bbc7733Szrj {
3886*2bbc7733Szrj save_temps_length = strlen (save_temps_prefix);
3887*2bbc7733Szrj }
3888e4b17023SJohn Marino else if (save_temps_prefix != NULL)
3889e4b17023SJohn Marino {
3890e4b17023SJohn Marino free (save_temps_prefix);
3891e4b17023SJohn Marino save_temps_prefix = NULL;
3892e4b17023SJohn Marino }
3893e4b17023SJohn Marino
3894e4b17023SJohn Marino if (save_temps_flag && use_pipes)
3895e4b17023SJohn Marino {
3896e4b17023SJohn Marino /* -save-temps overrides -pipe, so that temp files are produced */
3897e4b17023SJohn Marino if (save_temps_flag)
3898e4b17023SJohn Marino warning (0, "-pipe ignored because -save-temps specified");
3899e4b17023SJohn Marino use_pipes = 0;
3900e4b17023SJohn Marino }
3901e4b17023SJohn Marino
3902e4b17023SJohn Marino if (!compare_debug)
3903e4b17023SJohn Marino {
3904e4b17023SJohn Marino const char *gcd = getenv ("GCC_COMPARE_DEBUG");
3905e4b17023SJohn Marino
3906e4b17023SJohn Marino if (gcd && gcd[0] == '-')
3907e4b17023SJohn Marino {
3908e4b17023SJohn Marino compare_debug = 2;
3909e4b17023SJohn Marino compare_debug_opt = gcd;
3910e4b17023SJohn Marino }
3911e4b17023SJohn Marino else if (gcd && *gcd && strcmp (gcd, "0"))
3912e4b17023SJohn Marino {
3913e4b17023SJohn Marino compare_debug = 3;
3914e4b17023SJohn Marino compare_debug_opt = "-gtoggle";
3915e4b17023SJohn Marino }
3916e4b17023SJohn Marino }
3917e4b17023SJohn Marino else if (compare_debug < 0)
3918e4b17023SJohn Marino {
3919e4b17023SJohn Marino compare_debug = 0;
3920e4b17023SJohn Marino gcc_assert (!compare_debug_opt);
3921e4b17023SJohn Marino }
3922e4b17023SJohn Marino
3923e4b17023SJohn Marino /* Set up the search paths. We add directories that we expect to
3924e4b17023SJohn Marino contain GNU Toolchain components before directories specified by
3925e4b17023SJohn Marino the machine description so that we will find GNU components (like
3926e4b17023SJohn Marino the GNU assembler) before those of the host system. */
3927e4b17023SJohn Marino
3928e4b17023SJohn Marino /* If we don't know where the toolchain has been installed, use the
3929e4b17023SJohn Marino configured-in locations. */
3930e4b17023SJohn Marino if (!gcc_exec_prefix)
3931e4b17023SJohn Marino {
3932e4b17023SJohn Marino #ifndef OS2
3933fdc4107cSJohn Marino add_prefix (&exec_prefixes, standard_libexec_prefix, NULL,
3934fdc4107cSJohn Marino PREFIX_PRIORITY_LAST, 0, 0);
3935fdc4107cSJohn Marino #if 0 /* Bad paths */
3936e4b17023SJohn Marino add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
3937e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 1, 0);
3938e4b17023SJohn Marino add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
3939e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 2, 0);
3940e4b17023SJohn Marino add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
3941e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 2, 0);
3942e4b17023SJohn Marino #endif
3943fdc4107cSJohn Marino #endif
3944fdc4107cSJohn Marino #if 0 /* Bad paths */
3945e4b17023SJohn Marino add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
3946e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 1, 0);
3947fdc4107cSJohn Marino #endif
3948e4b17023SJohn Marino }
3949e4b17023SJohn Marino
3950e4b17023SJohn Marino gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
3951e4b17023SJohn Marino tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
3952e4b17023SJohn Marino dir_separator_str, NULL);
3953e4b17023SJohn Marino
3954e4b17023SJohn Marino /* Look for tools relative to the location from which the driver is
3955e4b17023SJohn Marino running, or, if that is not available, the configured prefix. */
3956e4b17023SJohn Marino tooldir_prefix
3957e4b17023SJohn Marino = concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
3958e4b17023SJohn Marino spec_machine, dir_separator_str,
3959e4b17023SJohn Marino spec_version, dir_separator_str, tooldir_prefix, NULL);
3960e4b17023SJohn Marino
3961fdc4107cSJohn Marino #if 0 /* Bad paths */
3962e4b17023SJohn Marino add_prefix (&exec_prefixes,
3963e4b17023SJohn Marino concat (tooldir_prefix, "bin", dir_separator_str, NULL),
3964e4b17023SJohn Marino "BINUTILS", PREFIX_PRIORITY_LAST, 0, 0);
3965e4b17023SJohn Marino add_prefix (&startfile_prefixes,
3966e4b17023SJohn Marino concat (tooldir_prefix, "lib", dir_separator_str, NULL),
3967e4b17023SJohn Marino "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
3968fdc4107cSJohn Marino #endif
3969e4b17023SJohn Marino
3970e4b17023SJohn Marino #if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
3971e4b17023SJohn Marino /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
3972e4b17023SJohn Marino then consider it to relocate with the rest of the GCC installation
3973e4b17023SJohn Marino if GCC_EXEC_PREFIX is set.
3974e4b17023SJohn Marino ``make_relative_prefix'' is not compiled for VMS, so don't call it. */
3975e4b17023SJohn Marino if (target_system_root && !target_system_root_changed && gcc_exec_prefix)
3976e4b17023SJohn Marino {
3977e4b17023SJohn Marino char *tmp_prefix = get_relative_prefix (decoded_options[0].arg,
3978e4b17023SJohn Marino standard_bindir_prefix,
3979e4b17023SJohn Marino target_system_root);
3980e4b17023SJohn Marino if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
3981e4b17023SJohn Marino {
3982e4b17023SJohn Marino target_system_root = tmp_prefix;
3983e4b17023SJohn Marino target_system_root_changed = 1;
3984e4b17023SJohn Marino }
3985e4b17023SJohn Marino }
3986e4b17023SJohn Marino #endif
3987e4b17023SJohn Marino
3988e4b17023SJohn Marino /* More prefixes are enabled in main, after we read the specs file
3989e4b17023SJohn Marino and determine whether this is cross-compilation or not. */
3990e4b17023SJohn Marino
3991e4b17023SJohn Marino if (n_infiles == last_language_n_infiles && spec_lang != 0)
3992e4b17023SJohn Marino warning (0, "%<-x %s%> after last input file has no effect", spec_lang);
3993e4b17023SJohn Marino
3994e4b17023SJohn Marino if (compare_debug == 2 || compare_debug == 3)
3995e4b17023SJohn Marino {
3996e4b17023SJohn Marino alloc_switch ();
3997e4b17023SJohn Marino switches[n_switches].part1 = concat ("fcompare-debug=",
3998e4b17023SJohn Marino compare_debug_opt,
3999e4b17023SJohn Marino NULL);
4000e4b17023SJohn Marino switches[n_switches].args = 0;
4001e4b17023SJohn Marino switches[n_switches].live_cond = 0;
4002e4b17023SJohn Marino switches[n_switches].validated = 0;
4003e4b17023SJohn Marino switches[n_switches].ordering = 0;
4004e4b17023SJohn Marino n_switches++;
4005e4b17023SJohn Marino compare_debug = 1;
4006e4b17023SJohn Marino }
4007e4b17023SJohn Marino
4008e4b17023SJohn Marino /* Ensure we only invoke each subprocess once. */
4009e4b17023SJohn Marino if (print_subprocess_help || print_help_list || print_version)
4010e4b17023SJohn Marino {
4011e4b17023SJohn Marino n_infiles = 0;
4012e4b17023SJohn Marino
4013e4b17023SJohn Marino /* Create a dummy input file, so that we can pass
4014e4b17023SJohn Marino the help option on to the various sub-processes. */
4015e4b17023SJohn Marino add_infile ("help-dummy", "c");
4016e4b17023SJohn Marino }
4017e4b17023SJohn Marino
4018e4b17023SJohn Marino alloc_switch ();
4019e4b17023SJohn Marino switches[n_switches].part1 = 0;
4020e4b17023SJohn Marino alloc_infile ();
4021e4b17023SJohn Marino infiles[n_infiles].name = 0;
4022e4b17023SJohn Marino }
4023e4b17023SJohn Marino
4024e4b17023SJohn Marino /* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
4025e4b17023SJohn Marino and place that in the environment. */
4026e4b17023SJohn Marino
4027e4b17023SJohn Marino static void
set_collect_gcc_options(void)4028e4b17023SJohn Marino set_collect_gcc_options (void)
4029e4b17023SJohn Marino {
4030e4b17023SJohn Marino int i;
4031e4b17023SJohn Marino int first_time;
4032e4b17023SJohn Marino
4033e4b17023SJohn Marino /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
4034e4b17023SJohn Marino the compiler. */
4035e4b17023SJohn Marino obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
4036e4b17023SJohn Marino sizeof ("COLLECT_GCC_OPTIONS=") - 1);
4037e4b17023SJohn Marino
4038e4b17023SJohn Marino first_time = TRUE;
4039e4b17023SJohn Marino for (i = 0; (int) i < n_switches; i++)
4040e4b17023SJohn Marino {
4041e4b17023SJohn Marino const char *const *args;
4042e4b17023SJohn Marino const char *p, *q;
4043e4b17023SJohn Marino if (!first_time)
4044e4b17023SJohn Marino obstack_grow (&collect_obstack, " ", 1);
4045e4b17023SJohn Marino
4046e4b17023SJohn Marino first_time = FALSE;
4047e4b17023SJohn Marino
4048e4b17023SJohn Marino /* Ignore elided switches. */
4049e4b17023SJohn Marino if ((switches[i].live_cond
4050e4b17023SJohn Marino & (SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC))
4051e4b17023SJohn Marino == SWITCH_IGNORE)
4052e4b17023SJohn Marino continue;
4053e4b17023SJohn Marino
4054e4b17023SJohn Marino obstack_grow (&collect_obstack, "'-", 2);
4055e4b17023SJohn Marino q = switches[i].part1;
4056e4b17023SJohn Marino while ((p = strchr (q, '\'')))
4057e4b17023SJohn Marino {
4058e4b17023SJohn Marino obstack_grow (&collect_obstack, q, p - q);
4059e4b17023SJohn Marino obstack_grow (&collect_obstack, "'\\''", 4);
4060e4b17023SJohn Marino q = ++p;
4061e4b17023SJohn Marino }
4062e4b17023SJohn Marino obstack_grow (&collect_obstack, q, strlen (q));
4063e4b17023SJohn Marino obstack_grow (&collect_obstack, "'", 1);
4064e4b17023SJohn Marino
4065e4b17023SJohn Marino for (args = switches[i].args; args && *args; args++)
4066e4b17023SJohn Marino {
4067e4b17023SJohn Marino obstack_grow (&collect_obstack, " '", 2);
4068e4b17023SJohn Marino q = *args;
4069e4b17023SJohn Marino while ((p = strchr (q, '\'')))
4070e4b17023SJohn Marino {
4071e4b17023SJohn Marino obstack_grow (&collect_obstack, q, p - q);
4072e4b17023SJohn Marino obstack_grow (&collect_obstack, "'\\''", 4);
4073e4b17023SJohn Marino q = ++p;
4074e4b17023SJohn Marino }
4075e4b17023SJohn Marino obstack_grow (&collect_obstack, q, strlen (q));
4076e4b17023SJohn Marino obstack_grow (&collect_obstack, "'", 1);
4077e4b17023SJohn Marino }
4078e4b17023SJohn Marino }
4079e4b17023SJohn Marino obstack_grow (&collect_obstack, "\0", 1);
4080e4b17023SJohn Marino xputenv (XOBFINISH (&collect_obstack, char *));
4081e4b17023SJohn Marino }
4082e4b17023SJohn Marino
4083e4b17023SJohn Marino /* Process a spec string, accumulating and running commands. */
4084e4b17023SJohn Marino
4085e4b17023SJohn Marino /* These variables describe the input file name.
4086e4b17023SJohn Marino input_file_number is the index on outfiles of this file,
4087e4b17023SJohn Marino so that the output file name can be stored for later use by %o.
4088e4b17023SJohn Marino input_basename is the start of the part of the input file
4089e4b17023SJohn Marino sans all directory names, and basename_length is the number
4090e4b17023SJohn Marino of characters starting there excluding the suffix .c or whatever. */
4091e4b17023SJohn Marino
4092e4b17023SJohn Marino static const char *gcc_input_filename;
4093e4b17023SJohn Marino static int input_file_number;
4094e4b17023SJohn Marino size_t input_filename_length;
4095e4b17023SJohn Marino static int basename_length;
4096e4b17023SJohn Marino static int suffixed_basename_length;
4097e4b17023SJohn Marino static const char *input_basename;
4098e4b17023SJohn Marino static const char *input_suffix;
4099e4b17023SJohn Marino #ifndef HOST_LACKS_INODE_NUMBERS
4100e4b17023SJohn Marino static struct stat input_stat;
4101e4b17023SJohn Marino #endif
4102e4b17023SJohn Marino static int input_stat_set;
4103e4b17023SJohn Marino
4104e4b17023SJohn Marino /* The compiler used to process the current input file. */
4105e4b17023SJohn Marino static struct compiler *input_file_compiler;
4106e4b17023SJohn Marino
4107e4b17023SJohn Marino /* These are variables used within do_spec and do_spec_1. */
4108e4b17023SJohn Marino
4109e4b17023SJohn Marino /* Nonzero if an arg has been started and not yet terminated
4110e4b17023SJohn Marino (with space, tab or newline). */
4111e4b17023SJohn Marino static int arg_going;
4112e4b17023SJohn Marino
4113e4b17023SJohn Marino /* Nonzero means %d or %g has been seen; the next arg to be terminated
4114e4b17023SJohn Marino is a temporary file name. */
4115e4b17023SJohn Marino static int delete_this_arg;
4116e4b17023SJohn Marino
4117e4b17023SJohn Marino /* Nonzero means %w has been seen; the next arg to be terminated
4118e4b17023SJohn Marino is the output file name of this compilation. */
4119e4b17023SJohn Marino static int this_is_output_file;
4120e4b17023SJohn Marino
4121e4b17023SJohn Marino /* Nonzero means %s has been seen; the next arg to be terminated
4122e4b17023SJohn Marino is the name of a library file and we should try the standard
4123e4b17023SJohn Marino search dirs for it. */
4124e4b17023SJohn Marino static int this_is_library_file;
4125e4b17023SJohn Marino
4126e4b17023SJohn Marino /* Nonzero means %T has been seen; the next arg to be terminated
4127e4b17023SJohn Marino is the name of a linker script and we should try all of the
4128e4b17023SJohn Marino standard search dirs for it. If it is found insert a --script
4129e4b17023SJohn Marino command line switch and then substitute the full path in place,
4130e4b17023SJohn Marino otherwise generate an error message. */
4131e4b17023SJohn Marino static int this_is_linker_script;
4132e4b17023SJohn Marino
4133e4b17023SJohn Marino /* Nonzero means that the input of this command is coming from a pipe. */
4134e4b17023SJohn Marino static int input_from_pipe;
4135e4b17023SJohn Marino
4136e4b17023SJohn Marino /* Nonnull means substitute this for any suffix when outputting a switches
4137e4b17023SJohn Marino arguments. */
4138e4b17023SJohn Marino static const char *suffix_subst;
4139e4b17023SJohn Marino
4140e4b17023SJohn Marino /* If there is an argument being accumulated, terminate it and store it. */
4141e4b17023SJohn Marino
4142e4b17023SJohn Marino static void
end_going_arg(void)4143e4b17023SJohn Marino end_going_arg (void)
4144e4b17023SJohn Marino {
4145e4b17023SJohn Marino if (arg_going)
4146e4b17023SJohn Marino {
4147e4b17023SJohn Marino const char *string;
4148e4b17023SJohn Marino
4149e4b17023SJohn Marino obstack_1grow (&obstack, 0);
4150e4b17023SJohn Marino string = XOBFINISH (&obstack, const char *);
4151e4b17023SJohn Marino if (this_is_library_file)
4152e4b17023SJohn Marino string = find_file (string);
4153e4b17023SJohn Marino if (this_is_linker_script)
4154e4b17023SJohn Marino {
4155e4b17023SJohn Marino char * full_script_path = find_a_file (&startfile_prefixes, string, R_OK, true);
4156e4b17023SJohn Marino
4157e4b17023SJohn Marino if (full_script_path == NULL)
4158e4b17023SJohn Marino {
4159e4b17023SJohn Marino error ("unable to locate default linker script %qs in the library search paths", string);
4160e4b17023SJohn Marino /* Script was not found on search path. */
4161e4b17023SJohn Marino return;
4162e4b17023SJohn Marino }
4163e4b17023SJohn Marino store_arg ("--script", false, false);
4164e4b17023SJohn Marino string = full_script_path;
4165e4b17023SJohn Marino }
4166e4b17023SJohn Marino store_arg (string, delete_this_arg, this_is_output_file);
4167e4b17023SJohn Marino if (this_is_output_file)
4168e4b17023SJohn Marino outfiles[input_file_number] = string;
4169e4b17023SJohn Marino arg_going = 0;
4170e4b17023SJohn Marino }
4171e4b17023SJohn Marino }
4172e4b17023SJohn Marino
4173e4b17023SJohn Marino
4174e4b17023SJohn Marino /* Parse the WRAPPER string which is a comma separated list of the command line
4175e4b17023SJohn Marino and insert them into the beginning of argbuf. */
4176e4b17023SJohn Marino
4177e4b17023SJohn Marino static void
insert_wrapper(const char * wrapper)4178e4b17023SJohn Marino insert_wrapper (const char *wrapper)
4179e4b17023SJohn Marino {
4180e4b17023SJohn Marino int n = 0;
4181e4b17023SJohn Marino int i;
4182e4b17023SJohn Marino char *buf = xstrdup (wrapper);
4183e4b17023SJohn Marino char *p = buf;
4184e4b17023SJohn Marino unsigned int old_length = VEC_length (const_char_p, argbuf);
4185e4b17023SJohn Marino
4186e4b17023SJohn Marino do
4187e4b17023SJohn Marino {
4188e4b17023SJohn Marino n++;
4189e4b17023SJohn Marino while (*p == ',')
4190e4b17023SJohn Marino p++;
4191e4b17023SJohn Marino }
4192e4b17023SJohn Marino while ((p = strchr (p, ',')) != NULL);
4193e4b17023SJohn Marino
4194e4b17023SJohn Marino VEC_safe_grow (const_char_p, heap, argbuf, old_length + n);
4195e4b17023SJohn Marino memmove (VEC_address (const_char_p, argbuf) + n,
4196e4b17023SJohn Marino VEC_address (const_char_p, argbuf),
4197e4b17023SJohn Marino old_length * sizeof (const_char_p));
4198e4b17023SJohn Marino
4199e4b17023SJohn Marino i = 0;
4200e4b17023SJohn Marino p = buf;
4201e4b17023SJohn Marino do
4202e4b17023SJohn Marino {
4203e4b17023SJohn Marino while (*p == ',')
4204e4b17023SJohn Marino {
4205e4b17023SJohn Marino *p = 0;
4206e4b17023SJohn Marino p++;
4207e4b17023SJohn Marino }
4208e4b17023SJohn Marino VEC_replace (const_char_p, argbuf, i, p);
4209e4b17023SJohn Marino i++;
4210e4b17023SJohn Marino }
4211e4b17023SJohn Marino while ((p = strchr (p, ',')) != NULL);
4212e4b17023SJohn Marino gcc_assert (i == n);
4213e4b17023SJohn Marino }
4214e4b17023SJohn Marino
4215e4b17023SJohn Marino /* Process the spec SPEC and run the commands specified therein.
4216e4b17023SJohn Marino Returns 0 if the spec is successfully processed; -1 if failed. */
4217e4b17023SJohn Marino
4218e4b17023SJohn Marino int
do_spec(const char * spec)4219e4b17023SJohn Marino do_spec (const char *spec)
4220e4b17023SJohn Marino {
4221e4b17023SJohn Marino int value;
4222e4b17023SJohn Marino
4223e4b17023SJohn Marino value = do_spec_2 (spec);
4224e4b17023SJohn Marino
4225e4b17023SJohn Marino /* Force out any unfinished command.
4226e4b17023SJohn Marino If -pipe, this forces out the last command if it ended in `|'. */
4227e4b17023SJohn Marino if (value == 0)
4228e4b17023SJohn Marino {
4229e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0
4230e4b17023SJohn Marino && !strcmp (VEC_last (const_char_p, argbuf), "|"))
4231e4b17023SJohn Marino VEC_pop (const_char_p, argbuf);
4232e4b17023SJohn Marino
4233e4b17023SJohn Marino set_collect_gcc_options ();
4234e4b17023SJohn Marino
4235e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0)
4236e4b17023SJohn Marino value = execute ();
4237e4b17023SJohn Marino }
4238e4b17023SJohn Marino
4239e4b17023SJohn Marino return value;
4240e4b17023SJohn Marino }
4241e4b17023SJohn Marino
4242e4b17023SJohn Marino static int
do_spec_2(const char * spec)4243e4b17023SJohn Marino do_spec_2 (const char *spec)
4244e4b17023SJohn Marino {
4245e4b17023SJohn Marino int result;
4246e4b17023SJohn Marino
4247e4b17023SJohn Marino clear_args ();
4248e4b17023SJohn Marino arg_going = 0;
4249e4b17023SJohn Marino delete_this_arg = 0;
4250e4b17023SJohn Marino this_is_output_file = 0;
4251e4b17023SJohn Marino this_is_library_file = 0;
4252e4b17023SJohn Marino this_is_linker_script = 0;
4253e4b17023SJohn Marino input_from_pipe = 0;
4254e4b17023SJohn Marino suffix_subst = NULL;
4255e4b17023SJohn Marino
4256e4b17023SJohn Marino result = do_spec_1 (spec, 0, NULL);
4257e4b17023SJohn Marino
4258e4b17023SJohn Marino end_going_arg ();
4259e4b17023SJohn Marino
4260e4b17023SJohn Marino return result;
4261e4b17023SJohn Marino }
4262e4b17023SJohn Marino
4263e4b17023SJohn Marino
4264e4b17023SJohn Marino /* Process the given spec string and add any new options to the end
4265e4b17023SJohn Marino of the switches/n_switches array. */
4266e4b17023SJohn Marino
4267e4b17023SJohn Marino static void
do_option_spec(const char * name,const char * spec)4268e4b17023SJohn Marino do_option_spec (const char *name, const char *spec)
4269e4b17023SJohn Marino {
4270e4b17023SJohn Marino unsigned int i, value_count, value_len;
4271e4b17023SJohn Marino const char *p, *q, *value;
4272e4b17023SJohn Marino char *tmp_spec, *tmp_spec_p;
4273e4b17023SJohn Marino
4274e4b17023SJohn Marino if (configure_default_options[0].name == NULL)
4275e4b17023SJohn Marino return;
4276e4b17023SJohn Marino
4277e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
4278e4b17023SJohn Marino if (strcmp (configure_default_options[i].name, name) == 0)
4279e4b17023SJohn Marino break;
4280e4b17023SJohn Marino if (i == ARRAY_SIZE (configure_default_options))
4281e4b17023SJohn Marino return;
4282e4b17023SJohn Marino
4283e4b17023SJohn Marino value = configure_default_options[i].value;
4284e4b17023SJohn Marino value_len = strlen (value);
4285e4b17023SJohn Marino
4286e4b17023SJohn Marino /* Compute the size of the final spec. */
4287e4b17023SJohn Marino value_count = 0;
4288e4b17023SJohn Marino p = spec;
4289e4b17023SJohn Marino while ((p = strstr (p, "%(VALUE)")) != NULL)
4290e4b17023SJohn Marino {
4291e4b17023SJohn Marino p ++;
4292e4b17023SJohn Marino value_count ++;
4293e4b17023SJohn Marino }
4294e4b17023SJohn Marino
4295e4b17023SJohn Marino /* Replace each %(VALUE) by the specified value. */
4296e4b17023SJohn Marino tmp_spec = (char *) alloca (strlen (spec) + 1
4297e4b17023SJohn Marino + value_count * (value_len - strlen ("%(VALUE)")));
4298e4b17023SJohn Marino tmp_spec_p = tmp_spec;
4299e4b17023SJohn Marino q = spec;
4300e4b17023SJohn Marino while ((p = strstr (q, "%(VALUE)")) != NULL)
4301e4b17023SJohn Marino {
4302e4b17023SJohn Marino memcpy (tmp_spec_p, q, p - q);
4303e4b17023SJohn Marino tmp_spec_p = tmp_spec_p + (p - q);
4304e4b17023SJohn Marino memcpy (tmp_spec_p, value, value_len);
4305e4b17023SJohn Marino tmp_spec_p += value_len;
4306e4b17023SJohn Marino q = p + strlen ("%(VALUE)");
4307e4b17023SJohn Marino }
4308e4b17023SJohn Marino strcpy (tmp_spec_p, q);
4309e4b17023SJohn Marino
4310e4b17023SJohn Marino do_self_spec (tmp_spec);
4311e4b17023SJohn Marino }
4312e4b17023SJohn Marino
4313e4b17023SJohn Marino /* Process the given spec string and add any new options to the end
4314e4b17023SJohn Marino of the switches/n_switches array. */
4315e4b17023SJohn Marino
4316e4b17023SJohn Marino static void
do_self_spec(const char * spec)4317e4b17023SJohn Marino do_self_spec (const char *spec)
4318e4b17023SJohn Marino {
4319e4b17023SJohn Marino int i;
4320e4b17023SJohn Marino
4321e4b17023SJohn Marino do_spec_2 (spec);
4322e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4323e4b17023SJohn Marino
4324e4b17023SJohn Marino /* Mark %<S switches processed by do_self_spec to be ignored permanently.
4325e4b17023SJohn Marino do_self_specs adds the replacements to switches array, so it shouldn't
4326e4b17023SJohn Marino be processed afterwards. */
4327e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
4328e4b17023SJohn Marino if ((switches[i].live_cond & SWITCH_IGNORE))
4329e4b17023SJohn Marino switches[i].live_cond |= SWITCH_IGNORE_PERMANENTLY;
4330e4b17023SJohn Marino
4331e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0)
4332e4b17023SJohn Marino {
4333e4b17023SJohn Marino const char **argbuf_copy;
4334e4b17023SJohn Marino struct cl_decoded_option *decoded_options;
4335e4b17023SJohn Marino struct cl_option_handlers handlers;
4336e4b17023SJohn Marino unsigned int decoded_options_count;
4337e4b17023SJohn Marino unsigned int j;
4338e4b17023SJohn Marino
4339e4b17023SJohn Marino /* Create a copy of argbuf with a dummy argv[0] entry for
4340e4b17023SJohn Marino decode_cmdline_options_to_array. */
4341e4b17023SJohn Marino argbuf_copy = XNEWVEC (const char *,
4342e4b17023SJohn Marino VEC_length (const_char_p, argbuf) + 1);
4343e4b17023SJohn Marino argbuf_copy[0] = "";
4344e4b17023SJohn Marino memcpy (argbuf_copy + 1, VEC_address (const_char_p, argbuf),
4345e4b17023SJohn Marino VEC_length (const_char_p, argbuf) * sizeof (const char *));
4346e4b17023SJohn Marino
4347e4b17023SJohn Marino decode_cmdline_options_to_array (VEC_length (const_char_p, argbuf) + 1,
4348e4b17023SJohn Marino argbuf_copy,
4349e4b17023SJohn Marino CL_DRIVER, &decoded_options,
4350e4b17023SJohn Marino &decoded_options_count);
4351e4b17023SJohn Marino
4352e4b17023SJohn Marino set_option_handlers (&handlers);
4353e4b17023SJohn Marino
4354e4b17023SJohn Marino for (j = 1; j < decoded_options_count; j++)
4355e4b17023SJohn Marino {
4356e4b17023SJohn Marino switch (decoded_options[j].opt_index)
4357e4b17023SJohn Marino {
4358e4b17023SJohn Marino case OPT_SPECIAL_input_file:
4359e4b17023SJohn Marino /* Specs should only generate options, not input
4360e4b17023SJohn Marino files. */
4361e4b17023SJohn Marino if (strcmp (decoded_options[j].arg, "-") != 0)
4362e4b17023SJohn Marino fatal_error ("switch %qs does not start with %<-%>",
4363e4b17023SJohn Marino decoded_options[j].arg);
4364e4b17023SJohn Marino else
4365e4b17023SJohn Marino fatal_error ("spec-generated switch is just %<-%>");
4366e4b17023SJohn Marino break;
4367e4b17023SJohn Marino
4368e4b17023SJohn Marino case OPT_fcompare_debug_second:
4369e4b17023SJohn Marino case OPT_fcompare_debug:
4370e4b17023SJohn Marino case OPT_fcompare_debug_:
4371e4b17023SJohn Marino case OPT_o:
4372e4b17023SJohn Marino /* Avoid duplicate processing of some options from
4373e4b17023SJohn Marino compare-debug specs; just save them here. */
4374e4b17023SJohn Marino save_switch (decoded_options[j].canonical_option[0],
4375e4b17023SJohn Marino (decoded_options[j].canonical_option_num_elements
4376e4b17023SJohn Marino - 1),
4377e4b17023SJohn Marino &decoded_options[j].canonical_option[1], false);
4378e4b17023SJohn Marino break;
4379e4b17023SJohn Marino
4380e4b17023SJohn Marino default:
4381e4b17023SJohn Marino read_cmdline_option (&global_options, &global_options_set,
4382e4b17023SJohn Marino decoded_options + j, UNKNOWN_LOCATION,
4383e4b17023SJohn Marino CL_DRIVER, &handlers, global_dc);
4384e4b17023SJohn Marino break;
4385e4b17023SJohn Marino }
4386e4b17023SJohn Marino }
4387e4b17023SJohn Marino
4388e4b17023SJohn Marino alloc_switch ();
4389e4b17023SJohn Marino switches[n_switches].part1 = 0;
4390e4b17023SJohn Marino }
4391e4b17023SJohn Marino }
4392e4b17023SJohn Marino
4393e4b17023SJohn Marino /* Callback for processing %D and %I specs. */
4394e4b17023SJohn Marino
4395e4b17023SJohn Marino struct spec_path_info {
4396e4b17023SJohn Marino const char *option;
4397e4b17023SJohn Marino const char *append;
4398e4b17023SJohn Marino size_t append_len;
4399e4b17023SJohn Marino bool omit_relative;
4400e4b17023SJohn Marino bool separate_options;
4401e4b17023SJohn Marino };
4402e4b17023SJohn Marino
4403e4b17023SJohn Marino static void *
spec_path(char * path,void * data)4404e4b17023SJohn Marino spec_path (char *path, void *data)
4405e4b17023SJohn Marino {
4406e4b17023SJohn Marino struct spec_path_info *info = (struct spec_path_info *) data;
4407e4b17023SJohn Marino size_t len = 0;
4408e4b17023SJohn Marino char save = 0;
4409e4b17023SJohn Marino
4410e4b17023SJohn Marino if (info->omit_relative && !IS_ABSOLUTE_PATH (path))
4411e4b17023SJohn Marino return NULL;
4412e4b17023SJohn Marino
4413e4b17023SJohn Marino if (info->append_len != 0)
4414e4b17023SJohn Marino {
4415e4b17023SJohn Marino len = strlen (path);
4416e4b17023SJohn Marino memcpy (path + len, info->append, info->append_len + 1);
4417e4b17023SJohn Marino }
4418e4b17023SJohn Marino
4419e4b17023SJohn Marino if (!is_directory (path, true))
4420e4b17023SJohn Marino return NULL;
4421e4b17023SJohn Marino
4422e4b17023SJohn Marino do_spec_1 (info->option, 1, NULL);
4423e4b17023SJohn Marino if (info->separate_options)
4424e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4425e4b17023SJohn Marino
4426e4b17023SJohn Marino if (info->append_len == 0)
4427e4b17023SJohn Marino {
4428e4b17023SJohn Marino len = strlen (path);
4429e4b17023SJohn Marino save = path[len - 1];
4430e4b17023SJohn Marino if (IS_DIR_SEPARATOR (path[len - 1]))
4431e4b17023SJohn Marino path[len - 1] = '\0';
4432e4b17023SJohn Marino }
4433e4b17023SJohn Marino
4434e4b17023SJohn Marino do_spec_1 (path, 1, NULL);
4435e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4436e4b17023SJohn Marino
4437e4b17023SJohn Marino /* Must not damage the original path. */
4438e4b17023SJohn Marino if (info->append_len == 0)
4439e4b17023SJohn Marino path[len - 1] = save;
4440e4b17023SJohn Marino
4441e4b17023SJohn Marino return NULL;
4442e4b17023SJohn Marino }
4443e4b17023SJohn Marino
4444e4b17023SJohn Marino /* Create a temporary FILE with the contents of ARGV. Add @FILE to the
4445e4b17023SJohn Marino argument list. */
4446e4b17023SJohn Marino
4447e4b17023SJohn Marino static void
create_at_file(char ** argv)4448e4b17023SJohn Marino create_at_file (char **argv)
4449e4b17023SJohn Marino {
4450e4b17023SJohn Marino char *temp_file = make_temp_file ("");
4451e4b17023SJohn Marino char *at_argument = concat ("@", temp_file, NULL);
4452e4b17023SJohn Marino FILE *f = fopen (temp_file, "w");
4453e4b17023SJohn Marino int status;
4454e4b17023SJohn Marino
4455e4b17023SJohn Marino if (f == NULL)
4456e4b17023SJohn Marino fatal_error ("could not open temporary response file %s",
4457e4b17023SJohn Marino temp_file);
4458e4b17023SJohn Marino
4459e4b17023SJohn Marino status = writeargv (argv, f);
4460e4b17023SJohn Marino
4461e4b17023SJohn Marino if (status)
4462e4b17023SJohn Marino fatal_error ("could not write to temporary response file %s",
4463e4b17023SJohn Marino temp_file);
4464e4b17023SJohn Marino
4465e4b17023SJohn Marino status = fclose (f);
4466e4b17023SJohn Marino
4467e4b17023SJohn Marino if (EOF == status)
4468e4b17023SJohn Marino fatal_error ("could not close temporary response file %s",
4469e4b17023SJohn Marino temp_file);
4470e4b17023SJohn Marino
4471e4b17023SJohn Marino store_arg (at_argument, 0, 0);
4472e4b17023SJohn Marino
4473e4b17023SJohn Marino record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
4474e4b17023SJohn Marino }
4475e4b17023SJohn Marino
4476e4b17023SJohn Marino /* True if we should compile INFILE. */
4477e4b17023SJohn Marino
4478e4b17023SJohn Marino static bool
compile_input_file_p(struct infile * infile)4479e4b17023SJohn Marino compile_input_file_p (struct infile *infile)
4480e4b17023SJohn Marino {
4481e4b17023SJohn Marino if ((!infile->language) || (infile->language[0] != '*'))
4482e4b17023SJohn Marino if (infile->incompiler == input_file_compiler)
4483e4b17023SJohn Marino return true;
4484e4b17023SJohn Marino return false;
4485e4b17023SJohn Marino }
4486e4b17023SJohn Marino
4487e4b17023SJohn Marino /* Process each member of VEC as a spec. */
4488e4b17023SJohn Marino
4489e4b17023SJohn Marino static void
do_specs_vec(VEC (char_p,heap)* vec)4490e4b17023SJohn Marino do_specs_vec (VEC(char_p,heap) *vec)
4491e4b17023SJohn Marino {
4492e4b17023SJohn Marino unsigned ix;
4493e4b17023SJohn Marino char *opt;
4494e4b17023SJohn Marino
4495e4b17023SJohn Marino FOR_EACH_VEC_ELT (char_p, vec, ix, opt)
4496e4b17023SJohn Marino {
4497e4b17023SJohn Marino do_spec_1 (opt, 1, NULL);
4498e4b17023SJohn Marino /* Make each accumulated option a separate argument. */
4499e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4500e4b17023SJohn Marino }
4501e4b17023SJohn Marino }
4502e4b17023SJohn Marino
4503e4b17023SJohn Marino /* Process the sub-spec SPEC as a portion of a larger spec.
4504e4b17023SJohn Marino This is like processing a whole spec except that we do
4505e4b17023SJohn Marino not initialize at the beginning and we do not supply a
4506e4b17023SJohn Marino newline by default at the end.
4507e4b17023SJohn Marino INSWITCH nonzero means don't process %-sequences in SPEC;
4508e4b17023SJohn Marino in this case, % is treated as an ordinary character.
4509e4b17023SJohn Marino This is used while substituting switches.
4510e4b17023SJohn Marino INSWITCH nonzero also causes SPC not to terminate an argument.
4511e4b17023SJohn Marino
4512e4b17023SJohn Marino Value is zero unless a line was finished
4513e4b17023SJohn Marino and the command on that line reported an error. */
4514e4b17023SJohn Marino
4515e4b17023SJohn Marino static int
do_spec_1(const char * spec,int inswitch,const char * soft_matched_part)4516e4b17023SJohn Marino do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
4517e4b17023SJohn Marino {
4518e4b17023SJohn Marino const char *p = spec;
4519e4b17023SJohn Marino int c;
4520e4b17023SJohn Marino int i;
4521e4b17023SJohn Marino int value;
4522e4b17023SJohn Marino
4523e4b17023SJohn Marino /* If it's an empty string argument to a switch, keep it as is. */
4524e4b17023SJohn Marino if (inswitch && !*p)
4525e4b17023SJohn Marino arg_going = 1;
4526e4b17023SJohn Marino
4527e4b17023SJohn Marino while ((c = *p++))
4528e4b17023SJohn Marino /* If substituting a switch, treat all chars like letters.
4529e4b17023SJohn Marino Otherwise, NL, SPC, TAB and % are special. */
4530e4b17023SJohn Marino switch (inswitch ? 'a' : c)
4531e4b17023SJohn Marino {
4532e4b17023SJohn Marino case '\n':
4533e4b17023SJohn Marino end_going_arg ();
4534e4b17023SJohn Marino
4535e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0
4536e4b17023SJohn Marino && !strcmp (VEC_last (const_char_p, argbuf), "|"))
4537e4b17023SJohn Marino {
4538e4b17023SJohn Marino /* A `|' before the newline means use a pipe here,
4539e4b17023SJohn Marino but only if -pipe was specified.
4540e4b17023SJohn Marino Otherwise, execute now and don't pass the `|' as an arg. */
4541e4b17023SJohn Marino if (use_pipes)
4542e4b17023SJohn Marino {
4543e4b17023SJohn Marino input_from_pipe = 1;
4544e4b17023SJohn Marino break;
4545e4b17023SJohn Marino }
4546e4b17023SJohn Marino else
4547e4b17023SJohn Marino VEC_pop (const_char_p, argbuf);
4548e4b17023SJohn Marino }
4549e4b17023SJohn Marino
4550e4b17023SJohn Marino set_collect_gcc_options ();
4551e4b17023SJohn Marino
4552e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0)
4553e4b17023SJohn Marino {
4554e4b17023SJohn Marino value = execute ();
4555e4b17023SJohn Marino if (value)
4556e4b17023SJohn Marino return value;
4557e4b17023SJohn Marino }
4558e4b17023SJohn Marino /* Reinitialize for a new command, and for a new argument. */
4559e4b17023SJohn Marino clear_args ();
4560e4b17023SJohn Marino arg_going = 0;
4561e4b17023SJohn Marino delete_this_arg = 0;
4562e4b17023SJohn Marino this_is_output_file = 0;
4563e4b17023SJohn Marino this_is_library_file = 0;
4564e4b17023SJohn Marino this_is_linker_script = 0;
4565e4b17023SJohn Marino input_from_pipe = 0;
4566e4b17023SJohn Marino break;
4567e4b17023SJohn Marino
4568e4b17023SJohn Marino case '|':
4569e4b17023SJohn Marino end_going_arg ();
4570e4b17023SJohn Marino
4571e4b17023SJohn Marino /* Use pipe */
4572e4b17023SJohn Marino obstack_1grow (&obstack, c);
4573e4b17023SJohn Marino arg_going = 1;
4574e4b17023SJohn Marino break;
4575e4b17023SJohn Marino
4576e4b17023SJohn Marino case '\t':
4577e4b17023SJohn Marino case ' ':
4578e4b17023SJohn Marino end_going_arg ();
4579e4b17023SJohn Marino
4580e4b17023SJohn Marino /* Reinitialize for a new argument. */
4581e4b17023SJohn Marino delete_this_arg = 0;
4582e4b17023SJohn Marino this_is_output_file = 0;
4583e4b17023SJohn Marino this_is_library_file = 0;
4584e4b17023SJohn Marino this_is_linker_script = 0;
4585e4b17023SJohn Marino break;
4586e4b17023SJohn Marino
4587e4b17023SJohn Marino case '%':
4588e4b17023SJohn Marino switch (c = *p++)
4589e4b17023SJohn Marino {
4590e4b17023SJohn Marino case 0:
4591e4b17023SJohn Marino fatal_error ("spec %qs invalid", spec);
4592e4b17023SJohn Marino
4593e4b17023SJohn Marino case 'b':
4594e4b17023SJohn Marino if (save_temps_length)
4595e4b17023SJohn Marino obstack_grow (&obstack, save_temps_prefix, save_temps_length);
4596e4b17023SJohn Marino else
4597e4b17023SJohn Marino obstack_grow (&obstack, input_basename, basename_length);
4598e4b17023SJohn Marino if (compare_debug < 0)
4599e4b17023SJohn Marino obstack_grow (&obstack, ".gk", 3);
4600e4b17023SJohn Marino arg_going = 1;
4601e4b17023SJohn Marino break;
4602e4b17023SJohn Marino
4603e4b17023SJohn Marino case 'B':
4604e4b17023SJohn Marino if (save_temps_length)
4605e4b17023SJohn Marino obstack_grow (&obstack, save_temps_prefix, save_temps_length);
4606e4b17023SJohn Marino else
4607e4b17023SJohn Marino obstack_grow (&obstack, input_basename, suffixed_basename_length);
4608e4b17023SJohn Marino if (compare_debug < 0)
4609e4b17023SJohn Marino obstack_grow (&obstack, ".gk", 3);
4610e4b17023SJohn Marino arg_going = 1;
4611e4b17023SJohn Marino break;
4612e4b17023SJohn Marino
4613e4b17023SJohn Marino case 'd':
4614e4b17023SJohn Marino delete_this_arg = 2;
4615e4b17023SJohn Marino break;
4616e4b17023SJohn Marino
4617e4b17023SJohn Marino /* Dump out the directories specified with LIBRARY_PATH,
4618e4b17023SJohn Marino followed by the absolute directories
4619e4b17023SJohn Marino that we search for startfiles. */
4620e4b17023SJohn Marino case 'D':
4621e4b17023SJohn Marino {
4622e4b17023SJohn Marino struct spec_path_info info;
4623e4b17023SJohn Marino
4624e4b17023SJohn Marino info.option = "-L";
4625e4b17023SJohn Marino info.append_len = 0;
4626e4b17023SJohn Marino #ifdef RELATIVE_PREFIX_NOT_LINKDIR
4627e4b17023SJohn Marino /* Used on systems which record the specified -L dirs
4628e4b17023SJohn Marino and use them to search for dynamic linking.
4629e4b17023SJohn Marino Relative directories always come from -B,
4630e4b17023SJohn Marino and it is better not to use them for searching
4631e4b17023SJohn Marino at run time. In particular, stage1 loses. */
4632e4b17023SJohn Marino info.omit_relative = true;
4633e4b17023SJohn Marino #else
4634e4b17023SJohn Marino info.omit_relative = false;
4635e4b17023SJohn Marino #endif
4636e4b17023SJohn Marino info.separate_options = false;
4637e4b17023SJohn Marino
4638e4b17023SJohn Marino for_each_path (&startfile_prefixes, true, 0, spec_path, &info);
4639e4b17023SJohn Marino }
4640e4b17023SJohn Marino break;
4641e4b17023SJohn Marino
4642e4b17023SJohn Marino case 'e':
4643e4b17023SJohn Marino /* %efoo means report an error with `foo' as error message
4644e4b17023SJohn Marino and don't execute any more commands for this file. */
4645e4b17023SJohn Marino {
4646e4b17023SJohn Marino const char *q = p;
4647e4b17023SJohn Marino char *buf;
4648e4b17023SJohn Marino while (*p != 0 && *p != '\n')
4649e4b17023SJohn Marino p++;
4650e4b17023SJohn Marino buf = (char *) alloca (p - q + 1);
4651e4b17023SJohn Marino strncpy (buf, q, p - q);
4652e4b17023SJohn Marino buf[p - q] = 0;
4653e4b17023SJohn Marino error ("%s", _(buf));
4654e4b17023SJohn Marino return -1;
4655e4b17023SJohn Marino }
4656e4b17023SJohn Marino break;
4657e4b17023SJohn Marino case 'n':
4658e4b17023SJohn Marino /* %nfoo means report a notice with `foo' on stderr. */
4659e4b17023SJohn Marino {
4660e4b17023SJohn Marino const char *q = p;
4661e4b17023SJohn Marino char *buf;
4662e4b17023SJohn Marino while (*p != 0 && *p != '\n')
4663e4b17023SJohn Marino p++;
4664e4b17023SJohn Marino buf = (char *) alloca (p - q + 1);
4665e4b17023SJohn Marino strncpy (buf, q, p - q);
4666e4b17023SJohn Marino buf[p - q] = 0;
4667e4b17023SJohn Marino inform (0, "%s", _(buf));
4668e4b17023SJohn Marino if (*p)
4669e4b17023SJohn Marino p++;
4670e4b17023SJohn Marino }
4671e4b17023SJohn Marino break;
4672e4b17023SJohn Marino
4673e4b17023SJohn Marino case 'j':
4674e4b17023SJohn Marino {
4675e4b17023SJohn Marino struct stat st;
4676e4b17023SJohn Marino
4677e4b17023SJohn Marino /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
4678e4b17023SJohn Marino defined, and it is not a directory, and it is
4679e4b17023SJohn Marino writable, use it. Otherwise, treat this like any
4680e4b17023SJohn Marino other temporary file. */
4681e4b17023SJohn Marino
4682e4b17023SJohn Marino if ((!save_temps_flag)
4683e4b17023SJohn Marino && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
4684e4b17023SJohn Marino && (access (HOST_BIT_BUCKET, W_OK) == 0))
4685e4b17023SJohn Marino {
4686e4b17023SJohn Marino obstack_grow (&obstack, HOST_BIT_BUCKET,
4687e4b17023SJohn Marino strlen (HOST_BIT_BUCKET));
4688e4b17023SJohn Marino delete_this_arg = 0;
4689e4b17023SJohn Marino arg_going = 1;
4690e4b17023SJohn Marino break;
4691e4b17023SJohn Marino }
4692e4b17023SJohn Marino }
4693e4b17023SJohn Marino goto create_temp_file;
4694e4b17023SJohn Marino case '|':
4695e4b17023SJohn Marino if (use_pipes)
4696e4b17023SJohn Marino {
4697e4b17023SJohn Marino obstack_1grow (&obstack, '-');
4698e4b17023SJohn Marino delete_this_arg = 0;
4699e4b17023SJohn Marino arg_going = 1;
4700e4b17023SJohn Marino
4701e4b17023SJohn Marino /* consume suffix */
4702e4b17023SJohn Marino while (*p == '.' || ISALNUM ((unsigned char) *p))
4703e4b17023SJohn Marino p++;
4704e4b17023SJohn Marino if (p[0] == '%' && p[1] == 'O')
4705e4b17023SJohn Marino p += 2;
4706e4b17023SJohn Marino
4707e4b17023SJohn Marino break;
4708e4b17023SJohn Marino }
4709e4b17023SJohn Marino goto create_temp_file;
4710e4b17023SJohn Marino case 'm':
4711e4b17023SJohn Marino if (use_pipes)
4712e4b17023SJohn Marino {
4713e4b17023SJohn Marino /* consume suffix */
4714e4b17023SJohn Marino while (*p == '.' || ISALNUM ((unsigned char) *p))
4715e4b17023SJohn Marino p++;
4716e4b17023SJohn Marino if (p[0] == '%' && p[1] == 'O')
4717e4b17023SJohn Marino p += 2;
4718e4b17023SJohn Marino
4719e4b17023SJohn Marino break;
4720e4b17023SJohn Marino }
4721e4b17023SJohn Marino goto create_temp_file;
4722e4b17023SJohn Marino case 'g':
4723e4b17023SJohn Marino case 'u':
4724e4b17023SJohn Marino case 'U':
4725e4b17023SJohn Marino create_temp_file:
4726e4b17023SJohn Marino {
4727e4b17023SJohn Marino struct temp_name *t;
4728e4b17023SJohn Marino int suffix_length;
4729e4b17023SJohn Marino const char *suffix = p;
4730e4b17023SJohn Marino char *saved_suffix = NULL;
4731e4b17023SJohn Marino
4732e4b17023SJohn Marino while (*p == '.' || ISALNUM ((unsigned char) *p))
4733e4b17023SJohn Marino p++;
4734e4b17023SJohn Marino suffix_length = p - suffix;
4735e4b17023SJohn Marino if (p[0] == '%' && p[1] == 'O')
4736e4b17023SJohn Marino {
4737e4b17023SJohn Marino p += 2;
4738e4b17023SJohn Marino /* We don't support extra suffix characters after %O. */
4739e4b17023SJohn Marino if (*p == '.' || ISALNUM ((unsigned char) *p))
4740e4b17023SJohn Marino fatal_error ("spec %qs has invalid %<%%0%c%>", spec, *p);
4741e4b17023SJohn Marino if (suffix_length == 0)
4742e4b17023SJohn Marino suffix = TARGET_OBJECT_SUFFIX;
4743e4b17023SJohn Marino else
4744e4b17023SJohn Marino {
4745e4b17023SJohn Marino saved_suffix
4746e4b17023SJohn Marino = XNEWVEC (char, suffix_length
4747e4b17023SJohn Marino + strlen (TARGET_OBJECT_SUFFIX));
4748e4b17023SJohn Marino strncpy (saved_suffix, suffix, suffix_length);
4749e4b17023SJohn Marino strcpy (saved_suffix + suffix_length,
4750e4b17023SJohn Marino TARGET_OBJECT_SUFFIX);
4751e4b17023SJohn Marino }
4752e4b17023SJohn Marino suffix_length += strlen (TARGET_OBJECT_SUFFIX);
4753e4b17023SJohn Marino }
4754e4b17023SJohn Marino
4755e4b17023SJohn Marino if (compare_debug < 0)
4756e4b17023SJohn Marino {
4757e4b17023SJohn Marino suffix = concat (".gk", suffix, NULL);
4758e4b17023SJohn Marino suffix_length += 3;
4759e4b17023SJohn Marino }
4760e4b17023SJohn Marino
4761e4b17023SJohn Marino /* If -save-temps=obj and -o were specified, use that for the
4762e4b17023SJohn Marino temp file. */
4763e4b17023SJohn Marino if (save_temps_length)
4764e4b17023SJohn Marino {
4765e4b17023SJohn Marino char *tmp;
4766e4b17023SJohn Marino temp_filename_length
4767e4b17023SJohn Marino = save_temps_length + suffix_length + 1;
4768e4b17023SJohn Marino tmp = (char *) alloca (temp_filename_length);
4769e4b17023SJohn Marino memcpy (tmp, save_temps_prefix, save_temps_length);
4770e4b17023SJohn Marino memcpy (tmp + save_temps_length, suffix, suffix_length);
4771e4b17023SJohn Marino tmp[save_temps_length + suffix_length] = '\0';
4772e4b17023SJohn Marino temp_filename = save_string (tmp,
4773e4b17023SJohn Marino temp_filename_length + 1);
4774e4b17023SJohn Marino obstack_grow (&obstack, temp_filename,
4775e4b17023SJohn Marino temp_filename_length);
4776e4b17023SJohn Marino arg_going = 1;
4777e4b17023SJohn Marino delete_this_arg = 0;
4778e4b17023SJohn Marino break;
4779e4b17023SJohn Marino }
4780e4b17023SJohn Marino
4781e4b17023SJohn Marino /* If the gcc_input_filename has the same suffix specified
4782e4b17023SJohn Marino for the %g, %u, or %U, and -save-temps is specified,
4783e4b17023SJohn Marino we could end up using that file as an intermediate
4784e4b17023SJohn Marino thus clobbering the user's source file (.e.g.,
4785e4b17023SJohn Marino gcc -save-temps foo.s would clobber foo.s with the
4786e4b17023SJohn Marino output of cpp0). So check for this condition and
4787e4b17023SJohn Marino generate a temp file as the intermediate. */
4788e4b17023SJohn Marino
4789e4b17023SJohn Marino if (save_temps_flag)
4790e4b17023SJohn Marino {
4791e4b17023SJohn Marino char *tmp;
4792e4b17023SJohn Marino temp_filename_length = basename_length + suffix_length + 1;
4793e4b17023SJohn Marino tmp = (char *) alloca (temp_filename_length);
4794e4b17023SJohn Marino memcpy (tmp, input_basename, basename_length);
4795e4b17023SJohn Marino memcpy (tmp + basename_length, suffix, suffix_length);
4796e4b17023SJohn Marino tmp[basename_length + suffix_length] = '\0';
4797e4b17023SJohn Marino temp_filename = tmp;
4798e4b17023SJohn Marino
4799e4b17023SJohn Marino if (filename_cmp (temp_filename, gcc_input_filename) != 0)
4800e4b17023SJohn Marino {
4801e4b17023SJohn Marino #ifndef HOST_LACKS_INODE_NUMBERS
4802e4b17023SJohn Marino struct stat st_temp;
4803e4b17023SJohn Marino
4804e4b17023SJohn Marino /* Note, set_input() resets input_stat_set to 0. */
4805e4b17023SJohn Marino if (input_stat_set == 0)
4806e4b17023SJohn Marino {
4807e4b17023SJohn Marino input_stat_set = stat (gcc_input_filename,
4808e4b17023SJohn Marino &input_stat);
4809e4b17023SJohn Marino if (input_stat_set >= 0)
4810e4b17023SJohn Marino input_stat_set = 1;
4811e4b17023SJohn Marino }
4812e4b17023SJohn Marino
4813e4b17023SJohn Marino /* If we have the stat for the gcc_input_filename
4814e4b17023SJohn Marino and we can do the stat for the temp_filename
4815e4b17023SJohn Marino then the they could still refer to the same
4816e4b17023SJohn Marino file if st_dev/st_ino's are the same. */
4817e4b17023SJohn Marino if (input_stat_set != 1
4818e4b17023SJohn Marino || stat (temp_filename, &st_temp) < 0
4819e4b17023SJohn Marino || input_stat.st_dev != st_temp.st_dev
4820e4b17023SJohn Marino || input_stat.st_ino != st_temp.st_ino)
4821e4b17023SJohn Marino #else
4822e4b17023SJohn Marino /* Just compare canonical pathnames. */
4823e4b17023SJohn Marino char* input_realname = lrealpath (gcc_input_filename);
4824e4b17023SJohn Marino char* temp_realname = lrealpath (temp_filename);
4825e4b17023SJohn Marino bool files_differ = filename_cmp (input_realname, temp_realname);
4826e4b17023SJohn Marino free (input_realname);
4827e4b17023SJohn Marino free (temp_realname);
4828e4b17023SJohn Marino if (files_differ)
4829e4b17023SJohn Marino #endif
4830e4b17023SJohn Marino {
4831e4b17023SJohn Marino temp_filename = save_string (temp_filename,
4832e4b17023SJohn Marino temp_filename_length + 1);
4833e4b17023SJohn Marino obstack_grow (&obstack, temp_filename,
4834e4b17023SJohn Marino temp_filename_length);
4835e4b17023SJohn Marino arg_going = 1;
4836e4b17023SJohn Marino delete_this_arg = 0;
4837e4b17023SJohn Marino break;
4838e4b17023SJohn Marino }
4839e4b17023SJohn Marino }
4840e4b17023SJohn Marino }
4841e4b17023SJohn Marino
4842e4b17023SJohn Marino /* See if we already have an association of %g/%u/%U and
4843e4b17023SJohn Marino suffix. */
4844e4b17023SJohn Marino for (t = temp_names; t; t = t->next)
4845e4b17023SJohn Marino if (t->length == suffix_length
4846e4b17023SJohn Marino && strncmp (t->suffix, suffix, suffix_length) == 0
4847e4b17023SJohn Marino && t->unique == (c == 'u' || c == 'U' || c == 'j'))
4848e4b17023SJohn Marino break;
4849e4b17023SJohn Marino
4850e4b17023SJohn Marino /* Make a new association if needed. %u and %j
4851e4b17023SJohn Marino require one. */
4852e4b17023SJohn Marino if (t == 0 || c == 'u' || c == 'j')
4853e4b17023SJohn Marino {
4854e4b17023SJohn Marino if (t == 0)
4855e4b17023SJohn Marino {
4856e4b17023SJohn Marino t = XNEW (struct temp_name);
4857e4b17023SJohn Marino t->next = temp_names;
4858e4b17023SJohn Marino temp_names = t;
4859e4b17023SJohn Marino }
4860e4b17023SJohn Marino t->length = suffix_length;
4861e4b17023SJohn Marino if (saved_suffix)
4862e4b17023SJohn Marino {
4863e4b17023SJohn Marino t->suffix = saved_suffix;
4864e4b17023SJohn Marino saved_suffix = NULL;
4865e4b17023SJohn Marino }
4866e4b17023SJohn Marino else
4867e4b17023SJohn Marino t->suffix = save_string (suffix, suffix_length);
4868e4b17023SJohn Marino t->unique = (c == 'u' || c == 'U' || c == 'j');
4869e4b17023SJohn Marino temp_filename = make_temp_file (t->suffix);
4870e4b17023SJohn Marino temp_filename_length = strlen (temp_filename);
4871e4b17023SJohn Marino t->filename = temp_filename;
4872e4b17023SJohn Marino t->filename_length = temp_filename_length;
4873e4b17023SJohn Marino }
4874e4b17023SJohn Marino
4875e4b17023SJohn Marino free (saved_suffix);
4876e4b17023SJohn Marino
4877e4b17023SJohn Marino obstack_grow (&obstack, t->filename, t->filename_length);
4878e4b17023SJohn Marino delete_this_arg = 1;
4879e4b17023SJohn Marino }
4880e4b17023SJohn Marino arg_going = 1;
4881e4b17023SJohn Marino break;
4882e4b17023SJohn Marino
4883e4b17023SJohn Marino case 'i':
4884e4b17023SJohn Marino if (combine_inputs)
4885e4b17023SJohn Marino {
4886e4b17023SJohn Marino if (at_file_supplied)
4887e4b17023SJohn Marino {
4888e4b17023SJohn Marino /* We are going to expand `%i' to `@FILE', where FILE
4889e4b17023SJohn Marino is a newly-created temporary filename. The filenames
4890e4b17023SJohn Marino that would usually be expanded in place of %o will be
4891e4b17023SJohn Marino written to the temporary file. */
4892e4b17023SJohn Marino char **argv;
4893e4b17023SJohn Marino int n_files = 0;
4894e4b17023SJohn Marino int j;
4895e4b17023SJohn Marino
4896e4b17023SJohn Marino for (i = 0; i < n_infiles; i++)
4897e4b17023SJohn Marino if (compile_input_file_p (&infiles[i]))
4898e4b17023SJohn Marino n_files++;
4899e4b17023SJohn Marino
4900e4b17023SJohn Marino argv = (char **) alloca (sizeof (char *) * (n_files + 1));
4901e4b17023SJohn Marino
4902e4b17023SJohn Marino /* Copy the strings over. */
4903e4b17023SJohn Marino for (i = 0, j = 0; i < n_infiles; i++)
4904e4b17023SJohn Marino if (compile_input_file_p (&infiles[i]))
4905e4b17023SJohn Marino {
4906e4b17023SJohn Marino argv[j] = CONST_CAST (char *, infiles[i].name);
4907e4b17023SJohn Marino infiles[i].compiled = true;
4908e4b17023SJohn Marino j++;
4909e4b17023SJohn Marino }
4910e4b17023SJohn Marino argv[j] = NULL;
4911e4b17023SJohn Marino
4912e4b17023SJohn Marino create_at_file (argv);
4913e4b17023SJohn Marino }
4914e4b17023SJohn Marino else
4915e4b17023SJohn Marino for (i = 0; (int) i < n_infiles; i++)
4916e4b17023SJohn Marino if (compile_input_file_p (&infiles[i]))
4917e4b17023SJohn Marino {
4918e4b17023SJohn Marino store_arg (infiles[i].name, 0, 0);
4919e4b17023SJohn Marino infiles[i].compiled = true;
4920e4b17023SJohn Marino }
4921e4b17023SJohn Marino }
4922e4b17023SJohn Marino else
4923e4b17023SJohn Marino {
4924e4b17023SJohn Marino obstack_grow (&obstack, gcc_input_filename,
4925e4b17023SJohn Marino input_filename_length);
4926e4b17023SJohn Marino arg_going = 1;
4927e4b17023SJohn Marino }
4928e4b17023SJohn Marino break;
4929e4b17023SJohn Marino
4930e4b17023SJohn Marino case 'I':
4931e4b17023SJohn Marino {
4932e4b17023SJohn Marino struct spec_path_info info;
4933e4b17023SJohn Marino
4934e4b17023SJohn Marino if (multilib_dir)
4935e4b17023SJohn Marino {
4936e4b17023SJohn Marino do_spec_1 ("-imultilib", 1, NULL);
4937e4b17023SJohn Marino /* Make this a separate argument. */
4938e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4939e4b17023SJohn Marino do_spec_1 (multilib_dir, 1, NULL);
4940e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4941e4b17023SJohn Marino }
4942e4b17023SJohn Marino
49435ce9237cSJohn Marino if (multiarch_dir)
49445ce9237cSJohn Marino {
49455ce9237cSJohn Marino do_spec_1 ("-imultiarch", 1, NULL);
49465ce9237cSJohn Marino /* Make this a separate argument. */
49475ce9237cSJohn Marino do_spec_1 (" ", 0, NULL);
49485ce9237cSJohn Marino do_spec_1 (multiarch_dir, 1, NULL);
49495ce9237cSJohn Marino do_spec_1 (" ", 0, NULL);
49505ce9237cSJohn Marino }
49515ce9237cSJohn Marino
4952e4b17023SJohn Marino if (gcc_exec_prefix)
4953e4b17023SJohn Marino {
4954e4b17023SJohn Marino do_spec_1 ("-iprefix", 1, NULL);
4955e4b17023SJohn Marino /* Make this a separate argument. */
4956e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4957e4b17023SJohn Marino do_spec_1 (gcc_exec_prefix, 1, NULL);
4958e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4959e4b17023SJohn Marino }
4960e4b17023SJohn Marino
4961e4b17023SJohn Marino if (target_system_root_changed ||
4962e4b17023SJohn Marino (target_system_root && target_sysroot_hdrs_suffix))
4963e4b17023SJohn Marino {
4964e4b17023SJohn Marino do_spec_1 ("-isysroot", 1, NULL);
4965e4b17023SJohn Marino /* Make this a separate argument. */
4966e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4967e4b17023SJohn Marino do_spec_1 (target_system_root, 1, NULL);
4968e4b17023SJohn Marino if (target_sysroot_hdrs_suffix)
4969e4b17023SJohn Marino do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
4970e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
4971e4b17023SJohn Marino }
4972e4b17023SJohn Marino
4973e4b17023SJohn Marino info.option = "-isystem";
4974e4b17023SJohn Marino info.append = "include";
4975e4b17023SJohn Marino info.append_len = strlen (info.append);
4976e4b17023SJohn Marino info.omit_relative = false;
4977e4b17023SJohn Marino info.separate_options = true;
4978e4b17023SJohn Marino
4979e4b17023SJohn Marino for_each_path (&include_prefixes, false, info.append_len,
4980e4b17023SJohn Marino spec_path, &info);
4981e4b17023SJohn Marino
4982e4b17023SJohn Marino info.append = "include-fixed";
4983e4b17023SJohn Marino if (*sysroot_hdrs_suffix_spec)
4984e4b17023SJohn Marino info.append = concat (info.append, dir_separator_str,
4985e4b17023SJohn Marino multilib_dir, NULL);
4986e4b17023SJohn Marino info.append_len = strlen (info.append);
4987e4b17023SJohn Marino for_each_path (&include_prefixes, false, info.append_len,
4988e4b17023SJohn Marino spec_path, &info);
4989e4b17023SJohn Marino }
4990e4b17023SJohn Marino break;
4991e4b17023SJohn Marino
4992e4b17023SJohn Marino case 'o':
4993e4b17023SJohn Marino {
4994e4b17023SJohn Marino int max = n_infiles;
4995e4b17023SJohn Marino max += lang_specific_extra_outfiles;
4996e4b17023SJohn Marino
4997e4b17023SJohn Marino if (HAVE_GNU_LD && at_file_supplied)
4998e4b17023SJohn Marino {
4999e4b17023SJohn Marino /* We are going to expand `%o' to `@FILE', where FILE
5000e4b17023SJohn Marino is a newly-created temporary filename. The filenames
5001e4b17023SJohn Marino that would usually be expanded in place of %o will be
5002e4b17023SJohn Marino written to the temporary file. */
5003e4b17023SJohn Marino
5004e4b17023SJohn Marino char **argv;
5005e4b17023SJohn Marino int n_files, j;
5006e4b17023SJohn Marino
5007e4b17023SJohn Marino /* Convert OUTFILES into a form suitable for writeargv. */
5008e4b17023SJohn Marino
5009e4b17023SJohn Marino /* Determine how many are non-NULL. */
5010e4b17023SJohn Marino for (n_files = 0, i = 0; i < max; i++)
5011e4b17023SJohn Marino n_files += outfiles[i] != NULL;
5012e4b17023SJohn Marino
5013e4b17023SJohn Marino argv = (char **) alloca (sizeof (char *) * (n_files + 1));
5014e4b17023SJohn Marino
5015e4b17023SJohn Marino /* Copy the strings over. */
5016e4b17023SJohn Marino for (i = 0, j = 0; i < max; i++)
5017e4b17023SJohn Marino if (outfiles[i])
5018e4b17023SJohn Marino {
5019e4b17023SJohn Marino argv[j] = CONST_CAST (char *, outfiles[i]);
5020e4b17023SJohn Marino j++;
5021e4b17023SJohn Marino }
5022e4b17023SJohn Marino argv[j] = NULL;
5023e4b17023SJohn Marino
5024e4b17023SJohn Marino create_at_file (argv);
5025e4b17023SJohn Marino }
5026e4b17023SJohn Marino else
5027e4b17023SJohn Marino for (i = 0; i < max; i++)
5028e4b17023SJohn Marino if (outfiles[i])
5029e4b17023SJohn Marino store_arg (outfiles[i], 0, 0);
5030e4b17023SJohn Marino break;
5031e4b17023SJohn Marino }
5032e4b17023SJohn Marino
5033e4b17023SJohn Marino case 'O':
5034e4b17023SJohn Marino obstack_grow (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
5035e4b17023SJohn Marino arg_going = 1;
5036e4b17023SJohn Marino break;
5037e4b17023SJohn Marino
5038e4b17023SJohn Marino case 's':
5039e4b17023SJohn Marino this_is_library_file = 1;
5040e4b17023SJohn Marino break;
5041e4b17023SJohn Marino
5042e4b17023SJohn Marino case 'T':
5043e4b17023SJohn Marino this_is_linker_script = 1;
5044e4b17023SJohn Marino break;
5045e4b17023SJohn Marino
5046e4b17023SJohn Marino case 'V':
5047e4b17023SJohn Marino outfiles[input_file_number] = NULL;
5048e4b17023SJohn Marino break;
5049e4b17023SJohn Marino
5050e4b17023SJohn Marino case 'w':
5051e4b17023SJohn Marino this_is_output_file = 1;
5052e4b17023SJohn Marino break;
5053e4b17023SJohn Marino
5054e4b17023SJohn Marino case 'W':
5055e4b17023SJohn Marino {
5056e4b17023SJohn Marino unsigned int cur_index = VEC_length (const_char_p, argbuf);
5057e4b17023SJohn Marino /* Handle the {...} following the %W. */
5058e4b17023SJohn Marino if (*p != '{')
5059e4b17023SJohn Marino fatal_error ("spec %qs has invalid %<%%W%c%>", spec, *p);
5060e4b17023SJohn Marino p = handle_braces (p + 1);
5061e4b17023SJohn Marino if (p == 0)
5062e4b17023SJohn Marino return -1;
5063e4b17023SJohn Marino end_going_arg ();
5064e4b17023SJohn Marino /* If any args were output, mark the last one for deletion
5065e4b17023SJohn Marino on failure. */
5066e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) != cur_index)
5067e4b17023SJohn Marino record_temp_file (VEC_last (const_char_p, argbuf), 0, 1);
5068e4b17023SJohn Marino break;
5069e4b17023SJohn Marino }
5070e4b17023SJohn Marino
5071e4b17023SJohn Marino /* %x{OPTION} records OPTION for %X to output. */
5072e4b17023SJohn Marino case 'x':
5073e4b17023SJohn Marino {
5074e4b17023SJohn Marino const char *p1 = p;
5075e4b17023SJohn Marino char *string;
5076e4b17023SJohn Marino char *opt;
5077e4b17023SJohn Marino unsigned ix;
5078e4b17023SJohn Marino
5079e4b17023SJohn Marino /* Skip past the option value and make a copy. */
5080e4b17023SJohn Marino if (*p != '{')
5081e4b17023SJohn Marino fatal_error ("spec %qs has invalid %<%%x%c%>", spec, *p);
5082e4b17023SJohn Marino while (*p++ != '}')
5083e4b17023SJohn Marino ;
5084e4b17023SJohn Marino string = save_string (p1 + 1, p - p1 - 2);
5085e4b17023SJohn Marino
5086e4b17023SJohn Marino /* See if we already recorded this option. */
5087e4b17023SJohn Marino FOR_EACH_VEC_ELT (char_p, linker_options, ix, opt)
5088e4b17023SJohn Marino if (! strcmp (string, opt))
5089e4b17023SJohn Marino {
5090e4b17023SJohn Marino free (string);
5091e4b17023SJohn Marino return 0;
5092e4b17023SJohn Marino }
5093e4b17023SJohn Marino
5094e4b17023SJohn Marino /* This option is new; add it. */
5095e4b17023SJohn Marino add_linker_option (string, strlen (string));
5096e4b17023SJohn Marino }
5097e4b17023SJohn Marino break;
5098e4b17023SJohn Marino
5099e4b17023SJohn Marino /* Dump out the options accumulated previously using %x. */
5100e4b17023SJohn Marino case 'X':
5101e4b17023SJohn Marino do_specs_vec (linker_options);
5102e4b17023SJohn Marino break;
5103e4b17023SJohn Marino
5104e4b17023SJohn Marino /* Dump out the options accumulated previously using -Wa,. */
5105e4b17023SJohn Marino case 'Y':
5106e4b17023SJohn Marino do_specs_vec (assembler_options);
5107e4b17023SJohn Marino break;
5108e4b17023SJohn Marino
5109e4b17023SJohn Marino /* Dump out the options accumulated previously using -Wp,. */
5110e4b17023SJohn Marino case 'Z':
5111e4b17023SJohn Marino do_specs_vec (preprocessor_options);
5112e4b17023SJohn Marino break;
5113e4b17023SJohn Marino
5114e4b17023SJohn Marino /* Here are digits and numbers that just process
5115e4b17023SJohn Marino a certain constant string as a spec. */
5116e4b17023SJohn Marino
5117e4b17023SJohn Marino case '1':
5118e4b17023SJohn Marino value = do_spec_1 (cc1_spec, 0, NULL);
5119e4b17023SJohn Marino if (value != 0)
5120e4b17023SJohn Marino return value;
5121e4b17023SJohn Marino break;
5122e4b17023SJohn Marino
5123e4b17023SJohn Marino case '2':
5124e4b17023SJohn Marino value = do_spec_1 (cc1plus_spec, 0, NULL);
5125e4b17023SJohn Marino if (value != 0)
5126e4b17023SJohn Marino return value;
5127e4b17023SJohn Marino break;
5128e4b17023SJohn Marino
5129e4b17023SJohn Marino case 'a':
5130e4b17023SJohn Marino value = do_spec_1 (asm_spec, 0, NULL);
5131e4b17023SJohn Marino if (value != 0)
5132e4b17023SJohn Marino return value;
5133e4b17023SJohn Marino break;
5134e4b17023SJohn Marino
5135e4b17023SJohn Marino case 'A':
5136e4b17023SJohn Marino value = do_spec_1 (asm_final_spec, 0, NULL);
5137e4b17023SJohn Marino if (value != 0)
5138e4b17023SJohn Marino return value;
5139e4b17023SJohn Marino break;
5140e4b17023SJohn Marino
5141e4b17023SJohn Marino case 'C':
5142e4b17023SJohn Marino {
5143e4b17023SJohn Marino const char *const spec
5144e4b17023SJohn Marino = (input_file_compiler->cpp_spec
5145e4b17023SJohn Marino ? input_file_compiler->cpp_spec
5146e4b17023SJohn Marino : cpp_spec);
5147e4b17023SJohn Marino value = do_spec_1 (spec, 0, NULL);
5148e4b17023SJohn Marino if (value != 0)
5149e4b17023SJohn Marino return value;
5150e4b17023SJohn Marino }
5151e4b17023SJohn Marino break;
5152e4b17023SJohn Marino
5153e4b17023SJohn Marino case 'E':
5154e4b17023SJohn Marino value = do_spec_1 (endfile_spec, 0, NULL);
5155e4b17023SJohn Marino if (value != 0)
5156e4b17023SJohn Marino return value;
5157e4b17023SJohn Marino break;
5158e4b17023SJohn Marino
5159e4b17023SJohn Marino case 'l':
5160e4b17023SJohn Marino value = do_spec_1 (link_spec, 0, NULL);
5161e4b17023SJohn Marino if (value != 0)
5162e4b17023SJohn Marino return value;
5163e4b17023SJohn Marino break;
5164e4b17023SJohn Marino
5165e4b17023SJohn Marino case 'L':
5166e4b17023SJohn Marino value = do_spec_1 (lib_spec, 0, NULL);
5167e4b17023SJohn Marino if (value != 0)
5168e4b17023SJohn Marino return value;
5169e4b17023SJohn Marino break;
5170e4b17023SJohn Marino
5171e4b17023SJohn Marino case 'G':
5172e4b17023SJohn Marino value = do_spec_1 (libgcc_spec, 0, NULL);
5173e4b17023SJohn Marino if (value != 0)
5174e4b17023SJohn Marino return value;
5175e4b17023SJohn Marino break;
5176e4b17023SJohn Marino
5177e4b17023SJohn Marino case 'R':
5178e4b17023SJohn Marino /* We assume there is a directory
5179e4b17023SJohn Marino separator at the end of this string. */
5180e4b17023SJohn Marino if (target_system_root)
5181e4b17023SJohn Marino {
5182e4b17023SJohn Marino obstack_grow (&obstack, target_system_root,
5183e4b17023SJohn Marino strlen (target_system_root));
5184e4b17023SJohn Marino if (target_sysroot_suffix)
5185e4b17023SJohn Marino obstack_grow (&obstack, target_sysroot_suffix,
5186e4b17023SJohn Marino strlen (target_sysroot_suffix));
5187e4b17023SJohn Marino }
5188e4b17023SJohn Marino break;
5189e4b17023SJohn Marino
5190e4b17023SJohn Marino case 'S':
5191e4b17023SJohn Marino value = do_spec_1 (startfile_spec, 0, NULL);
5192e4b17023SJohn Marino if (value != 0)
5193e4b17023SJohn Marino return value;
5194e4b17023SJohn Marino break;
5195e4b17023SJohn Marino
5196e4b17023SJohn Marino /* Here we define characters other than letters and digits. */
5197e4b17023SJohn Marino
5198e4b17023SJohn Marino case '{':
5199e4b17023SJohn Marino p = handle_braces (p);
5200e4b17023SJohn Marino if (p == 0)
5201e4b17023SJohn Marino return -1;
5202e4b17023SJohn Marino break;
5203e4b17023SJohn Marino
5204e4b17023SJohn Marino case ':':
5205e4b17023SJohn Marino p = handle_spec_function (p);
5206e4b17023SJohn Marino if (p == 0)
5207e4b17023SJohn Marino return -1;
5208e4b17023SJohn Marino break;
5209e4b17023SJohn Marino
5210e4b17023SJohn Marino case '%':
5211e4b17023SJohn Marino obstack_1grow (&obstack, '%');
5212e4b17023SJohn Marino break;
5213e4b17023SJohn Marino
5214e4b17023SJohn Marino case '.':
5215e4b17023SJohn Marino {
5216e4b17023SJohn Marino unsigned len = 0;
5217e4b17023SJohn Marino
5218e4b17023SJohn Marino while (p[len] && p[len] != ' ' && p[len] != '%')
5219e4b17023SJohn Marino len++;
5220e4b17023SJohn Marino suffix_subst = save_string (p - 1, len + 1);
5221e4b17023SJohn Marino p += len;
5222e4b17023SJohn Marino }
5223e4b17023SJohn Marino break;
5224e4b17023SJohn Marino
5225e4b17023SJohn Marino /* Henceforth ignore the option(s) matching the pattern
5226e4b17023SJohn Marino after the %<. */
5227e4b17023SJohn Marino case '<':
5228e4b17023SJohn Marino case '>':
5229e4b17023SJohn Marino {
5230e4b17023SJohn Marino unsigned len = 0;
5231e4b17023SJohn Marino int have_wildcard = 0;
5232e4b17023SJohn Marino int i;
5233e4b17023SJohn Marino int switch_option;
5234e4b17023SJohn Marino
5235e4b17023SJohn Marino if (c == '>')
5236e4b17023SJohn Marino switch_option = SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC;
5237e4b17023SJohn Marino else
5238e4b17023SJohn Marino switch_option = SWITCH_IGNORE;
5239e4b17023SJohn Marino
5240e4b17023SJohn Marino while (p[len] && p[len] != ' ' && p[len] != '\t')
5241e4b17023SJohn Marino len++;
5242e4b17023SJohn Marino
5243e4b17023SJohn Marino if (p[len-1] == '*')
5244e4b17023SJohn Marino have_wildcard = 1;
5245e4b17023SJohn Marino
5246e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
5247e4b17023SJohn Marino if (!strncmp (switches[i].part1, p, len - have_wildcard)
5248e4b17023SJohn Marino && (have_wildcard || switches[i].part1[len] == '\0'))
5249e4b17023SJohn Marino {
5250e4b17023SJohn Marino switches[i].live_cond |= switch_option;
5251e4b17023SJohn Marino switches[i].validated = 1;
5252e4b17023SJohn Marino }
5253e4b17023SJohn Marino
5254e4b17023SJohn Marino p += len;
5255e4b17023SJohn Marino }
5256e4b17023SJohn Marino break;
5257e4b17023SJohn Marino
5258e4b17023SJohn Marino case '*':
5259e4b17023SJohn Marino if (soft_matched_part)
5260e4b17023SJohn Marino {
5261e4b17023SJohn Marino if (soft_matched_part[0])
5262e4b17023SJohn Marino do_spec_1 (soft_matched_part, 1, NULL);
5263e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
5264e4b17023SJohn Marino }
5265e4b17023SJohn Marino else
5266e4b17023SJohn Marino /* Catch the case where a spec string contains something like
5267e4b17023SJohn Marino '%{foo:%*}'. i.e. there is no * in the pattern on the left
5268e4b17023SJohn Marino hand side of the :. */
5269e4b17023SJohn Marino error ("spec failure: %<%%*%> has not been initialized by pattern match");
5270e4b17023SJohn Marino break;
5271e4b17023SJohn Marino
5272e4b17023SJohn Marino /* Process a string found as the value of a spec given by name.
5273e4b17023SJohn Marino This feature allows individual machine descriptions
5274e4b17023SJohn Marino to add and use their own specs. */
5275e4b17023SJohn Marino case '(':
5276e4b17023SJohn Marino {
5277e4b17023SJohn Marino const char *name = p;
5278e4b17023SJohn Marino struct spec_list *sl;
5279e4b17023SJohn Marino int len;
5280e4b17023SJohn Marino
5281e4b17023SJohn Marino /* The string after the S/P is the name of a spec that is to be
5282e4b17023SJohn Marino processed. */
5283e4b17023SJohn Marino while (*p && *p != ')')
5284e4b17023SJohn Marino p++;
5285e4b17023SJohn Marino
5286e4b17023SJohn Marino /* See if it's in the list. */
5287e4b17023SJohn Marino for (len = p - name, sl = specs; sl; sl = sl->next)
5288e4b17023SJohn Marino if (sl->name_len == len && !strncmp (sl->name, name, len))
5289e4b17023SJohn Marino {
5290e4b17023SJohn Marino name = *(sl->ptr_spec);
5291e4b17023SJohn Marino #ifdef DEBUG_SPECS
5292e4b17023SJohn Marino fnotice (stderr, "Processing spec (%s), which is '%s'\n",
5293e4b17023SJohn Marino sl->name, name);
5294e4b17023SJohn Marino #endif
5295e4b17023SJohn Marino break;
5296e4b17023SJohn Marino }
5297e4b17023SJohn Marino
5298e4b17023SJohn Marino if (sl)
5299e4b17023SJohn Marino {
5300e4b17023SJohn Marino value = do_spec_1 (name, 0, NULL);
5301e4b17023SJohn Marino if (value != 0)
5302e4b17023SJohn Marino return value;
5303e4b17023SJohn Marino }
5304e4b17023SJohn Marino
5305e4b17023SJohn Marino /* Discard the closing paren. */
5306e4b17023SJohn Marino if (*p)
5307e4b17023SJohn Marino p++;
5308e4b17023SJohn Marino }
5309e4b17023SJohn Marino break;
5310e4b17023SJohn Marino
5311e4b17023SJohn Marino default:
5312e4b17023SJohn Marino error ("spec failure: unrecognized spec option %qc", c);
5313e4b17023SJohn Marino break;
5314e4b17023SJohn Marino }
5315e4b17023SJohn Marino break;
5316e4b17023SJohn Marino
5317e4b17023SJohn Marino case '\\':
5318e4b17023SJohn Marino /* Backslash: treat next character as ordinary. */
5319e4b17023SJohn Marino c = *p++;
5320e4b17023SJohn Marino
5321e4b17023SJohn Marino /* Fall through. */
5322e4b17023SJohn Marino default:
5323e4b17023SJohn Marino /* Ordinary character: put it into the current argument. */
5324e4b17023SJohn Marino obstack_1grow (&obstack, c);
5325e4b17023SJohn Marino arg_going = 1;
5326e4b17023SJohn Marino }
5327e4b17023SJohn Marino
5328e4b17023SJohn Marino /* End of string. If we are processing a spec function, we need to
5329e4b17023SJohn Marino end any pending argument. */
5330e4b17023SJohn Marino if (processing_spec_function)
5331e4b17023SJohn Marino end_going_arg ();
5332e4b17023SJohn Marino
5333e4b17023SJohn Marino return 0;
5334e4b17023SJohn Marino }
5335e4b17023SJohn Marino
5336e4b17023SJohn Marino /* Look up a spec function. */
5337e4b17023SJohn Marino
5338e4b17023SJohn Marino static const struct spec_function *
lookup_spec_function(const char * name)5339e4b17023SJohn Marino lookup_spec_function (const char *name)
5340e4b17023SJohn Marino {
5341e4b17023SJohn Marino const struct spec_function *sf;
5342e4b17023SJohn Marino
5343e4b17023SJohn Marino for (sf = static_spec_functions; sf->name != NULL; sf++)
5344e4b17023SJohn Marino if (strcmp (sf->name, name) == 0)
5345e4b17023SJohn Marino return sf;
5346e4b17023SJohn Marino
5347e4b17023SJohn Marino return NULL;
5348e4b17023SJohn Marino }
5349e4b17023SJohn Marino
5350e4b17023SJohn Marino /* Evaluate a spec function. */
5351e4b17023SJohn Marino
5352e4b17023SJohn Marino static const char *
eval_spec_function(const char * func,const char * args)5353e4b17023SJohn Marino eval_spec_function (const char *func, const char *args)
5354e4b17023SJohn Marino {
5355e4b17023SJohn Marino const struct spec_function *sf;
5356e4b17023SJohn Marino const char *funcval;
5357e4b17023SJohn Marino
5358e4b17023SJohn Marino /* Saved spec processing context. */
5359e4b17023SJohn Marino VEC(const_char_p,heap) *save_argbuf;
5360e4b17023SJohn Marino
5361e4b17023SJohn Marino int save_arg_going;
5362e4b17023SJohn Marino int save_delete_this_arg;
5363e4b17023SJohn Marino int save_this_is_output_file;
5364e4b17023SJohn Marino int save_this_is_library_file;
5365e4b17023SJohn Marino int save_input_from_pipe;
5366e4b17023SJohn Marino int save_this_is_linker_script;
5367e4b17023SJohn Marino const char *save_suffix_subst;
5368e4b17023SJohn Marino
5369e4b17023SJohn Marino
5370e4b17023SJohn Marino sf = lookup_spec_function (func);
5371e4b17023SJohn Marino if (sf == NULL)
5372e4b17023SJohn Marino fatal_error ("unknown spec function %qs", func);
5373e4b17023SJohn Marino
5374e4b17023SJohn Marino /* Push the spec processing context. */
5375e4b17023SJohn Marino save_argbuf = argbuf;
5376e4b17023SJohn Marino
5377e4b17023SJohn Marino save_arg_going = arg_going;
5378e4b17023SJohn Marino save_delete_this_arg = delete_this_arg;
5379e4b17023SJohn Marino save_this_is_output_file = this_is_output_file;
5380e4b17023SJohn Marino save_this_is_library_file = this_is_library_file;
5381e4b17023SJohn Marino save_this_is_linker_script = this_is_linker_script;
5382e4b17023SJohn Marino save_input_from_pipe = input_from_pipe;
5383e4b17023SJohn Marino save_suffix_subst = suffix_subst;
5384e4b17023SJohn Marino
5385e4b17023SJohn Marino /* Create a new spec processing context, and build the function
5386e4b17023SJohn Marino arguments. */
5387e4b17023SJohn Marino
5388e4b17023SJohn Marino alloc_args ();
5389e4b17023SJohn Marino if (do_spec_2 (args) < 0)
5390e4b17023SJohn Marino fatal_error ("error in args to spec function %qs", func);
5391e4b17023SJohn Marino
5392e4b17023SJohn Marino /* argbuf_index is an index for the next argument to be inserted, and
5393e4b17023SJohn Marino so contains the count of the args already inserted. */
5394e4b17023SJohn Marino
5395e4b17023SJohn Marino funcval = (*sf->func) (VEC_length (const_char_p, argbuf),
5396e4b17023SJohn Marino VEC_address (const_char_p, argbuf));
5397e4b17023SJohn Marino
5398e4b17023SJohn Marino /* Pop the spec processing context. */
5399e4b17023SJohn Marino VEC_free (const_char_p, heap, argbuf);
5400e4b17023SJohn Marino argbuf = save_argbuf;
5401e4b17023SJohn Marino
5402e4b17023SJohn Marino arg_going = save_arg_going;
5403e4b17023SJohn Marino delete_this_arg = save_delete_this_arg;
5404e4b17023SJohn Marino this_is_output_file = save_this_is_output_file;
5405e4b17023SJohn Marino this_is_library_file = save_this_is_library_file;
5406e4b17023SJohn Marino this_is_linker_script = save_this_is_linker_script;
5407e4b17023SJohn Marino input_from_pipe = save_input_from_pipe;
5408e4b17023SJohn Marino suffix_subst = save_suffix_subst;
5409e4b17023SJohn Marino
5410e4b17023SJohn Marino return funcval;
5411e4b17023SJohn Marino }
5412e4b17023SJohn Marino
5413e4b17023SJohn Marino /* Handle a spec function call of the form:
5414e4b17023SJohn Marino
5415e4b17023SJohn Marino %:function(args)
5416e4b17023SJohn Marino
5417e4b17023SJohn Marino ARGS is processed as a spec in a separate context and split into an
5418e4b17023SJohn Marino argument vector in the normal fashion. The function returns a string
5419e4b17023SJohn Marino containing a spec which we then process in the caller's context, or
5420e4b17023SJohn Marino NULL if no processing is required. */
5421e4b17023SJohn Marino
5422e4b17023SJohn Marino static const char *
handle_spec_function(const char * p)5423e4b17023SJohn Marino handle_spec_function (const char *p)
5424e4b17023SJohn Marino {
5425e4b17023SJohn Marino char *func, *args;
5426e4b17023SJohn Marino const char *endp, *funcval;
5427e4b17023SJohn Marino int count;
5428e4b17023SJohn Marino
5429e4b17023SJohn Marino processing_spec_function++;
5430e4b17023SJohn Marino
5431e4b17023SJohn Marino /* Get the function name. */
5432e4b17023SJohn Marino for (endp = p; *endp != '\0'; endp++)
5433e4b17023SJohn Marino {
5434e4b17023SJohn Marino if (*endp == '(') /* ) */
5435e4b17023SJohn Marino break;
5436e4b17023SJohn Marino /* Only allow [A-Za-z0-9], -, and _ in function names. */
5437e4b17023SJohn Marino if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
5438e4b17023SJohn Marino fatal_error ("malformed spec function name");
5439e4b17023SJohn Marino }
5440e4b17023SJohn Marino if (*endp != '(') /* ) */
5441e4b17023SJohn Marino fatal_error ("no arguments for spec function");
5442e4b17023SJohn Marino func = save_string (p, endp - p);
5443e4b17023SJohn Marino p = ++endp;
5444e4b17023SJohn Marino
5445e4b17023SJohn Marino /* Get the arguments. */
5446e4b17023SJohn Marino for (count = 0; *endp != '\0'; endp++)
5447e4b17023SJohn Marino {
5448e4b17023SJohn Marino /* ( */
5449e4b17023SJohn Marino if (*endp == ')')
5450e4b17023SJohn Marino {
5451e4b17023SJohn Marino if (count == 0)
5452e4b17023SJohn Marino break;
5453e4b17023SJohn Marino count--;
5454e4b17023SJohn Marino }
5455e4b17023SJohn Marino else if (*endp == '(') /* ) */
5456e4b17023SJohn Marino count++;
5457e4b17023SJohn Marino }
5458e4b17023SJohn Marino /* ( */
5459e4b17023SJohn Marino if (*endp != ')')
5460e4b17023SJohn Marino fatal_error ("malformed spec function arguments");
5461e4b17023SJohn Marino args = save_string (p, endp - p);
5462e4b17023SJohn Marino p = ++endp;
5463e4b17023SJohn Marino
5464e4b17023SJohn Marino /* p now points to just past the end of the spec function expression. */
5465e4b17023SJohn Marino
5466e4b17023SJohn Marino funcval = eval_spec_function (func, args);
5467e4b17023SJohn Marino if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
5468e4b17023SJohn Marino p = NULL;
5469e4b17023SJohn Marino
5470e4b17023SJohn Marino free (func);
5471e4b17023SJohn Marino free (args);
5472e4b17023SJohn Marino
5473e4b17023SJohn Marino processing_spec_function--;
5474e4b17023SJohn Marino
5475e4b17023SJohn Marino return p;
5476e4b17023SJohn Marino }
5477e4b17023SJohn Marino
5478e4b17023SJohn Marino /* Inline subroutine of handle_braces. Returns true if the current
5479e4b17023SJohn Marino input suffix matches the atom bracketed by ATOM and END_ATOM. */
5480e4b17023SJohn Marino static inline bool
input_suffix_matches(const char * atom,const char * end_atom)5481e4b17023SJohn Marino input_suffix_matches (const char *atom, const char *end_atom)
5482e4b17023SJohn Marino {
5483e4b17023SJohn Marino return (input_suffix
5484e4b17023SJohn Marino && !strncmp (input_suffix, atom, end_atom - atom)
5485e4b17023SJohn Marino && input_suffix[end_atom - atom] == '\0');
5486e4b17023SJohn Marino }
5487e4b17023SJohn Marino
5488e4b17023SJohn Marino /* Subroutine of handle_braces. Returns true if the current
5489e4b17023SJohn Marino input file's spec name matches the atom bracketed by ATOM and END_ATOM. */
5490e4b17023SJohn Marino static bool
input_spec_matches(const char * atom,const char * end_atom)5491e4b17023SJohn Marino input_spec_matches (const char *atom, const char *end_atom)
5492e4b17023SJohn Marino {
5493e4b17023SJohn Marino return (input_file_compiler
5494e4b17023SJohn Marino && input_file_compiler->suffix
5495e4b17023SJohn Marino && input_file_compiler->suffix[0] != '\0'
5496e4b17023SJohn Marino && !strncmp (input_file_compiler->suffix + 1, atom,
5497e4b17023SJohn Marino end_atom - atom)
5498e4b17023SJohn Marino && input_file_compiler->suffix[end_atom - atom + 1] == '\0');
5499e4b17023SJohn Marino }
5500e4b17023SJohn Marino
5501e4b17023SJohn Marino /* Subroutine of handle_braces. Returns true if a switch
5502e4b17023SJohn Marino matching the atom bracketed by ATOM and END_ATOM appeared on the
5503e4b17023SJohn Marino command line. */
5504e4b17023SJohn Marino static bool
switch_matches(const char * atom,const char * end_atom,int starred)5505e4b17023SJohn Marino switch_matches (const char *atom, const char *end_atom, int starred)
5506e4b17023SJohn Marino {
5507e4b17023SJohn Marino int i;
5508e4b17023SJohn Marino int len = end_atom - atom;
5509e4b17023SJohn Marino int plen = starred ? len : -1;
5510e4b17023SJohn Marino
5511e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
5512e4b17023SJohn Marino if (!strncmp (switches[i].part1, atom, len)
5513e4b17023SJohn Marino && (starred || switches[i].part1[len] == '\0')
5514e4b17023SJohn Marino && check_live_switch (i, plen))
5515e4b17023SJohn Marino return true;
5516e4b17023SJohn Marino
5517e4b17023SJohn Marino /* Check if a switch with separated form matching the atom.
5518e4b17023SJohn Marino We check -D and -U switches. */
5519e4b17023SJohn Marino else if (switches[i].args != 0)
5520e4b17023SJohn Marino {
5521e4b17023SJohn Marino if ((*switches[i].part1 == 'D' || *switches[i].part1 == 'U')
5522e4b17023SJohn Marino && *switches[i].part1 == atom[0])
5523e4b17023SJohn Marino {
5524e4b17023SJohn Marino if (!strncmp (switches[i].args[0], &atom[1], len - 1)
5525e4b17023SJohn Marino && (starred || (switches[i].part1[1] == '\0'
5526e4b17023SJohn Marino && switches[i].args[0][len - 1] == '\0'))
5527e4b17023SJohn Marino && check_live_switch (i, (starred ? 1 : -1)))
5528e4b17023SJohn Marino return true;
5529e4b17023SJohn Marino }
5530e4b17023SJohn Marino }
5531e4b17023SJohn Marino
5532e4b17023SJohn Marino return false;
5533e4b17023SJohn Marino }
5534e4b17023SJohn Marino
5535e4b17023SJohn Marino /* Inline subroutine of handle_braces. Mark all of the switches which
5536e4b17023SJohn Marino match ATOM (extends to END_ATOM; STARRED indicates whether there
5537e4b17023SJohn Marino was a star after the atom) for later processing. */
5538e4b17023SJohn Marino static inline void
mark_matching_switches(const char * atom,const char * end_atom,int starred)5539e4b17023SJohn Marino mark_matching_switches (const char *atom, const char *end_atom, int starred)
5540e4b17023SJohn Marino {
5541e4b17023SJohn Marino int i;
5542e4b17023SJohn Marino int len = end_atom - atom;
5543e4b17023SJohn Marino int plen = starred ? len : -1;
5544e4b17023SJohn Marino
5545e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
5546e4b17023SJohn Marino if (!strncmp (switches[i].part1, atom, len)
5547e4b17023SJohn Marino && (starred || switches[i].part1[len] == '\0')
5548e4b17023SJohn Marino && check_live_switch (i, plen))
5549e4b17023SJohn Marino switches[i].ordering = 1;
5550e4b17023SJohn Marino }
5551e4b17023SJohn Marino
5552e4b17023SJohn Marino /* Inline subroutine of handle_braces. Process all the currently
5553e4b17023SJohn Marino marked switches through give_switch, and clear the marks. */
5554e4b17023SJohn Marino static inline void
process_marked_switches(void)5555e4b17023SJohn Marino process_marked_switches (void)
5556e4b17023SJohn Marino {
5557e4b17023SJohn Marino int i;
5558e4b17023SJohn Marino
5559e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
5560e4b17023SJohn Marino if (switches[i].ordering == 1)
5561e4b17023SJohn Marino {
5562e4b17023SJohn Marino switches[i].ordering = 0;
5563e4b17023SJohn Marino give_switch (i, 0);
5564e4b17023SJohn Marino }
5565e4b17023SJohn Marino }
5566e4b17023SJohn Marino
5567e4b17023SJohn Marino /* Handle a %{ ... } construct. P points just inside the leading {.
5568e4b17023SJohn Marino Returns a pointer one past the end of the brace block, or 0
5569e4b17023SJohn Marino if we call do_spec_1 and that returns -1. */
5570e4b17023SJohn Marino
5571e4b17023SJohn Marino static const char *
handle_braces(const char * p)5572e4b17023SJohn Marino handle_braces (const char *p)
5573e4b17023SJohn Marino {
5574e4b17023SJohn Marino const char *atom, *end_atom;
5575e4b17023SJohn Marino const char *d_atom = NULL, *d_end_atom = NULL;
5576e4b17023SJohn Marino const char *orig = p;
5577e4b17023SJohn Marino
5578e4b17023SJohn Marino bool a_is_suffix;
5579e4b17023SJohn Marino bool a_is_spectype;
5580e4b17023SJohn Marino bool a_is_starred;
5581e4b17023SJohn Marino bool a_is_negated;
5582e4b17023SJohn Marino bool a_matched;
5583e4b17023SJohn Marino
5584e4b17023SJohn Marino bool a_must_be_last = false;
5585e4b17023SJohn Marino bool ordered_set = false;
5586e4b17023SJohn Marino bool disjunct_set = false;
5587e4b17023SJohn Marino bool disj_matched = false;
5588e4b17023SJohn Marino bool disj_starred = true;
5589e4b17023SJohn Marino bool n_way_choice = false;
5590e4b17023SJohn Marino bool n_way_matched = false;
5591e4b17023SJohn Marino
5592e4b17023SJohn Marino #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
5593e4b17023SJohn Marino
5594e4b17023SJohn Marino do
5595e4b17023SJohn Marino {
5596e4b17023SJohn Marino if (a_must_be_last)
5597e4b17023SJohn Marino goto invalid;
5598e4b17023SJohn Marino
5599e4b17023SJohn Marino /* Scan one "atom" (S in the description above of %{}, possibly
5600e4b17023SJohn Marino with '!', '.', '@', ',', or '*' modifiers). */
5601e4b17023SJohn Marino a_matched = false;
5602e4b17023SJohn Marino a_is_suffix = false;
5603e4b17023SJohn Marino a_is_starred = false;
5604e4b17023SJohn Marino a_is_negated = false;
5605e4b17023SJohn Marino a_is_spectype = false;
5606e4b17023SJohn Marino
5607e4b17023SJohn Marino SKIP_WHITE();
5608e4b17023SJohn Marino if (*p == '!')
5609e4b17023SJohn Marino p++, a_is_negated = true;
5610e4b17023SJohn Marino
5611e4b17023SJohn Marino SKIP_WHITE();
5612e4b17023SJohn Marino if (*p == '.')
5613e4b17023SJohn Marino p++, a_is_suffix = true;
5614e4b17023SJohn Marino else if (*p == ',')
5615e4b17023SJohn Marino p++, a_is_spectype = true;
5616e4b17023SJohn Marino
5617e4b17023SJohn Marino atom = p;
5618e4b17023SJohn Marino while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '='
5619e4b17023SJohn Marino || *p == ',' || *p == '.' || *p == '@')
5620e4b17023SJohn Marino p++;
5621e4b17023SJohn Marino end_atom = p;
5622e4b17023SJohn Marino
5623e4b17023SJohn Marino if (*p == '*')
5624e4b17023SJohn Marino p++, a_is_starred = 1;
5625e4b17023SJohn Marino
5626e4b17023SJohn Marino SKIP_WHITE();
5627e4b17023SJohn Marino switch (*p)
5628e4b17023SJohn Marino {
5629e4b17023SJohn Marino case '&': case '}':
5630e4b17023SJohn Marino /* Substitute the switch(es) indicated by the current atom. */
5631e4b17023SJohn Marino ordered_set = true;
5632e4b17023SJohn Marino if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
5633e4b17023SJohn Marino || a_is_spectype || atom == end_atom)
5634e4b17023SJohn Marino goto invalid;
5635e4b17023SJohn Marino
5636e4b17023SJohn Marino mark_matching_switches (atom, end_atom, a_is_starred);
5637e4b17023SJohn Marino
5638e4b17023SJohn Marino if (*p == '}')
5639e4b17023SJohn Marino process_marked_switches ();
5640e4b17023SJohn Marino break;
5641e4b17023SJohn Marino
5642e4b17023SJohn Marino case '|': case ':':
5643e4b17023SJohn Marino /* Substitute some text if the current atom appears as a switch
5644e4b17023SJohn Marino or suffix. */
5645e4b17023SJohn Marino disjunct_set = true;
5646e4b17023SJohn Marino if (ordered_set)
5647e4b17023SJohn Marino goto invalid;
5648e4b17023SJohn Marino
5649e4b17023SJohn Marino if (atom == end_atom)
5650e4b17023SJohn Marino {
5651e4b17023SJohn Marino if (!n_way_choice || disj_matched || *p == '|'
5652e4b17023SJohn Marino || a_is_negated || a_is_suffix || a_is_spectype
5653e4b17023SJohn Marino || a_is_starred)
5654e4b17023SJohn Marino goto invalid;
5655e4b17023SJohn Marino
5656e4b17023SJohn Marino /* An empty term may appear as the last choice of an
5657e4b17023SJohn Marino N-way choice set; it means "otherwise". */
5658e4b17023SJohn Marino a_must_be_last = true;
5659e4b17023SJohn Marino disj_matched = !n_way_matched;
5660e4b17023SJohn Marino disj_starred = false;
5661e4b17023SJohn Marino }
5662e4b17023SJohn Marino else
5663e4b17023SJohn Marino {
5664e4b17023SJohn Marino if ((a_is_suffix || a_is_spectype) && a_is_starred)
5665e4b17023SJohn Marino goto invalid;
5666e4b17023SJohn Marino
5667e4b17023SJohn Marino if (!a_is_starred)
5668e4b17023SJohn Marino disj_starred = false;
5669e4b17023SJohn Marino
5670e4b17023SJohn Marino /* Don't bother testing this atom if we already have a
5671e4b17023SJohn Marino match. */
5672e4b17023SJohn Marino if (!disj_matched && !n_way_matched)
5673e4b17023SJohn Marino {
5674e4b17023SJohn Marino if (a_is_suffix)
5675e4b17023SJohn Marino a_matched = input_suffix_matches (atom, end_atom);
5676e4b17023SJohn Marino else if (a_is_spectype)
5677e4b17023SJohn Marino a_matched = input_spec_matches (atom, end_atom);
5678e4b17023SJohn Marino else
5679e4b17023SJohn Marino a_matched = switch_matches (atom, end_atom, a_is_starred);
5680e4b17023SJohn Marino
5681e4b17023SJohn Marino if (a_matched != a_is_negated)
5682e4b17023SJohn Marino {
5683e4b17023SJohn Marino disj_matched = true;
5684e4b17023SJohn Marino d_atom = atom;
5685e4b17023SJohn Marino d_end_atom = end_atom;
5686e4b17023SJohn Marino }
5687e4b17023SJohn Marino }
5688e4b17023SJohn Marino }
5689e4b17023SJohn Marino
5690e4b17023SJohn Marino if (*p == ':')
5691e4b17023SJohn Marino {
5692e4b17023SJohn Marino /* Found the body, that is, the text to substitute if the
5693e4b17023SJohn Marino current disjunction matches. */
5694e4b17023SJohn Marino p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
5695e4b17023SJohn Marino disj_matched && !n_way_matched);
5696e4b17023SJohn Marino if (p == 0)
5697e4b17023SJohn Marino return 0;
5698e4b17023SJohn Marino
5699e4b17023SJohn Marino /* If we have an N-way choice, reset state for the next
5700e4b17023SJohn Marino disjunction. */
5701e4b17023SJohn Marino if (*p == ';')
5702e4b17023SJohn Marino {
5703e4b17023SJohn Marino n_way_choice = true;
5704e4b17023SJohn Marino n_way_matched |= disj_matched;
5705e4b17023SJohn Marino disj_matched = false;
5706e4b17023SJohn Marino disj_starred = true;
5707e4b17023SJohn Marino d_atom = d_end_atom = NULL;
5708e4b17023SJohn Marino }
5709e4b17023SJohn Marino }
5710e4b17023SJohn Marino break;
5711e4b17023SJohn Marino
5712e4b17023SJohn Marino default:
5713e4b17023SJohn Marino goto invalid;
5714e4b17023SJohn Marino }
5715e4b17023SJohn Marino }
5716e4b17023SJohn Marino while (*p++ != '}');
5717e4b17023SJohn Marino
5718e4b17023SJohn Marino return p;
5719e4b17023SJohn Marino
5720e4b17023SJohn Marino invalid:
5721e4b17023SJohn Marino fatal_error ("braced spec %qs is invalid at %qc", orig, *p);
5722e4b17023SJohn Marino
5723e4b17023SJohn Marino #undef SKIP_WHITE
5724e4b17023SJohn Marino }
5725e4b17023SJohn Marino
5726e4b17023SJohn Marino /* Subroutine of handle_braces. Scan and process a brace substitution body
5727e4b17023SJohn Marino (X in the description of %{} syntax). P points one past the colon;
5728e4b17023SJohn Marino ATOM and END_ATOM bracket the first atom which was found to be true
5729e4b17023SJohn Marino (present) in the current disjunction; STARRED indicates whether all
5730e4b17023SJohn Marino the atoms in the current disjunction were starred (for syntax validation);
5731e4b17023SJohn Marino MATCHED indicates whether the disjunction matched or not, and therefore
5732e4b17023SJohn Marino whether or not the body is to be processed through do_spec_1 or just
5733e4b17023SJohn Marino skipped. Returns a pointer to the closing } or ;, or 0 if do_spec_1
5734e4b17023SJohn Marino returns -1. */
5735e4b17023SJohn Marino
5736e4b17023SJohn Marino static const char *
process_brace_body(const char * p,const char * atom,const char * end_atom,int starred,int matched)5737e4b17023SJohn Marino process_brace_body (const char *p, const char *atom, const char *end_atom,
5738e4b17023SJohn Marino int starred, int matched)
5739e4b17023SJohn Marino {
5740e4b17023SJohn Marino const char *body, *end_body;
5741e4b17023SJohn Marino unsigned int nesting_level;
5742e4b17023SJohn Marino bool have_subst = false;
5743e4b17023SJohn Marino
5744e4b17023SJohn Marino /* Locate the closing } or ;, honoring nested braces.
5745e4b17023SJohn Marino Trim trailing whitespace. */
5746e4b17023SJohn Marino body = p;
5747e4b17023SJohn Marino nesting_level = 1;
5748e4b17023SJohn Marino for (;;)
5749e4b17023SJohn Marino {
5750e4b17023SJohn Marino if (*p == '{')
5751e4b17023SJohn Marino nesting_level++;
5752e4b17023SJohn Marino else if (*p == '}')
5753e4b17023SJohn Marino {
5754e4b17023SJohn Marino if (!--nesting_level)
5755e4b17023SJohn Marino break;
5756e4b17023SJohn Marino }
5757e4b17023SJohn Marino else if (*p == ';' && nesting_level == 1)
5758e4b17023SJohn Marino break;
5759e4b17023SJohn Marino else if (*p == '%' && p[1] == '*' && nesting_level == 1)
5760e4b17023SJohn Marino have_subst = true;
5761e4b17023SJohn Marino else if (*p == '\0')
5762e4b17023SJohn Marino goto invalid;
5763e4b17023SJohn Marino p++;
5764e4b17023SJohn Marino }
5765e4b17023SJohn Marino
5766e4b17023SJohn Marino end_body = p;
5767e4b17023SJohn Marino while (end_body[-1] == ' ' || end_body[-1] == '\t')
5768e4b17023SJohn Marino end_body--;
5769e4b17023SJohn Marino
5770e4b17023SJohn Marino if (have_subst && !starred)
5771e4b17023SJohn Marino goto invalid;
5772e4b17023SJohn Marino
5773e4b17023SJohn Marino if (matched)
5774e4b17023SJohn Marino {
5775e4b17023SJohn Marino /* Copy the substitution body to permanent storage and execute it.
5776e4b17023SJohn Marino If have_subst is false, this is a simple matter of running the
5777e4b17023SJohn Marino body through do_spec_1... */
5778e4b17023SJohn Marino char *string = save_string (body, end_body - body);
5779e4b17023SJohn Marino if (!have_subst)
5780e4b17023SJohn Marino {
5781e4b17023SJohn Marino if (do_spec_1 (string, 0, NULL) < 0)
5782e4b17023SJohn Marino return 0;
5783e4b17023SJohn Marino }
5784e4b17023SJohn Marino else
5785e4b17023SJohn Marino {
5786e4b17023SJohn Marino /* ... but if have_subst is true, we have to process the
5787e4b17023SJohn Marino body once for each matching switch, with %* set to the
5788e4b17023SJohn Marino variant part of the switch. */
5789e4b17023SJohn Marino unsigned int hard_match_len = end_atom - atom;
5790e4b17023SJohn Marino int i;
5791e4b17023SJohn Marino
5792e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
5793e4b17023SJohn Marino if (!strncmp (switches[i].part1, atom, hard_match_len)
5794e4b17023SJohn Marino && check_live_switch (i, hard_match_len))
5795e4b17023SJohn Marino {
5796e4b17023SJohn Marino if (do_spec_1 (string, 0,
5797e4b17023SJohn Marino &switches[i].part1[hard_match_len]) < 0)
5798e4b17023SJohn Marino return 0;
5799e4b17023SJohn Marino /* Pass any arguments this switch has. */
5800e4b17023SJohn Marino give_switch (i, 1);
5801e4b17023SJohn Marino suffix_subst = NULL;
5802e4b17023SJohn Marino }
5803e4b17023SJohn Marino }
5804e4b17023SJohn Marino }
5805e4b17023SJohn Marino
5806e4b17023SJohn Marino return p;
5807e4b17023SJohn Marino
5808e4b17023SJohn Marino invalid:
5809e4b17023SJohn Marino fatal_error ("braced spec body %qs is invalid", body);
5810e4b17023SJohn Marino }
5811e4b17023SJohn Marino
5812e4b17023SJohn Marino /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
5813e4b17023SJohn Marino on the command line. PREFIX_LENGTH is the length of XXX in an {XXX*}
5814e4b17023SJohn Marino spec, or -1 if either exact match or %* is used.
5815e4b17023SJohn Marino
5816e4b17023SJohn Marino A -O switch is obsoleted by a later -O switch. A -f, -m, or -W switch
5817e4b17023SJohn Marino whose value does not begin with "no-" is obsoleted by the same value
5818e4b17023SJohn Marino with the "no-", similarly for a switch with the "no-" prefix. */
5819e4b17023SJohn Marino
5820e4b17023SJohn Marino static int
check_live_switch(int switchnum,int prefix_length)5821e4b17023SJohn Marino check_live_switch (int switchnum, int prefix_length)
5822e4b17023SJohn Marino {
5823e4b17023SJohn Marino const char *name = switches[switchnum].part1;
5824e4b17023SJohn Marino int i;
5825e4b17023SJohn Marino
5826e4b17023SJohn Marino /* If we already processed this switch and determined if it was
5827e4b17023SJohn Marino live or not, return our past determination. */
5828e4b17023SJohn Marino if (switches[switchnum].live_cond != 0)
5829e4b17023SJohn Marino return ((switches[switchnum].live_cond & SWITCH_LIVE) != 0
5830e4b17023SJohn Marino && (switches[switchnum].live_cond & SWITCH_FALSE) == 0
5831e4b17023SJohn Marino && (switches[switchnum].live_cond & SWITCH_IGNORE_PERMANENTLY)
5832e4b17023SJohn Marino == 0);
5833e4b17023SJohn Marino
5834e4b17023SJohn Marino /* In the common case of {<at-most-one-letter>*}, a negating
5835e4b17023SJohn Marino switch would always match, so ignore that case. We will just
5836e4b17023SJohn Marino send the conflicting switches to the compiler phase. */
5837e4b17023SJohn Marino if (prefix_length >= 0 && prefix_length <= 1)
5838e4b17023SJohn Marino return 1;
5839e4b17023SJohn Marino
5840e4b17023SJohn Marino /* Now search for duplicate in a manner that depends on the name. */
5841e4b17023SJohn Marino switch (*name)
5842e4b17023SJohn Marino {
5843e4b17023SJohn Marino case 'O':
5844e4b17023SJohn Marino for (i = switchnum + 1; i < n_switches; i++)
5845e4b17023SJohn Marino if (switches[i].part1[0] == 'O')
5846e4b17023SJohn Marino {
5847e4b17023SJohn Marino switches[switchnum].validated = 1;
5848e4b17023SJohn Marino switches[switchnum].live_cond = SWITCH_FALSE;
5849e4b17023SJohn Marino return 0;
5850e4b17023SJohn Marino }
5851e4b17023SJohn Marino break;
5852e4b17023SJohn Marino
5853e4b17023SJohn Marino case 'W': case 'f': case 'm':
5854e4b17023SJohn Marino if (! strncmp (name + 1, "no-", 3))
5855e4b17023SJohn Marino {
5856e4b17023SJohn Marino /* We have Xno-YYY, search for XYYY. */
5857e4b17023SJohn Marino for (i = switchnum + 1; i < n_switches; i++)
5858e4b17023SJohn Marino if (switches[i].part1[0] == name[0]
5859e4b17023SJohn Marino && ! strcmp (&switches[i].part1[1], &name[4]))
5860e4b17023SJohn Marino {
5861e4b17023SJohn Marino switches[switchnum].validated = 1;
5862e4b17023SJohn Marino switches[switchnum].live_cond = SWITCH_FALSE;
5863e4b17023SJohn Marino return 0;
5864e4b17023SJohn Marino }
5865e4b17023SJohn Marino }
5866e4b17023SJohn Marino else
5867e4b17023SJohn Marino {
5868e4b17023SJohn Marino /* We have XYYY, search for Xno-YYY. */
5869e4b17023SJohn Marino for (i = switchnum + 1; i < n_switches; i++)
5870e4b17023SJohn Marino if (switches[i].part1[0] == name[0]
5871e4b17023SJohn Marino && switches[i].part1[1] == 'n'
5872e4b17023SJohn Marino && switches[i].part1[2] == 'o'
5873e4b17023SJohn Marino && switches[i].part1[3] == '-'
5874e4b17023SJohn Marino && !strcmp (&switches[i].part1[4], &name[1]))
5875e4b17023SJohn Marino {
5876e4b17023SJohn Marino switches[switchnum].validated = 1;
5877e4b17023SJohn Marino switches[switchnum].live_cond = SWITCH_FALSE;
5878e4b17023SJohn Marino return 0;
5879e4b17023SJohn Marino }
5880e4b17023SJohn Marino }
5881e4b17023SJohn Marino break;
5882e4b17023SJohn Marino }
5883e4b17023SJohn Marino
5884e4b17023SJohn Marino /* Otherwise the switch is live. */
5885e4b17023SJohn Marino switches[switchnum].live_cond |= SWITCH_LIVE;
5886e4b17023SJohn Marino return 1;
5887e4b17023SJohn Marino }
5888e4b17023SJohn Marino
5889e4b17023SJohn Marino /* Pass a switch to the current accumulating command
5890e4b17023SJohn Marino in the same form that we received it.
5891e4b17023SJohn Marino SWITCHNUM identifies the switch; it is an index into
5892e4b17023SJohn Marino the vector of switches gcc received, which is `switches'.
5893e4b17023SJohn Marino This cannot fail since it never finishes a command line.
5894e4b17023SJohn Marino
5895e4b17023SJohn Marino If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument. */
5896e4b17023SJohn Marino
5897e4b17023SJohn Marino static void
give_switch(int switchnum,int omit_first_word)5898e4b17023SJohn Marino give_switch (int switchnum, int omit_first_word)
5899e4b17023SJohn Marino {
5900e4b17023SJohn Marino if ((switches[switchnum].live_cond & SWITCH_IGNORE) != 0)
5901e4b17023SJohn Marino return;
5902e4b17023SJohn Marino
5903e4b17023SJohn Marino if (!omit_first_word)
5904e4b17023SJohn Marino {
5905e4b17023SJohn Marino do_spec_1 ("-", 0, NULL);
5906e4b17023SJohn Marino do_spec_1 (switches[switchnum].part1, 1, NULL);
5907e4b17023SJohn Marino }
5908e4b17023SJohn Marino
5909e4b17023SJohn Marino if (switches[switchnum].args != 0)
5910e4b17023SJohn Marino {
5911e4b17023SJohn Marino const char **p;
5912e4b17023SJohn Marino for (p = switches[switchnum].args; *p; p++)
5913e4b17023SJohn Marino {
5914e4b17023SJohn Marino const char *arg = *p;
5915e4b17023SJohn Marino
5916e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
5917e4b17023SJohn Marino if (suffix_subst)
5918e4b17023SJohn Marino {
5919e4b17023SJohn Marino unsigned length = strlen (arg);
5920e4b17023SJohn Marino int dot = 0;
5921e4b17023SJohn Marino
5922e4b17023SJohn Marino while (length-- && !IS_DIR_SEPARATOR (arg[length]))
5923e4b17023SJohn Marino if (arg[length] == '.')
5924e4b17023SJohn Marino {
5925e4b17023SJohn Marino (CONST_CAST(char *, arg))[length] = 0;
5926e4b17023SJohn Marino dot = 1;
5927e4b17023SJohn Marino break;
5928e4b17023SJohn Marino }
5929e4b17023SJohn Marino do_spec_1 (arg, 1, NULL);
5930e4b17023SJohn Marino if (dot)
5931e4b17023SJohn Marino (CONST_CAST(char *, arg))[length] = '.';
5932e4b17023SJohn Marino do_spec_1 (suffix_subst, 1, NULL);
5933e4b17023SJohn Marino }
5934e4b17023SJohn Marino else
5935e4b17023SJohn Marino do_spec_1 (arg, 1, NULL);
5936e4b17023SJohn Marino }
5937e4b17023SJohn Marino }
5938e4b17023SJohn Marino
5939e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
5940e4b17023SJohn Marino switches[switchnum].validated = 1;
5941e4b17023SJohn Marino }
5942e4b17023SJohn Marino
5943e4b17023SJohn Marino /* Search for a file named NAME trying various prefixes including the
5944e4b17023SJohn Marino user's -B prefix and some standard ones.
5945e4b17023SJohn Marino Return the absolute file name found. If nothing is found, return NAME. */
5946e4b17023SJohn Marino
5947e4b17023SJohn Marino static const char *
find_file(const char * name)5948e4b17023SJohn Marino find_file (const char *name)
5949e4b17023SJohn Marino {
5950e4b17023SJohn Marino char *newname = find_a_file (&startfile_prefixes, name, R_OK, true);
5951e4b17023SJohn Marino return newname ? newname : name;
5952e4b17023SJohn Marino }
5953e4b17023SJohn Marino
5954e4b17023SJohn Marino /* Determine whether a directory exists. If LINKER, return 0 for
5955e4b17023SJohn Marino certain fixed names not needed by the linker. */
5956e4b17023SJohn Marino
5957e4b17023SJohn Marino static int
is_directory(const char * path1,bool linker)5958e4b17023SJohn Marino is_directory (const char *path1, bool linker)
5959e4b17023SJohn Marino {
5960e4b17023SJohn Marino int len1;
5961e4b17023SJohn Marino char *path;
5962e4b17023SJohn Marino char *cp;
5963e4b17023SJohn Marino struct stat st;
5964e4b17023SJohn Marino
5965e4b17023SJohn Marino /* Ensure the string ends with "/.". The resulting path will be a
5966e4b17023SJohn Marino directory even if the given path is a symbolic link. */
5967e4b17023SJohn Marino len1 = strlen (path1);
5968e4b17023SJohn Marino path = (char *) alloca (3 + len1);
5969e4b17023SJohn Marino memcpy (path, path1, len1);
5970e4b17023SJohn Marino cp = path + len1;
5971e4b17023SJohn Marino if (!IS_DIR_SEPARATOR (cp[-1]))
5972e4b17023SJohn Marino *cp++ = DIR_SEPARATOR;
5973e4b17023SJohn Marino *cp++ = '.';
5974e4b17023SJohn Marino *cp = '\0';
5975e4b17023SJohn Marino
5976e4b17023SJohn Marino /* Exclude directories that the linker is known to search. */
5977e4b17023SJohn Marino if (linker
5978e4b17023SJohn Marino && IS_DIR_SEPARATOR (path[0])
5979e4b17023SJohn Marino && ((cp - path == 6
5980e4b17023SJohn Marino && filename_ncmp (path + 1, "lib", 3) == 0)
5981e4b17023SJohn Marino || (cp - path == 10
5982e4b17023SJohn Marino && filename_ncmp (path + 1, "usr", 3) == 0
5983e4b17023SJohn Marino && IS_DIR_SEPARATOR (path[4])
5984e4b17023SJohn Marino && filename_ncmp (path + 5, "lib", 3) == 0)))
5985e4b17023SJohn Marino return 0;
5986e4b17023SJohn Marino
5987e4b17023SJohn Marino return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
5988e4b17023SJohn Marino }
5989e4b17023SJohn Marino
5990e4b17023SJohn Marino /* Set up the various global variables to indicate that we're processing
5991e4b17023SJohn Marino the input file named FILENAME. */
5992e4b17023SJohn Marino
5993e4b17023SJohn Marino void
set_input(const char * filename)5994e4b17023SJohn Marino set_input (const char *filename)
5995e4b17023SJohn Marino {
5996e4b17023SJohn Marino const char *p;
5997e4b17023SJohn Marino
5998e4b17023SJohn Marino gcc_input_filename = filename;
5999e4b17023SJohn Marino input_filename_length = strlen (gcc_input_filename);
6000e4b17023SJohn Marino input_basename = lbasename (gcc_input_filename);
6001e4b17023SJohn Marino
6002e4b17023SJohn Marino /* Find a suffix starting with the last period,
6003e4b17023SJohn Marino and set basename_length to exclude that suffix. */
6004e4b17023SJohn Marino basename_length = strlen (input_basename);
6005e4b17023SJohn Marino suffixed_basename_length = basename_length;
6006e4b17023SJohn Marino p = input_basename + basename_length;
6007e4b17023SJohn Marino while (p != input_basename && *p != '.')
6008e4b17023SJohn Marino --p;
6009e4b17023SJohn Marino if (*p == '.' && p != input_basename)
6010e4b17023SJohn Marino {
6011e4b17023SJohn Marino basename_length = p - input_basename;
6012e4b17023SJohn Marino input_suffix = p + 1;
6013e4b17023SJohn Marino }
6014e4b17023SJohn Marino else
6015e4b17023SJohn Marino input_suffix = "";
6016e4b17023SJohn Marino
6017e4b17023SJohn Marino /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then
6018e4b17023SJohn Marino we will need to do a stat on the gcc_input_filename. The
6019e4b17023SJohn Marino INPUT_STAT_SET signals that the stat is needed. */
6020e4b17023SJohn Marino input_stat_set = 0;
6021e4b17023SJohn Marino }
6022e4b17023SJohn Marino
6023e4b17023SJohn Marino /* On fatal signals, delete all the temporary files. */
6024e4b17023SJohn Marino
6025e4b17023SJohn Marino static void
fatal_signal(int signum)6026e4b17023SJohn Marino fatal_signal (int signum)
6027e4b17023SJohn Marino {
6028e4b17023SJohn Marino signal (signum, SIG_DFL);
6029e4b17023SJohn Marino delete_failure_queue ();
6030e4b17023SJohn Marino delete_temp_files ();
6031e4b17023SJohn Marino /* Get the same signal again, this time not handled,
6032e4b17023SJohn Marino so its normal effect occurs. */
6033e4b17023SJohn Marino kill (getpid (), signum);
6034e4b17023SJohn Marino }
6035e4b17023SJohn Marino
6036e4b17023SJohn Marino /* Compare the contents of the two files named CMPFILE[0] and
6037e4b17023SJohn Marino CMPFILE[1]. Return zero if they're identical, nonzero
6038e4b17023SJohn Marino otherwise. */
6039e4b17023SJohn Marino
6040e4b17023SJohn Marino static int
compare_files(char * cmpfile[])6041e4b17023SJohn Marino compare_files (char *cmpfile[])
6042e4b17023SJohn Marino {
6043e4b17023SJohn Marino int ret = 0;
6044e4b17023SJohn Marino FILE *temp[2] = { NULL, NULL };
6045e4b17023SJohn Marino int i;
6046e4b17023SJohn Marino
6047e4b17023SJohn Marino #if HAVE_MMAP_FILE
6048e4b17023SJohn Marino {
6049e4b17023SJohn Marino size_t length[2];
6050e4b17023SJohn Marino void *map[2] = { NULL, NULL };
6051e4b17023SJohn Marino
6052e4b17023SJohn Marino for (i = 0; i < 2; i++)
6053e4b17023SJohn Marino {
6054e4b17023SJohn Marino struct stat st;
6055e4b17023SJohn Marino
6056e4b17023SJohn Marino if (stat (cmpfile[i], &st) < 0 || !S_ISREG (st.st_mode))
6057e4b17023SJohn Marino {
6058e4b17023SJohn Marino error ("%s: could not determine length of compare-debug file %s",
6059e4b17023SJohn Marino gcc_input_filename, cmpfile[i]);
6060e4b17023SJohn Marino ret = 1;
6061e4b17023SJohn Marino break;
6062e4b17023SJohn Marino }
6063e4b17023SJohn Marino
6064e4b17023SJohn Marino length[i] = st.st_size;
6065e4b17023SJohn Marino }
6066e4b17023SJohn Marino
6067e4b17023SJohn Marino if (!ret && length[0] != length[1])
6068e4b17023SJohn Marino {
6069e4b17023SJohn Marino error ("%s: -fcompare-debug failure (length)", gcc_input_filename);
6070e4b17023SJohn Marino ret = 1;
6071e4b17023SJohn Marino }
6072e4b17023SJohn Marino
6073e4b17023SJohn Marino if (!ret)
6074e4b17023SJohn Marino for (i = 0; i < 2; i++)
6075e4b17023SJohn Marino {
6076e4b17023SJohn Marino int fd = open (cmpfile[i], O_RDONLY);
6077e4b17023SJohn Marino if (fd < 0)
6078e4b17023SJohn Marino {
6079e4b17023SJohn Marino error ("%s: could not open compare-debug file %s",
6080e4b17023SJohn Marino gcc_input_filename, cmpfile[i]);
6081e4b17023SJohn Marino ret = 1;
6082e4b17023SJohn Marino break;
6083e4b17023SJohn Marino }
6084e4b17023SJohn Marino
6085e4b17023SJohn Marino map[i] = mmap (NULL, length[i], PROT_READ, MAP_PRIVATE, fd, 0);
6086e4b17023SJohn Marino close (fd);
6087e4b17023SJohn Marino
6088e4b17023SJohn Marino if (map[i] == (void *) MAP_FAILED)
6089e4b17023SJohn Marino {
6090e4b17023SJohn Marino ret = -1;
6091e4b17023SJohn Marino break;
6092e4b17023SJohn Marino }
6093e4b17023SJohn Marino }
6094e4b17023SJohn Marino
6095e4b17023SJohn Marino if (!ret)
6096e4b17023SJohn Marino {
6097e4b17023SJohn Marino if (memcmp (map[0], map[1], length[0]) != 0)
6098e4b17023SJohn Marino {
6099e4b17023SJohn Marino error ("%s: -fcompare-debug failure", gcc_input_filename);
6100e4b17023SJohn Marino ret = 1;
6101e4b17023SJohn Marino }
6102e4b17023SJohn Marino }
6103e4b17023SJohn Marino
6104e4b17023SJohn Marino for (i = 0; i < 2; i++)
6105e4b17023SJohn Marino if (map[i])
6106e4b17023SJohn Marino munmap ((caddr_t) map[i], length[i]);
6107e4b17023SJohn Marino
6108e4b17023SJohn Marino if (ret >= 0)
6109e4b17023SJohn Marino return ret;
6110e4b17023SJohn Marino
6111e4b17023SJohn Marino ret = 0;
6112e4b17023SJohn Marino }
6113e4b17023SJohn Marino #endif
6114e4b17023SJohn Marino
6115e4b17023SJohn Marino for (i = 0; i < 2; i++)
6116e4b17023SJohn Marino {
6117e4b17023SJohn Marino temp[i] = fopen (cmpfile[i], "r");
6118e4b17023SJohn Marino if (!temp[i])
6119e4b17023SJohn Marino {
6120e4b17023SJohn Marino error ("%s: could not open compare-debug file %s",
6121e4b17023SJohn Marino gcc_input_filename, cmpfile[i]);
6122e4b17023SJohn Marino ret = 1;
6123e4b17023SJohn Marino break;
6124e4b17023SJohn Marino }
6125e4b17023SJohn Marino }
6126e4b17023SJohn Marino
6127e4b17023SJohn Marino if (!ret && temp[0] && temp[1])
6128e4b17023SJohn Marino for (;;)
6129e4b17023SJohn Marino {
6130e4b17023SJohn Marino int c0, c1;
6131e4b17023SJohn Marino c0 = fgetc (temp[0]);
6132e4b17023SJohn Marino c1 = fgetc (temp[1]);
6133e4b17023SJohn Marino
6134e4b17023SJohn Marino if (c0 != c1)
6135e4b17023SJohn Marino {
6136e4b17023SJohn Marino error ("%s: -fcompare-debug failure",
6137e4b17023SJohn Marino gcc_input_filename);
6138e4b17023SJohn Marino ret = 1;
6139e4b17023SJohn Marino break;
6140e4b17023SJohn Marino }
6141e4b17023SJohn Marino
6142e4b17023SJohn Marino if (c0 == EOF)
6143e4b17023SJohn Marino break;
6144e4b17023SJohn Marino }
6145e4b17023SJohn Marino
6146e4b17023SJohn Marino for (i = 1; i >= 0; i--)
6147e4b17023SJohn Marino {
6148e4b17023SJohn Marino if (temp[i])
6149e4b17023SJohn Marino fclose (temp[i]);
6150e4b17023SJohn Marino }
6151e4b17023SJohn Marino
6152e4b17023SJohn Marino return ret;
6153e4b17023SJohn Marino }
6154e4b17023SJohn Marino
6155e4b17023SJohn Marino extern int main (int, char **);
6156e4b17023SJohn Marino
6157e4b17023SJohn Marino int
main(int argc,char ** argv)6158e4b17023SJohn Marino main (int argc, char **argv)
6159e4b17023SJohn Marino {
6160e4b17023SJohn Marino size_t i;
6161e4b17023SJohn Marino int value;
6162e4b17023SJohn Marino int linker_was_run = 0;
6163e4b17023SJohn Marino int lang_n_infiles = 0;
6164e4b17023SJohn Marino int num_linker_inputs = 0;
6165e4b17023SJohn Marino char *explicit_link_files;
6166e4b17023SJohn Marino char *specs_file;
6167e4b17023SJohn Marino char *lto_wrapper_file;
6168e4b17023SJohn Marino const char *p;
6169e4b17023SJohn Marino struct user_specs *uptr;
6170e4b17023SJohn Marino char **old_argv = argv;
6171e4b17023SJohn Marino struct cl_decoded_option *decoded_options;
6172e4b17023SJohn Marino unsigned int decoded_options_count;
6173e4b17023SJohn Marino
6174e4b17023SJohn Marino /* Initialize here, not in definition. The IRIX 6 O32 cc sometimes chokes
6175e4b17023SJohn Marino on ?: in file-scope variable initializations. */
6176e4b17023SJohn Marino asm_debug = ASM_DEBUG_SPEC;
6177e4b17023SJohn Marino
6178e4b17023SJohn Marino p = argv[0] + strlen (argv[0]);
6179e4b17023SJohn Marino while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
6180e4b17023SJohn Marino --p;
6181e4b17023SJohn Marino progname = p;
6182e4b17023SJohn Marino
6183e4b17023SJohn Marino xmalloc_set_program_name (progname);
6184e4b17023SJohn Marino
6185e4b17023SJohn Marino expandargv (&argc, &argv);
6186e4b17023SJohn Marino
6187e4b17023SJohn Marino /* Determine if any expansions were made. */
6188e4b17023SJohn Marino if (argv != old_argv)
6189e4b17023SJohn Marino at_file_supplied = true;
6190e4b17023SJohn Marino
6191e4b17023SJohn Marino /* Register the language-independent parameters. */
6192e4b17023SJohn Marino global_init_params ();
6193e4b17023SJohn Marino finish_params ();
6194e4b17023SJohn Marino
6195e4b17023SJohn Marino init_options_struct (&global_options, &global_options_set);
6196e4b17023SJohn Marino
6197e4b17023SJohn Marino decode_cmdline_options_to_array (argc, CONST_CAST2 (const char **, char **,
6198e4b17023SJohn Marino argv),
6199e4b17023SJohn Marino CL_DRIVER,
6200e4b17023SJohn Marino &decoded_options, &decoded_options_count);
6201e4b17023SJohn Marino
6202e4b17023SJohn Marino #ifdef GCC_DRIVER_HOST_INITIALIZATION
6203e4b17023SJohn Marino /* Perform host dependent initialization when needed. */
6204e4b17023SJohn Marino GCC_DRIVER_HOST_INITIALIZATION;
6205e4b17023SJohn Marino #endif
6206e4b17023SJohn Marino
6207e4b17023SJohn Marino /* Unlock the stdio streams. */
6208e4b17023SJohn Marino unlock_std_streams ();
6209e4b17023SJohn Marino
6210e4b17023SJohn Marino gcc_init_libintl ();
6211e4b17023SJohn Marino
6212e4b17023SJohn Marino diagnostic_initialize (global_dc, 0);
6213e4b17023SJohn Marino if (atexit (delete_temp_files) != 0)
6214e4b17023SJohn Marino fatal_error ("atexit failed");
6215e4b17023SJohn Marino
6216e4b17023SJohn Marino if (signal (SIGINT, SIG_IGN) != SIG_IGN)
6217e4b17023SJohn Marino signal (SIGINT, fatal_signal);
6218e4b17023SJohn Marino #ifdef SIGHUP
6219e4b17023SJohn Marino if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
6220e4b17023SJohn Marino signal (SIGHUP, fatal_signal);
6221e4b17023SJohn Marino #endif
6222e4b17023SJohn Marino if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
6223e4b17023SJohn Marino signal (SIGTERM, fatal_signal);
6224e4b17023SJohn Marino #ifdef SIGPIPE
6225e4b17023SJohn Marino if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
6226e4b17023SJohn Marino signal (SIGPIPE, fatal_signal);
6227e4b17023SJohn Marino #endif
6228e4b17023SJohn Marino #ifdef SIGCHLD
6229e4b17023SJohn Marino /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
6230e4b17023SJohn Marino receive the signal. A different setting is inheritable */
6231e4b17023SJohn Marino signal (SIGCHLD, SIG_DFL);
6232e4b17023SJohn Marino #endif
6233e4b17023SJohn Marino
6234e4b17023SJohn Marino /* Parsing and gimplification sometimes need quite large stack.
6235e4b17023SJohn Marino Increase stack size limits if possible. */
6236e4b17023SJohn Marino stack_limit_increase (64 * 1024 * 1024);
6237e4b17023SJohn Marino
6238e4b17023SJohn Marino /* Allocate the argument vector. */
6239e4b17023SJohn Marino alloc_args ();
6240e4b17023SJohn Marino
6241e4b17023SJohn Marino obstack_init (&obstack);
6242e4b17023SJohn Marino
6243e4b17023SJohn Marino /* Build multilib_select, et. al from the separate lines that make up each
6244e4b17023SJohn Marino multilib selection. */
6245e4b17023SJohn Marino {
6246e4b17023SJohn Marino const char *const *q = multilib_raw;
6247e4b17023SJohn Marino int need_space;
6248e4b17023SJohn Marino
6249e4b17023SJohn Marino obstack_init (&multilib_obstack);
6250e4b17023SJohn Marino while ((p = *q++) != (char *) 0)
6251e4b17023SJohn Marino obstack_grow (&multilib_obstack, p, strlen (p));
6252e4b17023SJohn Marino
6253e4b17023SJohn Marino obstack_1grow (&multilib_obstack, 0);
6254e4b17023SJohn Marino multilib_select = XOBFINISH (&multilib_obstack, const char *);
6255e4b17023SJohn Marino
6256e4b17023SJohn Marino q = multilib_matches_raw;
6257e4b17023SJohn Marino while ((p = *q++) != (char *) 0)
6258e4b17023SJohn Marino obstack_grow (&multilib_obstack, p, strlen (p));
6259e4b17023SJohn Marino
6260e4b17023SJohn Marino obstack_1grow (&multilib_obstack, 0);
6261e4b17023SJohn Marino multilib_matches = XOBFINISH (&multilib_obstack, const char *);
6262e4b17023SJohn Marino
6263e4b17023SJohn Marino q = multilib_exclusions_raw;
6264e4b17023SJohn Marino while ((p = *q++) != (char *) 0)
6265e4b17023SJohn Marino obstack_grow (&multilib_obstack, p, strlen (p));
6266e4b17023SJohn Marino
6267e4b17023SJohn Marino obstack_1grow (&multilib_obstack, 0);
6268e4b17023SJohn Marino multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
6269e4b17023SJohn Marino
6270e4b17023SJohn Marino need_space = FALSE;
6271e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
6272e4b17023SJohn Marino {
6273e4b17023SJohn Marino if (need_space)
6274e4b17023SJohn Marino obstack_1grow (&multilib_obstack, ' ');
6275e4b17023SJohn Marino obstack_grow (&multilib_obstack,
6276e4b17023SJohn Marino multilib_defaults_raw[i],
6277e4b17023SJohn Marino strlen (multilib_defaults_raw[i]));
6278e4b17023SJohn Marino need_space = TRUE;
6279e4b17023SJohn Marino }
6280e4b17023SJohn Marino
6281e4b17023SJohn Marino obstack_1grow (&multilib_obstack, 0);
6282e4b17023SJohn Marino multilib_defaults = XOBFINISH (&multilib_obstack, const char *);
6283e4b17023SJohn Marino }
6284e4b17023SJohn Marino
6285e4b17023SJohn Marino #ifdef INIT_ENVIRONMENT
6286e4b17023SJohn Marino /* Set up any other necessary machine specific environment variables. */
6287e4b17023SJohn Marino xputenv (INIT_ENVIRONMENT);
6288e4b17023SJohn Marino #endif
6289e4b17023SJohn Marino
6290e4b17023SJohn Marino /* Make a table of what switches there are (switches, n_switches).
6291e4b17023SJohn Marino Make a table of specified input files (infiles, n_infiles).
6292e4b17023SJohn Marino Decode switches that are handled locally. */
6293e4b17023SJohn Marino
6294e4b17023SJohn Marino process_command (decoded_options_count, decoded_options);
6295e4b17023SJohn Marino
6296e4b17023SJohn Marino /* Initialize the vector of specs to just the default.
6297e4b17023SJohn Marino This means one element containing 0s, as a terminator. */
6298e4b17023SJohn Marino
6299e4b17023SJohn Marino compilers = XNEWVAR (struct compiler, sizeof default_compilers);
6300e4b17023SJohn Marino memcpy (compilers, default_compilers, sizeof default_compilers);
6301e4b17023SJohn Marino n_compilers = n_default_compilers;
6302e4b17023SJohn Marino
6303e4b17023SJohn Marino /* Read specs from a file if there is one. */
6304e4b17023SJohn Marino
6305e4b17023SJohn Marino machine_suffix = concat (spec_machine, dir_separator_str,
6306e4b17023SJohn Marino spec_version, dir_separator_str, NULL);
6307e4b17023SJohn Marino just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
6308e4b17023SJohn Marino
6309e4b17023SJohn Marino specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
6310e4b17023SJohn Marino /* Read the specs file unless it is a default one. */
6311e4b17023SJohn Marino if (specs_file != 0 && strcmp (specs_file, "specs"))
6312e4b17023SJohn Marino read_specs (specs_file, TRUE);
6313e4b17023SJohn Marino else
6314e4b17023SJohn Marino init_spec ();
6315e4b17023SJohn Marino
6316e4b17023SJohn Marino /* We need to check standard_exec_prefix/just_machine_suffix/specs
6317e4b17023SJohn Marino for any override of as, ld and libraries. */
6318e4b17023SJohn Marino specs_file = (char *) alloca (strlen (standard_exec_prefix)
6319e4b17023SJohn Marino + strlen (just_machine_suffix) + sizeof ("specs"));
6320e4b17023SJohn Marino
6321e4b17023SJohn Marino strcpy (specs_file, standard_exec_prefix);
6322e4b17023SJohn Marino strcat (specs_file, just_machine_suffix);
6323e4b17023SJohn Marino strcat (specs_file, "specs");
6324e4b17023SJohn Marino if (access (specs_file, R_OK) == 0)
6325e4b17023SJohn Marino read_specs (specs_file, TRUE);
6326e4b17023SJohn Marino
6327e4b17023SJohn Marino /* Process any configure-time defaults specified for the command line
6328e4b17023SJohn Marino options, via OPTION_DEFAULT_SPECS. */
6329e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
6330e4b17023SJohn Marino do_option_spec (option_default_specs[i].name,
6331e4b17023SJohn Marino option_default_specs[i].spec);
6332e4b17023SJohn Marino
6333e4b17023SJohn Marino /* Process DRIVER_SELF_SPECS, adding any new options to the end
6334e4b17023SJohn Marino of the command line. */
6335e4b17023SJohn Marino
6336e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
6337e4b17023SJohn Marino do_self_spec (driver_self_specs[i]);
6338e4b17023SJohn Marino
6339e4b17023SJohn Marino /* If not cross-compiling, look for executables in the standard
6340e4b17023SJohn Marino places. */
6341e4b17023SJohn Marino if (*cross_compile == '0')
6342e4b17023SJohn Marino {
6343e4b17023SJohn Marino if (*md_exec_prefix)
6344e4b17023SJohn Marino {
6345e4b17023SJohn Marino add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
6346e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 0);
6347e4b17023SJohn Marino }
6348e4b17023SJohn Marino }
6349e4b17023SJohn Marino
6350e4b17023SJohn Marino /* Process sysroot_suffix_spec. */
6351e4b17023SJohn Marino if (*sysroot_suffix_spec != 0
6352e4b17023SJohn Marino && do_spec_2 (sysroot_suffix_spec) == 0)
6353e4b17023SJohn Marino {
6354e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 1)
6355e4b17023SJohn Marino error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC");
6356e4b17023SJohn Marino else if (VEC_length (const_char_p, argbuf) == 1)
6357e4b17023SJohn Marino target_sysroot_suffix = xstrdup (VEC_last (const_char_p, argbuf));
6358e4b17023SJohn Marino }
6359e4b17023SJohn Marino
6360e4b17023SJohn Marino #ifdef HAVE_LD_SYSROOT
6361e4b17023SJohn Marino /* Pass the --sysroot option to the linker, if it supports that. If
6362e4b17023SJohn Marino there is a sysroot_suffix_spec, it has already been processed by
6363e4b17023SJohn Marino this point, so target_system_root really is the system root we
6364e4b17023SJohn Marino should be using. */
6365e4b17023SJohn Marino if (target_system_root)
6366e4b17023SJohn Marino {
6367e4b17023SJohn Marino obstack_grow (&obstack, "%(sysroot_spec) ", strlen ("%(sysroot_spec) "));
6368e4b17023SJohn Marino obstack_grow0 (&obstack, link_spec, strlen (link_spec));
6369e4b17023SJohn Marino set_spec ("link", XOBFINISH (&obstack, const char *));
6370e4b17023SJohn Marino }
6371e4b17023SJohn Marino #endif
6372e4b17023SJohn Marino
6373e4b17023SJohn Marino /* Process sysroot_hdrs_suffix_spec. */
6374e4b17023SJohn Marino if (*sysroot_hdrs_suffix_spec != 0
6375e4b17023SJohn Marino && do_spec_2 (sysroot_hdrs_suffix_spec) == 0)
6376e4b17023SJohn Marino {
6377e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 1)
6378e4b17023SJohn Marino error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC");
6379e4b17023SJohn Marino else if (VEC_length (const_char_p, argbuf) == 1)
6380e4b17023SJohn Marino target_sysroot_hdrs_suffix = xstrdup (VEC_last (const_char_p, argbuf));
6381e4b17023SJohn Marino }
6382e4b17023SJohn Marino
6383e4b17023SJohn Marino /* Look for startfiles in the standard places. */
6384e4b17023SJohn Marino if (*startfile_prefix_spec != 0
6385e4b17023SJohn Marino && do_spec_2 (startfile_prefix_spec) == 0
6386e4b17023SJohn Marino && do_spec_1 (" ", 0, NULL) == 0)
6387e4b17023SJohn Marino {
6388e4b17023SJohn Marino const char *arg;
6389e4b17023SJohn Marino int ndx;
6390e4b17023SJohn Marino FOR_EACH_VEC_ELT (const_char_p, argbuf, ndx, arg)
6391e4b17023SJohn Marino add_sysrooted_prefix (&startfile_prefixes, arg, "BINUTILS",
6392e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 1);
6393e4b17023SJohn Marino }
6394e4b17023SJohn Marino /* We should eventually get rid of all these and stick to
6395e4b17023SJohn Marino startfile_prefix_spec exclusively. */
6396e4b17023SJohn Marino else if (*cross_compile == '0' || target_system_root)
6397e4b17023SJohn Marino {
6398e4b17023SJohn Marino if (*md_startfile_prefix)
6399e4b17023SJohn Marino add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
6400e4b17023SJohn Marino "GCC", PREFIX_PRIORITY_LAST, 0, 1);
6401e4b17023SJohn Marino
6402e4b17023SJohn Marino if (*md_startfile_prefix_1)
6403e4b17023SJohn Marino add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
6404e4b17023SJohn Marino "GCC", PREFIX_PRIORITY_LAST, 0, 1);
6405e4b17023SJohn Marino
6406e4b17023SJohn Marino /* If standard_startfile_prefix is relative, base it on
6407e4b17023SJohn Marino standard_exec_prefix. This lets us move the installed tree
6408e4b17023SJohn Marino as a unit. If GCC_EXEC_PREFIX is defined, base
6409e4b17023SJohn Marino standard_startfile_prefix on that as well.
6410e4b17023SJohn Marino
6411e4b17023SJohn Marino If the prefix is relative, only search it for native compilers;
6412e4b17023SJohn Marino otherwise we will search a directory containing host libraries. */
6413e4b17023SJohn Marino if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
6414e4b17023SJohn Marino add_sysrooted_prefix (&startfile_prefixes,
6415e4b17023SJohn Marino standard_startfile_prefix, "BINUTILS",
6416e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 1);
6417e4b17023SJohn Marino else if (*cross_compile == '0')
6418e4b17023SJohn Marino {
6419e4b17023SJohn Marino add_prefix (&startfile_prefixes,
6420e4b17023SJohn Marino concat (gcc_exec_prefix
6421e4b17023SJohn Marino ? gcc_exec_prefix : standard_exec_prefix,
6422e4b17023SJohn Marino machine_suffix,
6423e4b17023SJohn Marino standard_startfile_prefix, NULL),
6424e4b17023SJohn Marino NULL, PREFIX_PRIORITY_LAST, 0, 1);
6425e4b17023SJohn Marino }
6426e4b17023SJohn Marino
6427e4b17023SJohn Marino /* Sysrooted prefixes are relocated because target_system_root is
6428e4b17023SJohn Marino also relocated by gcc_exec_prefix. */
6429e4b17023SJohn Marino if (*standard_startfile_prefix_1)
6430e4b17023SJohn Marino add_sysrooted_prefix (&startfile_prefixes,
6431e4b17023SJohn Marino standard_startfile_prefix_1, "BINUTILS",
6432e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 1);
6433e4b17023SJohn Marino if (*standard_startfile_prefix_2)
6434e4b17023SJohn Marino add_sysrooted_prefix (&startfile_prefixes,
6435e4b17023SJohn Marino standard_startfile_prefix_2, "BINUTILS",
6436e4b17023SJohn Marino PREFIX_PRIORITY_LAST, 0, 1);
6437e4b17023SJohn Marino }
6438e4b17023SJohn Marino
6439e4b17023SJohn Marino /* Process any user specified specs in the order given on the command
6440e4b17023SJohn Marino line. */
6441e4b17023SJohn Marino for (uptr = user_specs_head; uptr; uptr = uptr->next)
6442e4b17023SJohn Marino {
6443e4b17023SJohn Marino char *filename = find_a_file (&startfile_prefixes, uptr->filename,
6444e4b17023SJohn Marino R_OK, true);
6445e4b17023SJohn Marino read_specs (filename ? filename : uptr->filename, FALSE);
6446e4b17023SJohn Marino }
6447e4b17023SJohn Marino
6448e4b17023SJohn Marino /* Process any user self specs. */
6449e4b17023SJohn Marino {
6450e4b17023SJohn Marino struct spec_list *sl;
6451e4b17023SJohn Marino for (sl = specs; sl; sl = sl->next)
6452e4b17023SJohn Marino if (sl->name_len == sizeof "self_spec" - 1
6453e4b17023SJohn Marino && !strcmp (sl->name, "self_spec"))
6454e4b17023SJohn Marino do_self_spec (*sl->ptr_spec);
6455e4b17023SJohn Marino }
6456e4b17023SJohn Marino
6457e4b17023SJohn Marino if (compare_debug)
6458e4b17023SJohn Marino {
6459e4b17023SJohn Marino enum save_temps save;
6460e4b17023SJohn Marino
6461e4b17023SJohn Marino if (!compare_debug_second)
6462e4b17023SJohn Marino {
6463e4b17023SJohn Marino n_switches_debug_check[1] = n_switches;
6464e4b17023SJohn Marino n_switches_alloc_debug_check[1] = n_switches_alloc;
6465e4b17023SJohn Marino switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
6466e4b17023SJohn Marino n_switches_alloc);
6467e4b17023SJohn Marino
6468e4b17023SJohn Marino do_self_spec ("%:compare-debug-self-opt()");
6469e4b17023SJohn Marino n_switches_debug_check[0] = n_switches;
6470e4b17023SJohn Marino n_switches_alloc_debug_check[0] = n_switches_alloc;
6471e4b17023SJohn Marino switches_debug_check[0] = switches;
6472e4b17023SJohn Marino
6473e4b17023SJohn Marino n_switches = n_switches_debug_check[1];
6474e4b17023SJohn Marino n_switches_alloc = n_switches_alloc_debug_check[1];
6475e4b17023SJohn Marino switches = switches_debug_check[1];
6476e4b17023SJohn Marino }
6477e4b17023SJohn Marino
6478e4b17023SJohn Marino /* Avoid crash when computing %j in this early. */
6479e4b17023SJohn Marino save = save_temps_flag;
6480e4b17023SJohn Marino save_temps_flag = SAVE_TEMPS_NONE;
6481e4b17023SJohn Marino
6482e4b17023SJohn Marino compare_debug = -compare_debug;
6483e4b17023SJohn Marino do_self_spec ("%:compare-debug-self-opt()");
6484e4b17023SJohn Marino
6485e4b17023SJohn Marino save_temps_flag = save;
6486e4b17023SJohn Marino
6487e4b17023SJohn Marino if (!compare_debug_second)
6488e4b17023SJohn Marino {
6489e4b17023SJohn Marino n_switches_debug_check[1] = n_switches;
6490e4b17023SJohn Marino n_switches_alloc_debug_check[1] = n_switches_alloc;
6491e4b17023SJohn Marino switches_debug_check[1] = switches;
6492e4b17023SJohn Marino compare_debug = -compare_debug;
6493e4b17023SJohn Marino n_switches = n_switches_debug_check[0];
6494e4b17023SJohn Marino n_switches_alloc = n_switches_debug_check[0];
6495e4b17023SJohn Marino switches = switches_debug_check[0];
6496e4b17023SJohn Marino }
6497e4b17023SJohn Marino }
6498e4b17023SJohn Marino
6499e4b17023SJohn Marino
6500e4b17023SJohn Marino /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake. */
6501e4b17023SJohn Marino if (gcc_exec_prefix)
6502e4b17023SJohn Marino gcc_exec_prefix = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
6503e4b17023SJohn Marino spec_version, dir_separator_str, NULL);
6504e4b17023SJohn Marino
6505e4b17023SJohn Marino /* Now we have the specs.
6506e4b17023SJohn Marino Set the `valid' bits for switches that match anything in any spec. */
6507e4b17023SJohn Marino
6508e4b17023SJohn Marino validate_all_switches ();
6509e4b17023SJohn Marino
6510e4b17023SJohn Marino /* Now that we have the switches and the specs, set
6511e4b17023SJohn Marino the subdirectory based on the options. */
6512e4b17023SJohn Marino set_multilib_dir ();
6513e4b17023SJohn Marino
6514e4b17023SJohn Marino /* Set up to remember the pathname of gcc and any options
6515e4b17023SJohn Marino needed for collect. We use argv[0] instead of progname because
6516e4b17023SJohn Marino we need the complete pathname. */
6517e4b17023SJohn Marino obstack_init (&collect_obstack);
6518e4b17023SJohn Marino obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
6519e4b17023SJohn Marino obstack_grow (&collect_obstack, argv[0], strlen (argv[0]) + 1);
6520e4b17023SJohn Marino xputenv (XOBFINISH (&collect_obstack, char *));
6521e4b17023SJohn Marino
6522e4b17023SJohn Marino /* Set up to remember the pathname of the lto wrapper. */
6523e4b17023SJohn Marino
6524e4b17023SJohn Marino if (have_c)
6525e4b17023SJohn Marino lto_wrapper_file = NULL;
6526e4b17023SJohn Marino else
6527e4b17023SJohn Marino lto_wrapper_file = find_a_file (&exec_prefixes, "lto-wrapper",
6528e4b17023SJohn Marino X_OK, false);
6529e4b17023SJohn Marino if (lto_wrapper_file)
6530e4b17023SJohn Marino {
65315ce9237cSJohn Marino lto_wrapper_file = convert_white_space (lto_wrapper_file);
6532e4b17023SJohn Marino lto_wrapper_spec = lto_wrapper_file;
6533e4b17023SJohn Marino obstack_init (&collect_obstack);
6534e4b17023SJohn Marino obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
6535e4b17023SJohn Marino sizeof ("COLLECT_LTO_WRAPPER=") - 1);
6536e4b17023SJohn Marino obstack_grow (&collect_obstack, lto_wrapper_spec,
6537e4b17023SJohn Marino strlen (lto_wrapper_spec) + 1);
6538e4b17023SJohn Marino xputenv (XOBFINISH (&collect_obstack, char *));
6539e4b17023SJohn Marino }
6540e4b17023SJohn Marino
6541e4b17023SJohn Marino /* Warn about any switches that no pass was interested in. */
6542e4b17023SJohn Marino
6543e4b17023SJohn Marino for (i = 0; (int) i < n_switches; i++)
6544e4b17023SJohn Marino if (! switches[i].validated)
6545e4b17023SJohn Marino error ("unrecognized option %<-%s%>", switches[i].part1);
6546e4b17023SJohn Marino
6547e4b17023SJohn Marino /* Obey some of the options. */
6548e4b17023SJohn Marino
6549e4b17023SJohn Marino if (print_search_dirs)
6550e4b17023SJohn Marino {
6551fdc4107cSJohn Marino printf (_("install: %s\n"), STD_EXEC_PATH);
6552e4b17023SJohn Marino printf (_("programs: %s\n"),
6553e4b17023SJohn Marino build_search_list (&exec_prefixes, "", false, false));
6554e4b17023SJohn Marino printf (_("libraries: %s\n"),
6555e4b17023SJohn Marino build_search_list (&startfile_prefixes, "", false, true));
6556e4b17023SJohn Marino return (0);
6557e4b17023SJohn Marino }
6558e4b17023SJohn Marino
6559e4b17023SJohn Marino if (print_file_name)
6560e4b17023SJohn Marino {
6561e4b17023SJohn Marino printf ("%s\n", find_file (print_file_name));
6562e4b17023SJohn Marino return (0);
6563e4b17023SJohn Marino }
6564e4b17023SJohn Marino
6565e4b17023SJohn Marino if (print_prog_name)
6566e4b17023SJohn Marino {
6567e4b17023SJohn Marino char *newname = find_a_file (&exec_prefixes, print_prog_name, X_OK, 0);
6568e4b17023SJohn Marino printf ("%s\n", (newname ? newname : print_prog_name));
6569e4b17023SJohn Marino return (0);
6570e4b17023SJohn Marino }
6571e4b17023SJohn Marino
6572e4b17023SJohn Marino if (print_multi_lib)
6573e4b17023SJohn Marino {
6574e4b17023SJohn Marino print_multilib_info ();
6575e4b17023SJohn Marino return (0);
6576e4b17023SJohn Marino }
6577e4b17023SJohn Marino
6578e4b17023SJohn Marino if (print_multi_directory)
6579e4b17023SJohn Marino {
6580e4b17023SJohn Marino if (multilib_dir == NULL)
6581e4b17023SJohn Marino printf (".\n");
6582e4b17023SJohn Marino else
6583e4b17023SJohn Marino printf ("%s\n", multilib_dir);
6584e4b17023SJohn Marino return (0);
6585e4b17023SJohn Marino }
6586e4b17023SJohn Marino
65875ce9237cSJohn Marino if (print_multiarch)
65885ce9237cSJohn Marino {
65895ce9237cSJohn Marino if (multiarch_dir == NULL)
65905ce9237cSJohn Marino printf ("\n");
65915ce9237cSJohn Marino else
65925ce9237cSJohn Marino printf ("%s\n", multiarch_dir);
65935ce9237cSJohn Marino return (0);
65945ce9237cSJohn Marino }
65955ce9237cSJohn Marino
6596e4b17023SJohn Marino if (print_sysroot)
6597e4b17023SJohn Marino {
6598e4b17023SJohn Marino if (target_system_root)
6599e4b17023SJohn Marino {
6600e4b17023SJohn Marino if (target_sysroot_suffix)
6601e4b17023SJohn Marino printf ("%s%s\n", target_system_root, target_sysroot_suffix);
6602e4b17023SJohn Marino else
6603e4b17023SJohn Marino printf ("%s\n", target_system_root);
6604e4b17023SJohn Marino }
6605e4b17023SJohn Marino return (0);
6606e4b17023SJohn Marino }
6607e4b17023SJohn Marino
6608e4b17023SJohn Marino if (print_multi_os_directory)
6609e4b17023SJohn Marino {
6610e4b17023SJohn Marino if (multilib_os_dir == NULL)
6611e4b17023SJohn Marino printf (".\n");
6612e4b17023SJohn Marino else
6613e4b17023SJohn Marino printf ("%s\n", multilib_os_dir);
6614e4b17023SJohn Marino return (0);
6615e4b17023SJohn Marino }
6616e4b17023SJohn Marino
6617e4b17023SJohn Marino if (print_sysroot_headers_suffix)
6618e4b17023SJohn Marino {
6619e4b17023SJohn Marino if (*sysroot_hdrs_suffix_spec)
6620e4b17023SJohn Marino {
6621e4b17023SJohn Marino printf("%s\n", (target_sysroot_hdrs_suffix
6622e4b17023SJohn Marino ? target_sysroot_hdrs_suffix
6623e4b17023SJohn Marino : ""));
6624e4b17023SJohn Marino return (0);
6625e4b17023SJohn Marino }
6626e4b17023SJohn Marino else
6627e4b17023SJohn Marino /* The error status indicates that only one set of fixed
6628e4b17023SJohn Marino headers should be built. */
6629e4b17023SJohn Marino fatal_error ("not configured with sysroot headers suffix");
6630e4b17023SJohn Marino }
6631e4b17023SJohn Marino
6632e4b17023SJohn Marino if (print_help_list)
6633e4b17023SJohn Marino {
6634e4b17023SJohn Marino display_help ();
6635e4b17023SJohn Marino
6636e4b17023SJohn Marino if (! verbose_flag)
6637e4b17023SJohn Marino {
6638e4b17023SJohn Marino printf (_("\nFor bug reporting instructions, please see:\n"));
6639e4b17023SJohn Marino printf ("%s.\n", bug_report_url);
6640e4b17023SJohn Marino
6641e4b17023SJohn Marino return (0);
6642e4b17023SJohn Marino }
6643e4b17023SJohn Marino
6644e4b17023SJohn Marino /* We do not exit here. Instead we have created a fake input file
6645e4b17023SJohn Marino called 'help-dummy' which needs to be compiled, and we pass this
6646e4b17023SJohn Marino on the various sub-processes, along with the --help switch.
6647e4b17023SJohn Marino Ensure their output appears after ours. */
6648e4b17023SJohn Marino fputc ('\n', stdout);
6649e4b17023SJohn Marino fflush (stdout);
6650e4b17023SJohn Marino }
6651e4b17023SJohn Marino
6652e4b17023SJohn Marino if (print_version)
6653e4b17023SJohn Marino {
6654e4b17023SJohn Marino printf (_("%s %s%s\n"), progname, pkgversion_string,
6655e4b17023SJohn Marino version_string);
6656e4b17023SJohn Marino printf ("Copyright %s 2012 Free Software Foundation, Inc.\n",
6657e4b17023SJohn Marino _("(C)"));
6658e4b17023SJohn Marino fputs (_("This is free software; see the source for copying conditions. There is NO\n\
6659e4b17023SJohn Marino warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
6660e4b17023SJohn Marino stdout);
6661e4b17023SJohn Marino if (! verbose_flag)
6662e4b17023SJohn Marino return 0;
6663e4b17023SJohn Marino
6664e4b17023SJohn Marino /* We do not exit here. We use the same mechanism of --help to print
6665e4b17023SJohn Marino the version of the sub-processes. */
6666e4b17023SJohn Marino fputc ('\n', stdout);
6667e4b17023SJohn Marino fflush (stdout);
6668e4b17023SJohn Marino }
6669e4b17023SJohn Marino
6670e4b17023SJohn Marino if (verbose_flag)
6671e4b17023SJohn Marino {
6672e4b17023SJohn Marino int n;
6673e4b17023SJohn Marino const char *thrmod;
6674e4b17023SJohn Marino
6675e4b17023SJohn Marino fnotice (stderr, "Target: %s\n", spec_machine);
6676e4b17023SJohn Marino fnotice (stderr, "Configured with: %s\n", configuration_arguments);
6677e4b17023SJohn Marino
6678e4b17023SJohn Marino #ifdef THREAD_MODEL_SPEC
6679e4b17023SJohn Marino /* We could have defined THREAD_MODEL_SPEC to "%*" by default,
6680e4b17023SJohn Marino but there's no point in doing all this processing just to get
6681e4b17023SJohn Marino thread_model back. */
6682e4b17023SJohn Marino obstack_init (&obstack);
6683e4b17023SJohn Marino do_spec_1 (THREAD_MODEL_SPEC, 0, thread_model);
6684e4b17023SJohn Marino obstack_1grow (&obstack, '\0');
6685e4b17023SJohn Marino thrmod = XOBFINISH (&obstack, const char *);
6686e4b17023SJohn Marino #else
6687e4b17023SJohn Marino thrmod = thread_model;
6688e4b17023SJohn Marino #endif
6689e4b17023SJohn Marino
6690e4b17023SJohn Marino fnotice (stderr, "Thread model: %s\n", thrmod);
6691e4b17023SJohn Marino
6692e4b17023SJohn Marino /* compiler_version is truncated at the first space when initialized
6693e4b17023SJohn Marino from version string, so truncate version_string at the first space
6694e4b17023SJohn Marino before comparing. */
6695e4b17023SJohn Marino for (n = 0; version_string[n]; n++)
6696e4b17023SJohn Marino if (version_string[n] == ' ')
6697e4b17023SJohn Marino break;
6698e4b17023SJohn Marino
6699e4b17023SJohn Marino if (! strncmp (version_string, compiler_version, n)
6700e4b17023SJohn Marino && compiler_version[n] == 0)
6701e4b17023SJohn Marino fnotice (stderr, "gcc version %s %s\n", version_string,
6702e4b17023SJohn Marino pkgversion_string);
6703e4b17023SJohn Marino else
6704e4b17023SJohn Marino fnotice (stderr, "gcc driver version %s %sexecuting gcc version %s\n",
6705e4b17023SJohn Marino version_string, pkgversion_string, compiler_version);
6706e4b17023SJohn Marino
6707e4b17023SJohn Marino if (n_infiles == 0)
6708e4b17023SJohn Marino return (0);
6709e4b17023SJohn Marino }
6710e4b17023SJohn Marino
6711e4b17023SJohn Marino if (n_infiles == added_libraries)
6712e4b17023SJohn Marino fatal_error ("no input files");
6713e4b17023SJohn Marino
6714e4b17023SJohn Marino if (seen_error ())
6715e4b17023SJohn Marino goto out;
6716e4b17023SJohn Marino
6717e4b17023SJohn Marino /* Make a place to record the compiler output file names
6718e4b17023SJohn Marino that correspond to the input files. */
6719e4b17023SJohn Marino
6720e4b17023SJohn Marino i = n_infiles;
6721e4b17023SJohn Marino i += lang_specific_extra_outfiles;
6722e4b17023SJohn Marino outfiles = XCNEWVEC (const char *, i);
6723e4b17023SJohn Marino
6724e4b17023SJohn Marino /* Record which files were specified explicitly as link input. */
6725e4b17023SJohn Marino
6726e4b17023SJohn Marino explicit_link_files = XCNEWVEC (char, n_infiles);
6727e4b17023SJohn Marino
6728e4b17023SJohn Marino combine_inputs = have_o || flag_wpa;
6729e4b17023SJohn Marino
6730e4b17023SJohn Marino for (i = 0; (int) i < n_infiles; i++)
6731e4b17023SJohn Marino {
6732e4b17023SJohn Marino const char *name = infiles[i].name;
6733e4b17023SJohn Marino struct compiler *compiler = lookup_compiler (name,
6734e4b17023SJohn Marino strlen (name),
6735e4b17023SJohn Marino infiles[i].language);
6736e4b17023SJohn Marino
6737e4b17023SJohn Marino if (compiler && !(compiler->combinable))
6738e4b17023SJohn Marino combine_inputs = false;
6739e4b17023SJohn Marino
6740e4b17023SJohn Marino if (lang_n_infiles > 0 && compiler != input_file_compiler
6741e4b17023SJohn Marino && infiles[i].language && infiles[i].language[0] != '*')
6742e4b17023SJohn Marino infiles[i].incompiler = compiler;
6743e4b17023SJohn Marino else if (compiler)
6744e4b17023SJohn Marino {
6745e4b17023SJohn Marino lang_n_infiles++;
6746e4b17023SJohn Marino input_file_compiler = compiler;
6747e4b17023SJohn Marino infiles[i].incompiler = compiler;
6748e4b17023SJohn Marino }
6749e4b17023SJohn Marino else
6750e4b17023SJohn Marino {
6751e4b17023SJohn Marino /* Since there is no compiler for this input file, assume it is a
6752e4b17023SJohn Marino linker file. */
6753e4b17023SJohn Marino explicit_link_files[i] = 1;
6754e4b17023SJohn Marino infiles[i].incompiler = NULL;
6755e4b17023SJohn Marino }
6756e4b17023SJohn Marino infiles[i].compiled = false;
6757e4b17023SJohn Marino infiles[i].preprocessed = false;
6758e4b17023SJohn Marino }
6759e4b17023SJohn Marino
6760e4b17023SJohn Marino if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
6761e4b17023SJohn Marino fatal_error ("cannot specify -o with -c, -S or -E with multiple files");
6762e4b17023SJohn Marino
6763e4b17023SJohn Marino for (i = 0; (int) i < n_infiles; i++)
6764e4b17023SJohn Marino {
6765e4b17023SJohn Marino int this_file_error = 0;
6766e4b17023SJohn Marino
6767e4b17023SJohn Marino /* Tell do_spec what to substitute for %i. */
6768e4b17023SJohn Marino
6769e4b17023SJohn Marino input_file_number = i;
6770e4b17023SJohn Marino set_input (infiles[i].name);
6771e4b17023SJohn Marino
6772e4b17023SJohn Marino if (infiles[i].compiled)
6773e4b17023SJohn Marino continue;
6774e4b17023SJohn Marino
6775e4b17023SJohn Marino /* Use the same thing in %o, unless cp->spec says otherwise. */
6776e4b17023SJohn Marino
6777e4b17023SJohn Marino outfiles[i] = gcc_input_filename;
6778e4b17023SJohn Marino
6779e4b17023SJohn Marino /* Figure out which compiler from the file's suffix. */
6780e4b17023SJohn Marino
6781e4b17023SJohn Marino input_file_compiler
6782e4b17023SJohn Marino = lookup_compiler (infiles[i].name, input_filename_length,
6783e4b17023SJohn Marino infiles[i].language);
6784e4b17023SJohn Marino
6785e4b17023SJohn Marino if (input_file_compiler)
6786e4b17023SJohn Marino {
6787e4b17023SJohn Marino /* Ok, we found an applicable compiler. Run its spec. */
6788e4b17023SJohn Marino
6789e4b17023SJohn Marino if (input_file_compiler->spec[0] == '#')
6790e4b17023SJohn Marino {
6791e4b17023SJohn Marino error ("%s: %s compiler not installed on this system",
6792e4b17023SJohn Marino gcc_input_filename, &input_file_compiler->spec[1]);
6793e4b17023SJohn Marino this_file_error = 1;
6794e4b17023SJohn Marino }
6795e4b17023SJohn Marino else
6796e4b17023SJohn Marino {
6797e4b17023SJohn Marino if (compare_debug)
6798e4b17023SJohn Marino {
6799e4b17023SJohn Marino free (debug_check_temp_file[0]);
6800e4b17023SJohn Marino debug_check_temp_file[0] = NULL;
6801e4b17023SJohn Marino
6802e4b17023SJohn Marino free (debug_check_temp_file[1]);
6803e4b17023SJohn Marino debug_check_temp_file[1] = NULL;
6804e4b17023SJohn Marino }
6805e4b17023SJohn Marino
6806e4b17023SJohn Marino value = do_spec (input_file_compiler->spec);
6807e4b17023SJohn Marino infiles[i].compiled = true;
6808e4b17023SJohn Marino if (value < 0)
6809e4b17023SJohn Marino this_file_error = 1;
6810e4b17023SJohn Marino else if (compare_debug && debug_check_temp_file[0])
6811e4b17023SJohn Marino {
6812e4b17023SJohn Marino if (verbose_flag)
6813e4b17023SJohn Marino inform (0, "recompiling with -fcompare-debug");
6814e4b17023SJohn Marino
6815e4b17023SJohn Marino compare_debug = -compare_debug;
6816e4b17023SJohn Marino n_switches = n_switches_debug_check[1];
6817e4b17023SJohn Marino n_switches_alloc = n_switches_alloc_debug_check[1];
6818e4b17023SJohn Marino switches = switches_debug_check[1];
6819e4b17023SJohn Marino
6820e4b17023SJohn Marino value = do_spec (input_file_compiler->spec);
6821e4b17023SJohn Marino
6822e4b17023SJohn Marino compare_debug = -compare_debug;
6823e4b17023SJohn Marino n_switches = n_switches_debug_check[0];
6824e4b17023SJohn Marino n_switches_alloc = n_switches_alloc_debug_check[0];
6825e4b17023SJohn Marino switches = switches_debug_check[0];
6826e4b17023SJohn Marino
6827e4b17023SJohn Marino if (value < 0)
6828e4b17023SJohn Marino {
6829e4b17023SJohn Marino error ("during -fcompare-debug recompilation");
6830e4b17023SJohn Marino this_file_error = 1;
6831e4b17023SJohn Marino }
6832e4b17023SJohn Marino
6833e4b17023SJohn Marino gcc_assert (debug_check_temp_file[1]
6834e4b17023SJohn Marino && filename_cmp (debug_check_temp_file[0],
6835e4b17023SJohn Marino debug_check_temp_file[1]));
6836e4b17023SJohn Marino
6837e4b17023SJohn Marino if (verbose_flag)
6838e4b17023SJohn Marino inform (0, "comparing final insns dumps");
6839e4b17023SJohn Marino
6840e4b17023SJohn Marino if (compare_files (debug_check_temp_file))
6841e4b17023SJohn Marino this_file_error = 1;
6842e4b17023SJohn Marino }
6843e4b17023SJohn Marino
6844e4b17023SJohn Marino if (compare_debug)
6845e4b17023SJohn Marino {
6846e4b17023SJohn Marino free (debug_check_temp_file[0]);
6847e4b17023SJohn Marino debug_check_temp_file[0] = NULL;
6848e4b17023SJohn Marino
6849e4b17023SJohn Marino free (debug_check_temp_file[1]);
6850e4b17023SJohn Marino debug_check_temp_file[1] = NULL;
6851e4b17023SJohn Marino }
6852e4b17023SJohn Marino }
6853e4b17023SJohn Marino }
6854e4b17023SJohn Marino
6855e4b17023SJohn Marino /* If this file's name does not contain a recognized suffix,
6856e4b17023SJohn Marino record it as explicit linker input. */
6857e4b17023SJohn Marino
6858e4b17023SJohn Marino else
6859e4b17023SJohn Marino explicit_link_files[i] = 1;
6860e4b17023SJohn Marino
6861e4b17023SJohn Marino /* Clear the delete-on-failure queue, deleting the files in it
6862e4b17023SJohn Marino if this compilation failed. */
6863e4b17023SJohn Marino
6864e4b17023SJohn Marino if (this_file_error)
6865e4b17023SJohn Marino {
6866e4b17023SJohn Marino delete_failure_queue ();
6867e4b17023SJohn Marino errorcount++;
6868e4b17023SJohn Marino }
6869e4b17023SJohn Marino /* If this compilation succeeded, don't delete those files later. */
6870e4b17023SJohn Marino clear_failure_queue ();
6871e4b17023SJohn Marino }
6872e4b17023SJohn Marino
6873e4b17023SJohn Marino /* Reset the input file name to the first compile/object file name, for use
6874e4b17023SJohn Marino with %b in LINK_SPEC. We use the first input file that we can find
6875e4b17023SJohn Marino a compiler to compile it instead of using infiles.language since for
6876e4b17023SJohn Marino languages other than C we use aliases that we then lookup later. */
6877e4b17023SJohn Marino if (n_infiles > 0)
6878e4b17023SJohn Marino {
6879e4b17023SJohn Marino int i;
6880e4b17023SJohn Marino
6881e4b17023SJohn Marino for (i = 0; i < n_infiles ; i++)
6882e4b17023SJohn Marino if (infiles[i].incompiler
6883e4b17023SJohn Marino || (infiles[i].language && infiles[i].language[0] != '*'))
6884e4b17023SJohn Marino {
6885e4b17023SJohn Marino set_input (infiles[i].name);
6886e4b17023SJohn Marino break;
6887e4b17023SJohn Marino }
6888e4b17023SJohn Marino }
6889e4b17023SJohn Marino
6890e4b17023SJohn Marino if (!seen_error ())
6891e4b17023SJohn Marino {
6892e4b17023SJohn Marino /* Make sure INPUT_FILE_NUMBER points to first available open
6893e4b17023SJohn Marino slot. */
6894e4b17023SJohn Marino input_file_number = n_infiles;
6895e4b17023SJohn Marino if (lang_specific_pre_link ())
6896e4b17023SJohn Marino errorcount++;
6897e4b17023SJohn Marino }
6898e4b17023SJohn Marino
6899e4b17023SJohn Marino /* Determine if there are any linker input files. */
6900e4b17023SJohn Marino num_linker_inputs = 0;
6901e4b17023SJohn Marino for (i = 0; (int) i < n_infiles; i++)
6902e4b17023SJohn Marino if (explicit_link_files[i] || outfiles[i] != NULL)
6903e4b17023SJohn Marino num_linker_inputs++;
6904e4b17023SJohn Marino
6905e4b17023SJohn Marino /* Run ld to link all the compiler output files. */
6906e4b17023SJohn Marino
6907e4b17023SJohn Marino if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
6908e4b17023SJohn Marino {
6909e4b17023SJohn Marino int tmp = execution_count;
6910e4b17023SJohn Marino
6911e4b17023SJohn Marino if (! have_c)
6912e4b17023SJohn Marino {
6913e4b17023SJohn Marino #if HAVE_LTO_PLUGIN > 0
6914e4b17023SJohn Marino #if HAVE_LTO_PLUGIN == 2
6915e4b17023SJohn Marino const char *fno_use_linker_plugin = "fno-use-linker-plugin";
6916e4b17023SJohn Marino #else
6917e4b17023SJohn Marino const char *fuse_linker_plugin = "fuse-linker-plugin";
6918e4b17023SJohn Marino #endif
6919e4b17023SJohn Marino #endif
6920e4b17023SJohn Marino
6921e4b17023SJohn Marino /* We'll use ld if we can't find collect2. */
6922e4b17023SJohn Marino if (! strcmp (linker_name_spec, "collect2"))
6923e4b17023SJohn Marino {
6924e4b17023SJohn Marino char *s = find_a_file (&exec_prefixes, "collect2", X_OK, false);
6925e4b17023SJohn Marino if (s == NULL)
6926e4b17023SJohn Marino linker_name_spec = "ld";
6927e4b17023SJohn Marino }
6928e4b17023SJohn Marino
6929e4b17023SJohn Marino #if HAVE_LTO_PLUGIN > 0
6930e4b17023SJohn Marino #if HAVE_LTO_PLUGIN == 2
6931e4b17023SJohn Marino if (!switch_matches (fno_use_linker_plugin,
6932e4b17023SJohn Marino fno_use_linker_plugin
6933e4b17023SJohn Marino + strlen (fno_use_linker_plugin), 0))
6934e4b17023SJohn Marino #else
6935e4b17023SJohn Marino if (switch_matches (fuse_linker_plugin,
6936e4b17023SJohn Marino fuse_linker_plugin
6937e4b17023SJohn Marino + strlen (fuse_linker_plugin), 0))
6938e4b17023SJohn Marino #endif
6939e4b17023SJohn Marino {
69405ce9237cSJohn Marino char *temp_spec = find_a_file (&exec_prefixes,
6941e4b17023SJohn Marino LTOPLUGINSONAME, R_OK,
6942e4b17023SJohn Marino false);
69435ce9237cSJohn Marino if (!temp_spec)
6944e4b17023SJohn Marino fatal_error ("-fuse-linker-plugin, but %s not found",
6945e4b17023SJohn Marino LTOPLUGINSONAME);
69465ce9237cSJohn Marino linker_plugin_file_spec = convert_white_space (temp_spec);
6947e4b17023SJohn Marino }
6948e4b17023SJohn Marino #endif
6949e4b17023SJohn Marino lto_gcc_spec = argv[0];
6950e4b17023SJohn Marino }
6951e4b17023SJohn Marino
6952e4b17023SJohn Marino /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
6953e4b17023SJohn Marino for collect. */
6954e4b17023SJohn Marino putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
6955e4b17023SJohn Marino putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
6956e4b17023SJohn Marino
6957e4b17023SJohn Marino if (print_subprocess_help == 1)
6958e4b17023SJohn Marino {
6959e4b17023SJohn Marino printf (_("\nLinker options\n==============\n\n"));
6960e4b17023SJohn Marino printf (_("Use \"-Wl,OPTION\" to pass \"OPTION\""
6961e4b17023SJohn Marino " to the linker.\n\n"));
6962e4b17023SJohn Marino fflush (stdout);
6963e4b17023SJohn Marino }
6964e4b17023SJohn Marino value = do_spec (link_command_spec);
6965e4b17023SJohn Marino if (value < 0)
6966e4b17023SJohn Marino errorcount = 1;
6967e4b17023SJohn Marino linker_was_run = (tmp != execution_count);
6968e4b17023SJohn Marino }
6969e4b17023SJohn Marino
6970e4b17023SJohn Marino /* If options said don't run linker,
6971e4b17023SJohn Marino complain about input files to be given to the linker. */
6972e4b17023SJohn Marino
6973e4b17023SJohn Marino if (! linker_was_run && !seen_error ())
6974e4b17023SJohn Marino for (i = 0; (int) i < n_infiles; i++)
6975e4b17023SJohn Marino if (explicit_link_files[i]
6976e4b17023SJohn Marino && !(infiles[i].language && infiles[i].language[0] == '*'))
6977e4b17023SJohn Marino warning (0, "%s: linker input file unused because linking not done",
6978e4b17023SJohn Marino outfiles[i]);
6979e4b17023SJohn Marino
6980e4b17023SJohn Marino /* Delete some or all of the temporary files we made. */
6981e4b17023SJohn Marino
6982e4b17023SJohn Marino if (seen_error ())
6983e4b17023SJohn Marino delete_failure_queue ();
6984e4b17023SJohn Marino delete_temp_files ();
6985e4b17023SJohn Marino
6986e4b17023SJohn Marino if (print_help_list)
6987e4b17023SJohn Marino {
6988e4b17023SJohn Marino printf (("\nFor bug reporting instructions, please see:\n"));
6989e4b17023SJohn Marino printf ("%s\n", bug_report_url);
6990e4b17023SJohn Marino }
6991e4b17023SJohn Marino
6992e4b17023SJohn Marino out:
6993e4b17023SJohn Marino return (signal_count != 0 ? 2
6994e4b17023SJohn Marino : seen_error () ? (pass_exit_codes ? greatest_status : 1)
6995e4b17023SJohn Marino : 0);
6996e4b17023SJohn Marino }
6997e4b17023SJohn Marino
6998e4b17023SJohn Marino /* Find the proper compilation spec for the file name NAME,
6999e4b17023SJohn Marino whose length is LENGTH. LANGUAGE is the specified language,
7000e4b17023SJohn Marino or 0 if this file is to be passed to the linker. */
7001e4b17023SJohn Marino
7002e4b17023SJohn Marino static struct compiler *
lookup_compiler(const char * name,size_t length,const char * language)7003e4b17023SJohn Marino lookup_compiler (const char *name, size_t length, const char *language)
7004e4b17023SJohn Marino {
7005e4b17023SJohn Marino struct compiler *cp;
7006e4b17023SJohn Marino
7007e4b17023SJohn Marino /* If this was specified by the user to be a linker input, indicate that. */
7008e4b17023SJohn Marino if (language != 0 && language[0] == '*')
7009e4b17023SJohn Marino return 0;
7010e4b17023SJohn Marino
7011e4b17023SJohn Marino /* Otherwise, look for the language, if one is spec'd. */
7012e4b17023SJohn Marino if (language != 0)
7013e4b17023SJohn Marino {
7014e4b17023SJohn Marino for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
7015e4b17023SJohn Marino if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language))
7016e4b17023SJohn Marino return cp;
7017e4b17023SJohn Marino
7018e4b17023SJohn Marino error ("language %s not recognized", language);
7019e4b17023SJohn Marino return 0;
7020e4b17023SJohn Marino }
7021e4b17023SJohn Marino
7022e4b17023SJohn Marino /* Look for a suffix. */
7023e4b17023SJohn Marino for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
7024e4b17023SJohn Marino {
7025e4b17023SJohn Marino if (/* The suffix `-' matches only the file name `-'. */
7026e4b17023SJohn Marino (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
7027e4b17023SJohn Marino || (strlen (cp->suffix) < length
7028e4b17023SJohn Marino /* See if the suffix matches the end of NAME. */
7029e4b17023SJohn Marino && !strcmp (cp->suffix,
7030e4b17023SJohn Marino name + length - strlen (cp->suffix))
7031e4b17023SJohn Marino ))
7032e4b17023SJohn Marino break;
7033e4b17023SJohn Marino }
7034e4b17023SJohn Marino
7035e4b17023SJohn Marino #if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
7036e4b17023SJohn Marino /* Look again, but case-insensitively this time. */
7037e4b17023SJohn Marino if (cp < compilers)
7038e4b17023SJohn Marino for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
7039e4b17023SJohn Marino {
7040e4b17023SJohn Marino if (/* The suffix `-' matches only the file name `-'. */
7041e4b17023SJohn Marino (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
7042e4b17023SJohn Marino || (strlen (cp->suffix) < length
7043e4b17023SJohn Marino /* See if the suffix matches the end of NAME. */
7044e4b17023SJohn Marino && ((!strcmp (cp->suffix,
7045e4b17023SJohn Marino name + length - strlen (cp->suffix))
7046e4b17023SJohn Marino || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
7047e4b17023SJohn Marino && !strcasecmp (cp->suffix,
7048e4b17023SJohn Marino name + length - strlen (cp->suffix)))
7049e4b17023SJohn Marino ))
7050e4b17023SJohn Marino break;
7051e4b17023SJohn Marino }
7052e4b17023SJohn Marino #endif
7053e4b17023SJohn Marino
7054e4b17023SJohn Marino if (cp >= compilers)
7055e4b17023SJohn Marino {
7056e4b17023SJohn Marino if (cp->spec[0] != '@')
7057e4b17023SJohn Marino /* A non-alias entry: return it. */
7058e4b17023SJohn Marino return cp;
7059e4b17023SJohn Marino
7060e4b17023SJohn Marino /* An alias entry maps a suffix to a language.
7061e4b17023SJohn Marino Search for the language; pass 0 for NAME and LENGTH
7062e4b17023SJohn Marino to avoid infinite recursion if language not found. */
7063e4b17023SJohn Marino return lookup_compiler (NULL, 0, cp->spec + 1);
7064e4b17023SJohn Marino }
7065e4b17023SJohn Marino return 0;
7066e4b17023SJohn Marino }
7067e4b17023SJohn Marino
7068e4b17023SJohn Marino static char *
save_string(const char * s,int len)7069e4b17023SJohn Marino save_string (const char *s, int len)
7070e4b17023SJohn Marino {
7071e4b17023SJohn Marino char *result = XNEWVEC (char, len + 1);
7072e4b17023SJohn Marino
7073e4b17023SJohn Marino memcpy (result, s, len);
7074e4b17023SJohn Marino result[len] = 0;
7075e4b17023SJohn Marino return result;
7076e4b17023SJohn Marino }
7077e4b17023SJohn Marino
7078e4b17023SJohn Marino void
pfatal_with_name(const char * name)7079e4b17023SJohn Marino pfatal_with_name (const char *name)
7080e4b17023SJohn Marino {
7081e4b17023SJohn Marino perror_with_name (name);
7082e4b17023SJohn Marino delete_temp_files ();
7083e4b17023SJohn Marino exit (1);
7084e4b17023SJohn Marino }
7085e4b17023SJohn Marino
7086e4b17023SJohn Marino static void
perror_with_name(const char * name)7087e4b17023SJohn Marino perror_with_name (const char *name)
7088e4b17023SJohn Marino {
7089e4b17023SJohn Marino error ("%s: %m", name);
7090e4b17023SJohn Marino }
7091e4b17023SJohn Marino
7092e4b17023SJohn Marino static inline void
validate_switches_from_spec(const char * spec)7093e4b17023SJohn Marino validate_switches_from_spec (const char *spec)
7094e4b17023SJohn Marino {
7095e4b17023SJohn Marino const char *p = spec;
7096e4b17023SJohn Marino char c;
7097e4b17023SJohn Marino while ((c = *p++))
7098e4b17023SJohn Marino if (c == '%' && (*p == '{' || *p == '<' || (*p == 'W' && *++p == '{')))
7099e4b17023SJohn Marino /* We have a switch spec. */
7100e4b17023SJohn Marino p = validate_switches (p + 1);
7101e4b17023SJohn Marino }
7102e4b17023SJohn Marino
7103e4b17023SJohn Marino static void
validate_all_switches(void)7104e4b17023SJohn Marino validate_all_switches (void)
7105e4b17023SJohn Marino {
7106e4b17023SJohn Marino struct compiler *comp;
7107e4b17023SJohn Marino struct spec_list *spec;
7108e4b17023SJohn Marino
7109e4b17023SJohn Marino for (comp = compilers; comp->spec; comp++)
7110e4b17023SJohn Marino validate_switches_from_spec (comp->spec);
7111e4b17023SJohn Marino
7112e4b17023SJohn Marino /* Look through the linked list of specs read from the specs file. */
7113e4b17023SJohn Marino for (spec = specs; spec; spec = spec->next)
7114e4b17023SJohn Marino validate_switches_from_spec (*spec->ptr_spec);
7115e4b17023SJohn Marino
7116e4b17023SJohn Marino validate_switches_from_spec (link_command_spec);
7117e4b17023SJohn Marino }
7118e4b17023SJohn Marino
7119e4b17023SJohn Marino /* Look at the switch-name that comes after START
7120e4b17023SJohn Marino and mark as valid all supplied switches that match it. */
7121e4b17023SJohn Marino
7122e4b17023SJohn Marino static const char *
validate_switches(const char * start)7123e4b17023SJohn Marino validate_switches (const char *start)
7124e4b17023SJohn Marino {
7125e4b17023SJohn Marino const char *p = start;
7126e4b17023SJohn Marino const char *atom;
7127e4b17023SJohn Marino size_t len;
7128e4b17023SJohn Marino int i;
7129e4b17023SJohn Marino bool suffix = false;
7130e4b17023SJohn Marino bool starred = false;
7131e4b17023SJohn Marino
7132e4b17023SJohn Marino #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
7133e4b17023SJohn Marino
7134e4b17023SJohn Marino next_member:
7135e4b17023SJohn Marino SKIP_WHITE ();
7136e4b17023SJohn Marino
7137e4b17023SJohn Marino if (*p == '!')
7138e4b17023SJohn Marino p++;
7139e4b17023SJohn Marino
7140e4b17023SJohn Marino SKIP_WHITE ();
7141e4b17023SJohn Marino if (*p == '.' || *p == ',')
7142e4b17023SJohn Marino suffix = true, p++;
7143e4b17023SJohn Marino
7144e4b17023SJohn Marino atom = p;
7145e4b17023SJohn Marino while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
7146e4b17023SJohn Marino || *p == ',' || *p == '.' || *p == '@')
7147e4b17023SJohn Marino p++;
7148e4b17023SJohn Marino len = p - atom;
7149e4b17023SJohn Marino
7150e4b17023SJohn Marino if (*p == '*')
7151e4b17023SJohn Marino starred = true, p++;
7152e4b17023SJohn Marino
7153e4b17023SJohn Marino SKIP_WHITE ();
7154e4b17023SJohn Marino
7155e4b17023SJohn Marino if (!suffix)
7156e4b17023SJohn Marino {
7157e4b17023SJohn Marino /* Mark all matching switches as valid. */
7158e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
7159e4b17023SJohn Marino if (!strncmp (switches[i].part1, atom, len)
7160e4b17023SJohn Marino && (starred || switches[i].part1[len] == 0))
7161e4b17023SJohn Marino switches[i].validated = 1;
7162e4b17023SJohn Marino }
7163e4b17023SJohn Marino
7164e4b17023SJohn Marino if (*p) p++;
7165e4b17023SJohn Marino if (*p && (p[-1] == '|' || p[-1] == '&'))
7166e4b17023SJohn Marino goto next_member;
7167e4b17023SJohn Marino
7168e4b17023SJohn Marino if (*p && p[-1] == ':')
7169e4b17023SJohn Marino {
7170e4b17023SJohn Marino while (*p && *p != ';' && *p != '}')
7171e4b17023SJohn Marino {
7172e4b17023SJohn Marino if (*p == '%')
7173e4b17023SJohn Marino {
7174e4b17023SJohn Marino p++;
7175e4b17023SJohn Marino if (*p == '{' || *p == '<')
7176e4b17023SJohn Marino p = validate_switches (p+1);
7177e4b17023SJohn Marino else if (p[0] == 'W' && p[1] == '{')
7178e4b17023SJohn Marino p = validate_switches (p+2);
7179e4b17023SJohn Marino }
7180e4b17023SJohn Marino else
7181e4b17023SJohn Marino p++;
7182e4b17023SJohn Marino }
7183e4b17023SJohn Marino
7184e4b17023SJohn Marino if (*p) p++;
7185e4b17023SJohn Marino if (*p && p[-1] == ';')
7186e4b17023SJohn Marino goto next_member;
7187e4b17023SJohn Marino }
7188e4b17023SJohn Marino
7189e4b17023SJohn Marino return p;
7190e4b17023SJohn Marino #undef SKIP_WHITE
7191e4b17023SJohn Marino }
7192e4b17023SJohn Marino
7193e4b17023SJohn Marino struct mdswitchstr
7194e4b17023SJohn Marino {
7195e4b17023SJohn Marino const char *str;
7196e4b17023SJohn Marino int len;
7197e4b17023SJohn Marino };
7198e4b17023SJohn Marino
7199e4b17023SJohn Marino static struct mdswitchstr *mdswitches;
7200e4b17023SJohn Marino static int n_mdswitches;
7201e4b17023SJohn Marino
7202e4b17023SJohn Marino /* Check whether a particular argument was used. The first time we
7203e4b17023SJohn Marino canonicalize the switches to keep only the ones we care about. */
7204e4b17023SJohn Marino
7205e4b17023SJohn Marino static int
used_arg(const char * p,int len)7206e4b17023SJohn Marino used_arg (const char *p, int len)
7207e4b17023SJohn Marino {
7208e4b17023SJohn Marino struct mswitchstr
7209e4b17023SJohn Marino {
7210e4b17023SJohn Marino const char *str;
7211e4b17023SJohn Marino const char *replace;
7212e4b17023SJohn Marino int len;
7213e4b17023SJohn Marino int rep_len;
7214e4b17023SJohn Marino };
7215e4b17023SJohn Marino
7216e4b17023SJohn Marino static struct mswitchstr *mswitches;
7217e4b17023SJohn Marino static int n_mswitches;
7218e4b17023SJohn Marino int i, j;
7219e4b17023SJohn Marino
7220e4b17023SJohn Marino if (!mswitches)
7221e4b17023SJohn Marino {
7222e4b17023SJohn Marino struct mswitchstr *matches;
7223e4b17023SJohn Marino const char *q;
7224e4b17023SJohn Marino int cnt = 0;
7225e4b17023SJohn Marino
7226e4b17023SJohn Marino /* Break multilib_matches into the component strings of string
7227e4b17023SJohn Marino and replacement string. */
7228e4b17023SJohn Marino for (q = multilib_matches; *q != '\0'; q++)
7229e4b17023SJohn Marino if (*q == ';')
7230e4b17023SJohn Marino cnt++;
7231e4b17023SJohn Marino
7232e4b17023SJohn Marino matches
7233e4b17023SJohn Marino = (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
7234e4b17023SJohn Marino i = 0;
7235e4b17023SJohn Marino q = multilib_matches;
7236e4b17023SJohn Marino while (*q != '\0')
7237e4b17023SJohn Marino {
7238e4b17023SJohn Marino matches[i].str = q;
7239e4b17023SJohn Marino while (*q != ' ')
7240e4b17023SJohn Marino {
7241e4b17023SJohn Marino if (*q == '\0')
7242e4b17023SJohn Marino {
7243e4b17023SJohn Marino invalid_matches:
7244e4b17023SJohn Marino fatal_error ("multilib spec %qs is invalid",
7245e4b17023SJohn Marino multilib_matches);
7246e4b17023SJohn Marino }
7247e4b17023SJohn Marino q++;
7248e4b17023SJohn Marino }
7249e4b17023SJohn Marino matches[i].len = q - matches[i].str;
7250e4b17023SJohn Marino
7251e4b17023SJohn Marino matches[i].replace = ++q;
7252e4b17023SJohn Marino while (*q != ';' && *q != '\0')
7253e4b17023SJohn Marino {
7254e4b17023SJohn Marino if (*q == ' ')
7255e4b17023SJohn Marino goto invalid_matches;
7256e4b17023SJohn Marino q++;
7257e4b17023SJohn Marino }
7258e4b17023SJohn Marino matches[i].rep_len = q - matches[i].replace;
7259e4b17023SJohn Marino i++;
7260e4b17023SJohn Marino if (*q == ';')
7261e4b17023SJohn Marino q++;
7262e4b17023SJohn Marino }
7263e4b17023SJohn Marino
7264e4b17023SJohn Marino /* Now build a list of the replacement string for switches that we care
7265e4b17023SJohn Marino about. Make sure we allocate at least one entry. This prevents
7266e4b17023SJohn Marino xmalloc from calling fatal, and prevents us from re-executing this
7267e4b17023SJohn Marino block of code. */
7268e4b17023SJohn Marino mswitches
7269e4b17023SJohn Marino = XNEWVEC (struct mswitchstr, n_mdswitches + (n_switches ? n_switches : 1));
7270e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
7271e4b17023SJohn Marino if ((switches[i].live_cond & SWITCH_IGNORE) == 0)
7272e4b17023SJohn Marino {
7273e4b17023SJohn Marino int xlen = strlen (switches[i].part1);
7274e4b17023SJohn Marino for (j = 0; j < cnt; j++)
7275e4b17023SJohn Marino if (xlen == matches[j].len
7276e4b17023SJohn Marino && ! strncmp (switches[i].part1, matches[j].str, xlen))
7277e4b17023SJohn Marino {
7278e4b17023SJohn Marino mswitches[n_mswitches].str = matches[j].replace;
7279e4b17023SJohn Marino mswitches[n_mswitches].len = matches[j].rep_len;
7280e4b17023SJohn Marino mswitches[n_mswitches].replace = (char *) 0;
7281e4b17023SJohn Marino mswitches[n_mswitches].rep_len = 0;
7282e4b17023SJohn Marino n_mswitches++;
7283e4b17023SJohn Marino break;
7284e4b17023SJohn Marino }
7285e4b17023SJohn Marino }
7286e4b17023SJohn Marino
7287e4b17023SJohn Marino /* Add MULTILIB_DEFAULTS switches too, as long as they were not present
7288e4b17023SJohn Marino on the command line nor any options mutually incompatible with
7289e4b17023SJohn Marino them. */
7290e4b17023SJohn Marino for (i = 0; i < n_mdswitches; i++)
7291e4b17023SJohn Marino {
7292e4b17023SJohn Marino const char *r;
7293e4b17023SJohn Marino
7294e4b17023SJohn Marino for (q = multilib_options; *q != '\0'; q++)
7295e4b17023SJohn Marino {
7296e4b17023SJohn Marino while (*q == ' ')
7297e4b17023SJohn Marino q++;
7298e4b17023SJohn Marino
7299e4b17023SJohn Marino r = q;
7300e4b17023SJohn Marino while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
7301e4b17023SJohn Marino || strchr (" /", q[mdswitches[i].len]) == NULL)
7302e4b17023SJohn Marino {
7303e4b17023SJohn Marino while (*q != ' ' && *q != '/' && *q != '\0')
7304e4b17023SJohn Marino q++;
7305e4b17023SJohn Marino if (*q != '/')
7306e4b17023SJohn Marino break;
7307e4b17023SJohn Marino q++;
7308e4b17023SJohn Marino }
7309e4b17023SJohn Marino
7310e4b17023SJohn Marino if (*q != ' ' && *q != '\0')
7311e4b17023SJohn Marino {
7312e4b17023SJohn Marino while (*r != ' ' && *r != '\0')
7313e4b17023SJohn Marino {
7314e4b17023SJohn Marino q = r;
7315e4b17023SJohn Marino while (*q != ' ' && *q != '/' && *q != '\0')
7316e4b17023SJohn Marino q++;
7317e4b17023SJohn Marino
7318e4b17023SJohn Marino if (used_arg (r, q - r))
7319e4b17023SJohn Marino break;
7320e4b17023SJohn Marino
7321e4b17023SJohn Marino if (*q != '/')
7322e4b17023SJohn Marino {
7323e4b17023SJohn Marino mswitches[n_mswitches].str = mdswitches[i].str;
7324e4b17023SJohn Marino mswitches[n_mswitches].len = mdswitches[i].len;
7325e4b17023SJohn Marino mswitches[n_mswitches].replace = (char *) 0;
7326e4b17023SJohn Marino mswitches[n_mswitches].rep_len = 0;
7327e4b17023SJohn Marino n_mswitches++;
7328e4b17023SJohn Marino break;
7329e4b17023SJohn Marino }
7330e4b17023SJohn Marino
7331e4b17023SJohn Marino r = q + 1;
7332e4b17023SJohn Marino }
7333e4b17023SJohn Marino break;
7334e4b17023SJohn Marino }
7335e4b17023SJohn Marino }
7336e4b17023SJohn Marino }
7337e4b17023SJohn Marino }
7338e4b17023SJohn Marino
7339e4b17023SJohn Marino for (i = 0; i < n_mswitches; i++)
7340e4b17023SJohn Marino if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
7341e4b17023SJohn Marino return 1;
7342e4b17023SJohn Marino
7343e4b17023SJohn Marino return 0;
7344e4b17023SJohn Marino }
7345e4b17023SJohn Marino
7346e4b17023SJohn Marino static int
default_arg(const char * p,int len)7347e4b17023SJohn Marino default_arg (const char *p, int len)
7348e4b17023SJohn Marino {
7349e4b17023SJohn Marino int i;
7350e4b17023SJohn Marino
7351e4b17023SJohn Marino for (i = 0; i < n_mdswitches; i++)
7352e4b17023SJohn Marino if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
7353e4b17023SJohn Marino return 1;
7354e4b17023SJohn Marino
7355e4b17023SJohn Marino return 0;
7356e4b17023SJohn Marino }
7357e4b17023SJohn Marino
7358e4b17023SJohn Marino /* Work out the subdirectory to use based on the options. The format of
7359e4b17023SJohn Marino multilib_select is a list of elements. Each element is a subdirectory
7360e4b17023SJohn Marino name followed by a list of options followed by a semicolon. The format
7361e4b17023SJohn Marino of multilib_exclusions is the same, but without the preceding
7362e4b17023SJohn Marino directory. First gcc will check the exclusions, if none of the options
7363e4b17023SJohn Marino beginning with an exclamation point are present, and all of the other
7364e4b17023SJohn Marino options are present, then we will ignore this completely. Passing
7365e4b17023SJohn Marino that, gcc will consider each multilib_select in turn using the same
7366e4b17023SJohn Marino rules for matching the options. If a match is found, that subdirectory
73675ce9237cSJohn Marino will be used.
73685ce9237cSJohn Marino A subdirectory name is optionally followed by a colon and the corresponding
73695ce9237cSJohn Marino multiarch name. */
7370e4b17023SJohn Marino
7371e4b17023SJohn Marino static void
set_multilib_dir(void)7372e4b17023SJohn Marino set_multilib_dir (void)
7373e4b17023SJohn Marino {
7374e4b17023SJohn Marino const char *p;
7375e4b17023SJohn Marino unsigned int this_path_len;
7376e4b17023SJohn Marino const char *this_path, *this_arg;
7377e4b17023SJohn Marino const char *start, *end;
7378e4b17023SJohn Marino int not_arg;
7379e4b17023SJohn Marino int ok, ndfltok, first;
7380e4b17023SJohn Marino
7381e4b17023SJohn Marino n_mdswitches = 0;
7382e4b17023SJohn Marino start = multilib_defaults;
7383e4b17023SJohn Marino while (*start == ' ' || *start == '\t')
7384e4b17023SJohn Marino start++;
7385e4b17023SJohn Marino while (*start != '\0')
7386e4b17023SJohn Marino {
7387e4b17023SJohn Marino n_mdswitches++;
7388e4b17023SJohn Marino while (*start != ' ' && *start != '\t' && *start != '\0')
7389e4b17023SJohn Marino start++;
7390e4b17023SJohn Marino while (*start == ' ' || *start == '\t')
7391e4b17023SJohn Marino start++;
7392e4b17023SJohn Marino }
7393e4b17023SJohn Marino
7394e4b17023SJohn Marino if (n_mdswitches)
7395e4b17023SJohn Marino {
7396e4b17023SJohn Marino int i = 0;
7397e4b17023SJohn Marino
7398e4b17023SJohn Marino mdswitches = XNEWVEC (struct mdswitchstr, n_mdswitches);
7399e4b17023SJohn Marino for (start = multilib_defaults; *start != '\0'; start = end + 1)
7400e4b17023SJohn Marino {
7401e4b17023SJohn Marino while (*start == ' ' || *start == '\t')
7402e4b17023SJohn Marino start++;
7403e4b17023SJohn Marino
7404e4b17023SJohn Marino if (*start == '\0')
7405e4b17023SJohn Marino break;
7406e4b17023SJohn Marino
7407e4b17023SJohn Marino for (end = start + 1;
7408e4b17023SJohn Marino *end != ' ' && *end != '\t' && *end != '\0'; end++)
7409e4b17023SJohn Marino ;
7410e4b17023SJohn Marino
7411e4b17023SJohn Marino obstack_grow (&multilib_obstack, start, end - start);
7412e4b17023SJohn Marino obstack_1grow (&multilib_obstack, 0);
7413e4b17023SJohn Marino mdswitches[i].str = XOBFINISH (&multilib_obstack, const char *);
7414e4b17023SJohn Marino mdswitches[i++].len = end - start;
7415e4b17023SJohn Marino
7416e4b17023SJohn Marino if (*end == '\0')
7417e4b17023SJohn Marino break;
7418e4b17023SJohn Marino }
7419e4b17023SJohn Marino }
7420e4b17023SJohn Marino
7421e4b17023SJohn Marino p = multilib_exclusions;
7422e4b17023SJohn Marino while (*p != '\0')
7423e4b17023SJohn Marino {
7424e4b17023SJohn Marino /* Ignore newlines. */
7425e4b17023SJohn Marino if (*p == '\n')
7426e4b17023SJohn Marino {
7427e4b17023SJohn Marino ++p;
7428e4b17023SJohn Marino continue;
7429e4b17023SJohn Marino }
7430e4b17023SJohn Marino
7431e4b17023SJohn Marino /* Check the arguments. */
7432e4b17023SJohn Marino ok = 1;
7433e4b17023SJohn Marino while (*p != ';')
7434e4b17023SJohn Marino {
7435e4b17023SJohn Marino if (*p == '\0')
7436e4b17023SJohn Marino {
7437e4b17023SJohn Marino invalid_exclusions:
7438e4b17023SJohn Marino fatal_error ("multilib exclusions %qs is invalid",
7439e4b17023SJohn Marino multilib_exclusions);
7440e4b17023SJohn Marino }
7441e4b17023SJohn Marino
7442e4b17023SJohn Marino if (! ok)
7443e4b17023SJohn Marino {
7444e4b17023SJohn Marino ++p;
7445e4b17023SJohn Marino continue;
7446e4b17023SJohn Marino }
7447e4b17023SJohn Marino
7448e4b17023SJohn Marino this_arg = p;
7449e4b17023SJohn Marino while (*p != ' ' && *p != ';')
7450e4b17023SJohn Marino {
7451e4b17023SJohn Marino if (*p == '\0')
7452e4b17023SJohn Marino goto invalid_exclusions;
7453e4b17023SJohn Marino ++p;
7454e4b17023SJohn Marino }
7455e4b17023SJohn Marino
7456e4b17023SJohn Marino if (*this_arg != '!')
7457e4b17023SJohn Marino not_arg = 0;
7458e4b17023SJohn Marino else
7459e4b17023SJohn Marino {
7460e4b17023SJohn Marino not_arg = 1;
7461e4b17023SJohn Marino ++this_arg;
7462e4b17023SJohn Marino }
7463e4b17023SJohn Marino
7464e4b17023SJohn Marino ok = used_arg (this_arg, p - this_arg);
7465e4b17023SJohn Marino if (not_arg)
7466e4b17023SJohn Marino ok = ! ok;
7467e4b17023SJohn Marino
7468e4b17023SJohn Marino if (*p == ' ')
7469e4b17023SJohn Marino ++p;
7470e4b17023SJohn Marino }
7471e4b17023SJohn Marino
7472e4b17023SJohn Marino if (ok)
7473e4b17023SJohn Marino return;
7474e4b17023SJohn Marino
7475e4b17023SJohn Marino ++p;
7476e4b17023SJohn Marino }
7477e4b17023SJohn Marino
7478e4b17023SJohn Marino first = 1;
7479e4b17023SJohn Marino p = multilib_select;
7480e4b17023SJohn Marino while (*p != '\0')
7481e4b17023SJohn Marino {
7482e4b17023SJohn Marino /* Ignore newlines. */
7483e4b17023SJohn Marino if (*p == '\n')
7484e4b17023SJohn Marino {
7485e4b17023SJohn Marino ++p;
7486e4b17023SJohn Marino continue;
7487e4b17023SJohn Marino }
7488e4b17023SJohn Marino
7489e4b17023SJohn Marino /* Get the initial path. */
7490e4b17023SJohn Marino this_path = p;
7491e4b17023SJohn Marino while (*p != ' ')
7492e4b17023SJohn Marino {
7493e4b17023SJohn Marino if (*p == '\0')
7494e4b17023SJohn Marino {
7495e4b17023SJohn Marino invalid_select:
7496e4b17023SJohn Marino fatal_error ("multilib select %qs is invalid",
7497e4b17023SJohn Marino multilib_select);
7498e4b17023SJohn Marino }
7499e4b17023SJohn Marino ++p;
7500e4b17023SJohn Marino }
7501e4b17023SJohn Marino this_path_len = p - this_path;
7502e4b17023SJohn Marino
7503e4b17023SJohn Marino /* Check the arguments. */
7504e4b17023SJohn Marino ok = 1;
7505e4b17023SJohn Marino ndfltok = 1;
7506e4b17023SJohn Marino ++p;
7507e4b17023SJohn Marino while (*p != ';')
7508e4b17023SJohn Marino {
7509e4b17023SJohn Marino if (*p == '\0')
7510e4b17023SJohn Marino goto invalid_select;
7511e4b17023SJohn Marino
7512e4b17023SJohn Marino if (! ok)
7513e4b17023SJohn Marino {
7514e4b17023SJohn Marino ++p;
7515e4b17023SJohn Marino continue;
7516e4b17023SJohn Marino }
7517e4b17023SJohn Marino
7518e4b17023SJohn Marino this_arg = p;
7519e4b17023SJohn Marino while (*p != ' ' && *p != ';')
7520e4b17023SJohn Marino {
7521e4b17023SJohn Marino if (*p == '\0')
7522e4b17023SJohn Marino goto invalid_select;
7523e4b17023SJohn Marino ++p;
7524e4b17023SJohn Marino }
7525e4b17023SJohn Marino
7526e4b17023SJohn Marino if (*this_arg != '!')
7527e4b17023SJohn Marino not_arg = 0;
7528e4b17023SJohn Marino else
7529e4b17023SJohn Marino {
7530e4b17023SJohn Marino not_arg = 1;
7531e4b17023SJohn Marino ++this_arg;
7532e4b17023SJohn Marino }
7533e4b17023SJohn Marino
7534e4b17023SJohn Marino /* If this is a default argument, we can just ignore it.
7535e4b17023SJohn Marino This is true even if this_arg begins with '!'. Beginning
7536e4b17023SJohn Marino with '!' does not mean that this argument is necessarily
7537e4b17023SJohn Marino inappropriate for this library: it merely means that
7538e4b17023SJohn Marino there is a more specific library which uses this
7539e4b17023SJohn Marino argument. If this argument is a default, we need not
7540e4b17023SJohn Marino consider that more specific library. */
7541e4b17023SJohn Marino ok = used_arg (this_arg, p - this_arg);
7542e4b17023SJohn Marino if (not_arg)
7543e4b17023SJohn Marino ok = ! ok;
7544e4b17023SJohn Marino
7545e4b17023SJohn Marino if (! ok)
7546e4b17023SJohn Marino ndfltok = 0;
7547e4b17023SJohn Marino
7548e4b17023SJohn Marino if (default_arg (this_arg, p - this_arg))
7549e4b17023SJohn Marino ok = 1;
7550e4b17023SJohn Marino
7551e4b17023SJohn Marino if (*p == ' ')
7552e4b17023SJohn Marino ++p;
7553e4b17023SJohn Marino }
7554e4b17023SJohn Marino
7555e4b17023SJohn Marino if (ok && first)
7556e4b17023SJohn Marino {
7557e4b17023SJohn Marino if (this_path_len != 1
7558e4b17023SJohn Marino || this_path[0] != '.')
7559e4b17023SJohn Marino {
7560e4b17023SJohn Marino char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
7561e4b17023SJohn Marino char *q;
7562e4b17023SJohn Marino
7563e4b17023SJohn Marino strncpy (new_multilib_dir, this_path, this_path_len);
7564e4b17023SJohn Marino new_multilib_dir[this_path_len] = '\0';
7565e4b17023SJohn Marino q = strchr (new_multilib_dir, ':');
7566e4b17023SJohn Marino if (q != NULL)
7567e4b17023SJohn Marino *q = '\0';
7568e4b17023SJohn Marino multilib_dir = new_multilib_dir;
7569e4b17023SJohn Marino }
7570e4b17023SJohn Marino first = 0;
7571e4b17023SJohn Marino }
7572e4b17023SJohn Marino
7573e4b17023SJohn Marino if (ndfltok)
7574e4b17023SJohn Marino {
7575e4b17023SJohn Marino const char *q = this_path, *end = this_path + this_path_len;
7576e4b17023SJohn Marino
7577e4b17023SJohn Marino while (q < end && *q != ':')
7578e4b17023SJohn Marino q++;
7579e4b17023SJohn Marino if (q < end)
7580e4b17023SJohn Marino {
75815ce9237cSJohn Marino const char *q2 = q + 1, *ml_end = end;
75825ce9237cSJohn Marino char *new_multilib_os_dir;
75835ce9237cSJohn Marino
75845ce9237cSJohn Marino while (q2 < end && *q2 != ':')
75855ce9237cSJohn Marino q2++;
75865ce9237cSJohn Marino if (*q2 == ':')
75875ce9237cSJohn Marino ml_end = q2;
75885ce9237cSJohn Marino new_multilib_os_dir = XNEWVEC (char, ml_end - q);
75895ce9237cSJohn Marino memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
75905ce9237cSJohn Marino new_multilib_os_dir[ml_end - q - 1] = '\0';
75915ce9237cSJohn Marino multilib_os_dir = *new_multilib_os_dir ? new_multilib_os_dir : ".";
75925ce9237cSJohn Marino
75935ce9237cSJohn Marino if (q2 < end && *q2 == ':')
75945ce9237cSJohn Marino {
75955ce9237cSJohn Marino char *new_multiarch_dir = XNEWVEC (char, end - q2);
75965ce9237cSJohn Marino memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
75975ce9237cSJohn Marino new_multiarch_dir[end - q2 - 1] = '\0';
75985ce9237cSJohn Marino multiarch_dir = new_multiarch_dir;
75995ce9237cSJohn Marino }
7600e4b17023SJohn Marino break;
7601e4b17023SJohn Marino }
7602e4b17023SJohn Marino }
7603e4b17023SJohn Marino
7604e4b17023SJohn Marino ++p;
7605e4b17023SJohn Marino }
7606e4b17023SJohn Marino
7607e4b17023SJohn Marino if (multilib_dir == NULL && multilib_os_dir != NULL
7608e4b17023SJohn Marino && strcmp (multilib_os_dir, ".") == 0)
7609e4b17023SJohn Marino {
7610e4b17023SJohn Marino free (CONST_CAST (char *, multilib_os_dir));
7611e4b17023SJohn Marino multilib_os_dir = NULL;
7612e4b17023SJohn Marino }
7613e4b17023SJohn Marino else if (multilib_dir != NULL && multilib_os_dir == NULL)
7614e4b17023SJohn Marino multilib_os_dir = multilib_dir;
7615e4b17023SJohn Marino }
7616e4b17023SJohn Marino
7617e4b17023SJohn Marino /* Print out the multiple library subdirectory selection
7618e4b17023SJohn Marino information. This prints out a series of lines. Each line looks
7619e4b17023SJohn Marino like SUBDIRECTORY;@OPTION@OPTION, with as many options as is
7620e4b17023SJohn Marino required. Only the desired options are printed out, the negative
7621e4b17023SJohn Marino matches. The options are print without a leading dash. There are
7622e4b17023SJohn Marino no spaces to make it easy to use the information in the shell.
7623e4b17023SJohn Marino Each subdirectory is printed only once. This assumes the ordering
7624e4b17023SJohn Marino generated by the genmultilib script. Also, we leave out ones that match
7625e4b17023SJohn Marino the exclusions. */
7626e4b17023SJohn Marino
7627e4b17023SJohn Marino static void
print_multilib_info(void)7628e4b17023SJohn Marino print_multilib_info (void)
7629e4b17023SJohn Marino {
7630e4b17023SJohn Marino const char *p = multilib_select;
7631e4b17023SJohn Marino const char *last_path = 0, *this_path;
7632e4b17023SJohn Marino int skip;
7633e4b17023SJohn Marino unsigned int last_path_len = 0;
7634e4b17023SJohn Marino
7635e4b17023SJohn Marino while (*p != '\0')
7636e4b17023SJohn Marino {
7637e4b17023SJohn Marino skip = 0;
7638e4b17023SJohn Marino /* Ignore newlines. */
7639e4b17023SJohn Marino if (*p == '\n')
7640e4b17023SJohn Marino {
7641e4b17023SJohn Marino ++p;
7642e4b17023SJohn Marino continue;
7643e4b17023SJohn Marino }
7644e4b17023SJohn Marino
7645e4b17023SJohn Marino /* Get the initial path. */
7646e4b17023SJohn Marino this_path = p;
7647e4b17023SJohn Marino while (*p != ' ')
7648e4b17023SJohn Marino {
7649e4b17023SJohn Marino if (*p == '\0')
7650e4b17023SJohn Marino {
7651e4b17023SJohn Marino invalid_select:
7652e4b17023SJohn Marino fatal_error ("multilib select %qs is invalid", multilib_select);
7653e4b17023SJohn Marino }
7654e4b17023SJohn Marino
7655e4b17023SJohn Marino ++p;
7656e4b17023SJohn Marino }
7657e4b17023SJohn Marino
7658e4b17023SJohn Marino /* When --disable-multilib was used but target defines
76595ce9237cSJohn Marino MULTILIB_OSDIRNAMES, entries starting with .: (and not starting
76605ce9237cSJohn Marino with .:: for multiarch configurations) are there just to find
76615ce9237cSJohn Marino multilib_os_dir, so skip them from output. */
76625ce9237cSJohn Marino if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
7663e4b17023SJohn Marino skip = 1;
7664e4b17023SJohn Marino
7665e4b17023SJohn Marino /* Check for matches with the multilib_exclusions. We don't bother
7666e4b17023SJohn Marino with the '!' in either list. If any of the exclusion rules match
7667e4b17023SJohn Marino all of its options with the select rule, we skip it. */
7668e4b17023SJohn Marino {
7669e4b17023SJohn Marino const char *e = multilib_exclusions;
7670e4b17023SJohn Marino const char *this_arg;
7671e4b17023SJohn Marino
7672e4b17023SJohn Marino while (*e != '\0')
7673e4b17023SJohn Marino {
7674e4b17023SJohn Marino int m = 1;
7675e4b17023SJohn Marino /* Ignore newlines. */
7676e4b17023SJohn Marino if (*e == '\n')
7677e4b17023SJohn Marino {
7678e4b17023SJohn Marino ++e;
7679e4b17023SJohn Marino continue;
7680e4b17023SJohn Marino }
7681e4b17023SJohn Marino
7682e4b17023SJohn Marino /* Check the arguments. */
7683e4b17023SJohn Marino while (*e != ';')
7684e4b17023SJohn Marino {
7685e4b17023SJohn Marino const char *q;
7686e4b17023SJohn Marino int mp = 0;
7687e4b17023SJohn Marino
7688e4b17023SJohn Marino if (*e == '\0')
7689e4b17023SJohn Marino {
7690e4b17023SJohn Marino invalid_exclusion:
7691e4b17023SJohn Marino fatal_error ("multilib exclusion %qs is invalid",
7692e4b17023SJohn Marino multilib_exclusions);
7693e4b17023SJohn Marino }
7694e4b17023SJohn Marino
7695e4b17023SJohn Marino if (! m)
7696e4b17023SJohn Marino {
7697e4b17023SJohn Marino ++e;
7698e4b17023SJohn Marino continue;
7699e4b17023SJohn Marino }
7700e4b17023SJohn Marino
7701e4b17023SJohn Marino this_arg = e;
7702e4b17023SJohn Marino
7703e4b17023SJohn Marino while (*e != ' ' && *e != ';')
7704e4b17023SJohn Marino {
7705e4b17023SJohn Marino if (*e == '\0')
7706e4b17023SJohn Marino goto invalid_exclusion;
7707e4b17023SJohn Marino ++e;
7708e4b17023SJohn Marino }
7709e4b17023SJohn Marino
7710e4b17023SJohn Marino q = p + 1;
7711e4b17023SJohn Marino while (*q != ';')
7712e4b17023SJohn Marino {
7713e4b17023SJohn Marino const char *arg;
7714e4b17023SJohn Marino int len = e - this_arg;
7715e4b17023SJohn Marino
7716e4b17023SJohn Marino if (*q == '\0')
7717e4b17023SJohn Marino goto invalid_select;
7718e4b17023SJohn Marino
7719e4b17023SJohn Marino arg = q;
7720e4b17023SJohn Marino
7721e4b17023SJohn Marino while (*q != ' ' && *q != ';')
7722e4b17023SJohn Marino {
7723e4b17023SJohn Marino if (*q == '\0')
7724e4b17023SJohn Marino goto invalid_select;
7725e4b17023SJohn Marino ++q;
7726e4b17023SJohn Marino }
7727e4b17023SJohn Marino
7728e4b17023SJohn Marino if (! strncmp (arg, this_arg,
7729e4b17023SJohn Marino (len < q - arg) ? q - arg : len)
7730e4b17023SJohn Marino || default_arg (this_arg, e - this_arg))
7731e4b17023SJohn Marino {
7732e4b17023SJohn Marino mp = 1;
7733e4b17023SJohn Marino break;
7734e4b17023SJohn Marino }
7735e4b17023SJohn Marino
7736e4b17023SJohn Marino if (*q == ' ')
7737e4b17023SJohn Marino ++q;
7738e4b17023SJohn Marino }
7739e4b17023SJohn Marino
7740e4b17023SJohn Marino if (! mp)
7741e4b17023SJohn Marino m = 0;
7742e4b17023SJohn Marino
7743e4b17023SJohn Marino if (*e == ' ')
7744e4b17023SJohn Marino ++e;
7745e4b17023SJohn Marino }
7746e4b17023SJohn Marino
7747e4b17023SJohn Marino if (m)
7748e4b17023SJohn Marino {
7749e4b17023SJohn Marino skip = 1;
7750e4b17023SJohn Marino break;
7751e4b17023SJohn Marino }
7752e4b17023SJohn Marino
7753e4b17023SJohn Marino if (*e != '\0')
7754e4b17023SJohn Marino ++e;
7755e4b17023SJohn Marino }
7756e4b17023SJohn Marino }
7757e4b17023SJohn Marino
7758e4b17023SJohn Marino if (! skip)
7759e4b17023SJohn Marino {
7760e4b17023SJohn Marino /* If this is a duplicate, skip it. */
7761e4b17023SJohn Marino skip = (last_path != 0
7762e4b17023SJohn Marino && (unsigned int) (p - this_path) == last_path_len
7763e4b17023SJohn Marino && ! filename_ncmp (last_path, this_path, last_path_len));
7764e4b17023SJohn Marino
7765e4b17023SJohn Marino last_path = this_path;
7766e4b17023SJohn Marino last_path_len = p - this_path;
7767e4b17023SJohn Marino }
7768e4b17023SJohn Marino
7769e4b17023SJohn Marino /* If this directory requires any default arguments, we can skip
7770e4b17023SJohn Marino it. We will already have printed a directory identical to
7771e4b17023SJohn Marino this one which does not require that default argument. */
7772e4b17023SJohn Marino if (! skip)
7773e4b17023SJohn Marino {
7774e4b17023SJohn Marino const char *q;
7775e4b17023SJohn Marino
7776e4b17023SJohn Marino q = p + 1;
7777e4b17023SJohn Marino while (*q != ';')
7778e4b17023SJohn Marino {
7779e4b17023SJohn Marino const char *arg;
7780e4b17023SJohn Marino
7781e4b17023SJohn Marino if (*q == '\0')
7782e4b17023SJohn Marino goto invalid_select;
7783e4b17023SJohn Marino
7784e4b17023SJohn Marino if (*q == '!')
7785e4b17023SJohn Marino arg = NULL;
7786e4b17023SJohn Marino else
7787e4b17023SJohn Marino arg = q;
7788e4b17023SJohn Marino
7789e4b17023SJohn Marino while (*q != ' ' && *q != ';')
7790e4b17023SJohn Marino {
7791e4b17023SJohn Marino if (*q == '\0')
7792e4b17023SJohn Marino goto invalid_select;
7793e4b17023SJohn Marino ++q;
7794e4b17023SJohn Marino }
7795e4b17023SJohn Marino
7796e4b17023SJohn Marino if (arg != NULL
7797e4b17023SJohn Marino && default_arg (arg, q - arg))
7798e4b17023SJohn Marino {
7799e4b17023SJohn Marino skip = 1;
7800e4b17023SJohn Marino break;
7801e4b17023SJohn Marino }
7802e4b17023SJohn Marino
7803e4b17023SJohn Marino if (*q == ' ')
7804e4b17023SJohn Marino ++q;
7805e4b17023SJohn Marino }
7806e4b17023SJohn Marino }
7807e4b17023SJohn Marino
7808e4b17023SJohn Marino if (! skip)
7809e4b17023SJohn Marino {
7810e4b17023SJohn Marino const char *p1;
7811e4b17023SJohn Marino
7812e4b17023SJohn Marino for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
7813e4b17023SJohn Marino putchar (*p1);
7814e4b17023SJohn Marino putchar (';');
7815e4b17023SJohn Marino }
7816e4b17023SJohn Marino
7817e4b17023SJohn Marino ++p;
7818e4b17023SJohn Marino while (*p != ';')
7819e4b17023SJohn Marino {
7820e4b17023SJohn Marino int use_arg;
7821e4b17023SJohn Marino
7822e4b17023SJohn Marino if (*p == '\0')
7823e4b17023SJohn Marino goto invalid_select;
7824e4b17023SJohn Marino
7825e4b17023SJohn Marino if (skip)
7826e4b17023SJohn Marino {
7827e4b17023SJohn Marino ++p;
7828e4b17023SJohn Marino continue;
7829e4b17023SJohn Marino }
7830e4b17023SJohn Marino
7831e4b17023SJohn Marino use_arg = *p != '!';
7832e4b17023SJohn Marino
7833e4b17023SJohn Marino if (use_arg)
7834e4b17023SJohn Marino putchar ('@');
7835e4b17023SJohn Marino
7836e4b17023SJohn Marino while (*p != ' ' && *p != ';')
7837e4b17023SJohn Marino {
7838e4b17023SJohn Marino if (*p == '\0')
7839e4b17023SJohn Marino goto invalid_select;
7840e4b17023SJohn Marino if (use_arg)
7841e4b17023SJohn Marino putchar (*p);
7842e4b17023SJohn Marino ++p;
7843e4b17023SJohn Marino }
7844e4b17023SJohn Marino
7845e4b17023SJohn Marino if (*p == ' ')
7846e4b17023SJohn Marino ++p;
7847e4b17023SJohn Marino }
7848e4b17023SJohn Marino
7849e4b17023SJohn Marino if (! skip)
7850e4b17023SJohn Marino {
7851e4b17023SJohn Marino /* If there are extra options, print them now. */
7852e4b17023SJohn Marino if (multilib_extra && *multilib_extra)
7853e4b17023SJohn Marino {
7854e4b17023SJohn Marino int print_at = TRUE;
7855e4b17023SJohn Marino const char *q;
7856e4b17023SJohn Marino
7857e4b17023SJohn Marino for (q = multilib_extra; *q != '\0'; q++)
7858e4b17023SJohn Marino {
7859e4b17023SJohn Marino if (*q == ' ')
7860e4b17023SJohn Marino print_at = TRUE;
7861e4b17023SJohn Marino else
7862e4b17023SJohn Marino {
7863e4b17023SJohn Marino if (print_at)
7864e4b17023SJohn Marino putchar ('@');
7865e4b17023SJohn Marino putchar (*q);
7866e4b17023SJohn Marino print_at = FALSE;
7867e4b17023SJohn Marino }
7868e4b17023SJohn Marino }
7869e4b17023SJohn Marino }
7870e4b17023SJohn Marino
7871e4b17023SJohn Marino putchar ('\n');
7872e4b17023SJohn Marino }
7873e4b17023SJohn Marino
7874e4b17023SJohn Marino ++p;
7875e4b17023SJohn Marino }
7876e4b17023SJohn Marino }
7877e4b17023SJohn Marino
7878e4b17023SJohn Marino /* getenv built-in spec function.
7879e4b17023SJohn Marino
7880e4b17023SJohn Marino Returns the value of the environment variable given by its first
7881e4b17023SJohn Marino argument, concatenated with the second argument. If the
7882e4b17023SJohn Marino environment variable is not defined, a fatal error is issued. */
7883e4b17023SJohn Marino
7884e4b17023SJohn Marino static const char *
getenv_spec_function(int argc,const char ** argv)7885e4b17023SJohn Marino getenv_spec_function (int argc, const char **argv)
7886e4b17023SJohn Marino {
7887e4b17023SJohn Marino char *value;
7888e4b17023SJohn Marino char *result;
7889e4b17023SJohn Marino char *ptr;
7890e4b17023SJohn Marino size_t len;
7891e4b17023SJohn Marino
7892e4b17023SJohn Marino if (argc != 2)
7893e4b17023SJohn Marino return NULL;
7894e4b17023SJohn Marino
7895e4b17023SJohn Marino value = getenv (argv[0]);
7896e4b17023SJohn Marino if (!value)
7897e4b17023SJohn Marino fatal_error ("environment variable %qs not defined", argv[0]);
7898e4b17023SJohn Marino
7899e4b17023SJohn Marino /* We have to escape every character of the environment variable so
7900e4b17023SJohn Marino they are not interpreted as active spec characters. A
7901e4b17023SJohn Marino particularly painful case is when we are reading a variable
7902e4b17023SJohn Marino holding a windows path complete with \ separators. */
7903e4b17023SJohn Marino len = strlen (value) * 2 + strlen (argv[1]) + 1;
7904e4b17023SJohn Marino result = XNEWVAR (char, len);
7905e4b17023SJohn Marino for (ptr = result; *value; ptr += 2)
7906e4b17023SJohn Marino {
7907e4b17023SJohn Marino ptr[0] = '\\';
7908e4b17023SJohn Marino ptr[1] = *value++;
7909e4b17023SJohn Marino }
7910e4b17023SJohn Marino
7911e4b17023SJohn Marino strcpy (ptr, argv[1]);
7912e4b17023SJohn Marino
7913e4b17023SJohn Marino return result;
7914e4b17023SJohn Marino }
7915e4b17023SJohn Marino
7916e4b17023SJohn Marino /* if-exists built-in spec function.
7917e4b17023SJohn Marino
7918e4b17023SJohn Marino Checks to see if the file specified by the absolute pathname in
7919e4b17023SJohn Marino ARGS exists. Returns that pathname if found.
7920e4b17023SJohn Marino
7921e4b17023SJohn Marino The usual use for this function is to check for a library file
7922e4b17023SJohn Marino (whose name has been expanded with %s). */
7923e4b17023SJohn Marino
7924e4b17023SJohn Marino static const char *
if_exists_spec_function(int argc,const char ** argv)7925e4b17023SJohn Marino if_exists_spec_function (int argc, const char **argv)
7926e4b17023SJohn Marino {
7927e4b17023SJohn Marino /* Must have only one argument. */
7928e4b17023SJohn Marino if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
7929e4b17023SJohn Marino return argv[0];
7930e4b17023SJohn Marino
7931e4b17023SJohn Marino return NULL;
7932e4b17023SJohn Marino }
7933e4b17023SJohn Marino
7934e4b17023SJohn Marino /* if-exists-else built-in spec function.
7935e4b17023SJohn Marino
7936e4b17023SJohn Marino This is like if-exists, but takes an additional argument which
7937e4b17023SJohn Marino is returned if the first argument does not exist. */
7938e4b17023SJohn Marino
7939e4b17023SJohn Marino static const char *
if_exists_else_spec_function(int argc,const char ** argv)7940e4b17023SJohn Marino if_exists_else_spec_function (int argc, const char **argv)
7941e4b17023SJohn Marino {
7942e4b17023SJohn Marino /* Must have exactly two arguments. */
7943e4b17023SJohn Marino if (argc != 2)
7944e4b17023SJohn Marino return NULL;
7945e4b17023SJohn Marino
7946e4b17023SJohn Marino if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
7947e4b17023SJohn Marino return argv[0];
7948e4b17023SJohn Marino
7949e4b17023SJohn Marino return argv[1];
7950e4b17023SJohn Marino }
7951e4b17023SJohn Marino
7952e4b17023SJohn Marino /* replace-outfile built-in spec function.
7953e4b17023SJohn Marino
7954e4b17023SJohn Marino This looks for the first argument in the outfiles array's name and
7955e4b17023SJohn Marino replaces it with the second argument. */
7956e4b17023SJohn Marino
7957e4b17023SJohn Marino static const char *
replace_outfile_spec_function(int argc,const char ** argv)7958e4b17023SJohn Marino replace_outfile_spec_function (int argc, const char **argv)
7959e4b17023SJohn Marino {
7960e4b17023SJohn Marino int i;
7961e4b17023SJohn Marino /* Must have exactly two arguments. */
7962e4b17023SJohn Marino if (argc != 2)
7963e4b17023SJohn Marino abort ();
7964e4b17023SJohn Marino
7965e4b17023SJohn Marino for (i = 0; i < n_infiles; i++)
7966e4b17023SJohn Marino {
7967e4b17023SJohn Marino if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
7968e4b17023SJohn Marino outfiles[i] = xstrdup (argv[1]);
7969e4b17023SJohn Marino }
7970e4b17023SJohn Marino return NULL;
7971e4b17023SJohn Marino }
7972e4b17023SJohn Marino
7973e4b17023SJohn Marino /* remove-outfile built-in spec function.
7974e4b17023SJohn Marino *
7975e4b17023SJohn Marino * This looks for the first argument in the outfiles array's name and
7976e4b17023SJohn Marino * removes it. */
7977e4b17023SJohn Marino
7978e4b17023SJohn Marino static const char *
remove_outfile_spec_function(int argc,const char ** argv)7979e4b17023SJohn Marino remove_outfile_spec_function (int argc, const char **argv)
7980e4b17023SJohn Marino {
7981e4b17023SJohn Marino int i;
7982e4b17023SJohn Marino /* Must have exactly one argument. */
7983e4b17023SJohn Marino if (argc != 1)
7984e4b17023SJohn Marino abort ();
7985e4b17023SJohn Marino
7986e4b17023SJohn Marino for (i = 0; i < n_infiles; i++)
7987e4b17023SJohn Marino {
7988e4b17023SJohn Marino if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
7989e4b17023SJohn Marino outfiles[i] = NULL;
7990e4b17023SJohn Marino }
7991e4b17023SJohn Marino return NULL;
7992e4b17023SJohn Marino }
7993e4b17023SJohn Marino
7994e4b17023SJohn Marino /* Given two version numbers, compares the two numbers.
7995e4b17023SJohn Marino A version number must match the regular expression
7996e4b17023SJohn Marino ([1-9][0-9]*|0)(\.([1-9][0-9]*|0))*
7997e4b17023SJohn Marino */
7998e4b17023SJohn Marino static int
compare_version_strings(const char * v1,const char * v2)7999e4b17023SJohn Marino compare_version_strings (const char *v1, const char *v2)
8000e4b17023SJohn Marino {
8001e4b17023SJohn Marino int rresult;
8002e4b17023SJohn Marino regex_t r;
8003e4b17023SJohn Marino
8004e4b17023SJohn Marino if (regcomp (&r, "^([1-9][0-9]*|0)(\\.([1-9][0-9]*|0))*$",
8005e4b17023SJohn Marino REG_EXTENDED | REG_NOSUB) != 0)
8006e4b17023SJohn Marino abort ();
8007e4b17023SJohn Marino rresult = regexec (&r, v1, 0, NULL, 0);
8008e4b17023SJohn Marino if (rresult == REG_NOMATCH)
8009e4b17023SJohn Marino fatal_error ("invalid version number %qs", v1);
8010e4b17023SJohn Marino else if (rresult != 0)
8011e4b17023SJohn Marino abort ();
8012e4b17023SJohn Marino rresult = regexec (&r, v2, 0, NULL, 0);
8013e4b17023SJohn Marino if (rresult == REG_NOMATCH)
8014e4b17023SJohn Marino fatal_error ("invalid version number %qs", v2);
8015e4b17023SJohn Marino else if (rresult != 0)
8016e4b17023SJohn Marino abort ();
8017e4b17023SJohn Marino
8018e4b17023SJohn Marino return strverscmp (v1, v2);
8019e4b17023SJohn Marino }
8020e4b17023SJohn Marino
8021e4b17023SJohn Marino
8022e4b17023SJohn Marino /* version_compare built-in spec function.
8023e4b17023SJohn Marino
8024e4b17023SJohn Marino This takes an argument of the following form:
8025e4b17023SJohn Marino
8026e4b17023SJohn Marino <comparison-op> <arg1> [<arg2>] <switch> <result>
8027e4b17023SJohn Marino
8028e4b17023SJohn Marino and produces "result" if the comparison evaluates to true,
8029e4b17023SJohn Marino and nothing if it doesn't.
8030e4b17023SJohn Marino
8031e4b17023SJohn Marino The supported <comparison-op> values are:
8032e4b17023SJohn Marino
8033e4b17023SJohn Marino >= true if switch is a later (or same) version than arg1
8034e4b17023SJohn Marino !> opposite of >=
8035e4b17023SJohn Marino < true if switch is an earlier version than arg1
8036e4b17023SJohn Marino !< opposite of <
8037e4b17023SJohn Marino >< true if switch is arg1 or later, and earlier than arg2
8038e4b17023SJohn Marino <> true if switch is earlier than arg1 or is arg2 or later
8039e4b17023SJohn Marino
8040e4b17023SJohn Marino If the switch is not present, the condition is false unless
8041e4b17023SJohn Marino the first character of the <comparison-op> is '!'.
8042e4b17023SJohn Marino
8043e4b17023SJohn Marino For example,
8044e4b17023SJohn Marino %:version-compare(>= 10.3 mmacosx-version-min= -lmx)
8045e4b17023SJohn Marino adds -lmx if -mmacosx-version-min=10.3.9 was passed. */
8046e4b17023SJohn Marino
8047e4b17023SJohn Marino static const char *
version_compare_spec_function(int argc,const char ** argv)8048e4b17023SJohn Marino version_compare_spec_function (int argc, const char **argv)
8049e4b17023SJohn Marino {
8050e4b17023SJohn Marino int comp1, comp2;
8051e4b17023SJohn Marino size_t switch_len;
8052e4b17023SJohn Marino const char *switch_value = NULL;
8053e4b17023SJohn Marino int nargs = 1, i;
8054e4b17023SJohn Marino bool result;
8055e4b17023SJohn Marino
8056e4b17023SJohn Marino if (argc < 3)
8057e4b17023SJohn Marino fatal_error ("too few arguments to %%:version-compare");
8058e4b17023SJohn Marino if (argv[0][0] == '\0')
8059e4b17023SJohn Marino abort ();
8060e4b17023SJohn Marino if ((argv[0][1] == '<' || argv[0][1] == '>') && argv[0][0] != '!')
8061e4b17023SJohn Marino nargs = 2;
8062e4b17023SJohn Marino if (argc != nargs + 3)
8063e4b17023SJohn Marino fatal_error ("too many arguments to %%:version-compare");
8064e4b17023SJohn Marino
8065e4b17023SJohn Marino switch_len = strlen (argv[nargs + 1]);
8066e4b17023SJohn Marino for (i = 0; i < n_switches; i++)
8067e4b17023SJohn Marino if (!strncmp (switches[i].part1, argv[nargs + 1], switch_len)
8068e4b17023SJohn Marino && check_live_switch (i, switch_len))
8069e4b17023SJohn Marino switch_value = switches[i].part1 + switch_len;
8070e4b17023SJohn Marino
8071e4b17023SJohn Marino if (switch_value == NULL)
8072e4b17023SJohn Marino comp1 = comp2 = -1;
8073e4b17023SJohn Marino else
8074e4b17023SJohn Marino {
8075e4b17023SJohn Marino comp1 = compare_version_strings (switch_value, argv[1]);
8076e4b17023SJohn Marino if (nargs == 2)
8077e4b17023SJohn Marino comp2 = compare_version_strings (switch_value, argv[2]);
8078e4b17023SJohn Marino else
8079e4b17023SJohn Marino comp2 = -1; /* This value unused. */
8080e4b17023SJohn Marino }
8081e4b17023SJohn Marino
8082e4b17023SJohn Marino switch (argv[0][0] << 8 | argv[0][1])
8083e4b17023SJohn Marino {
8084e4b17023SJohn Marino case '>' << 8 | '=':
8085e4b17023SJohn Marino result = comp1 >= 0;
8086e4b17023SJohn Marino break;
8087e4b17023SJohn Marino case '!' << 8 | '<':
8088e4b17023SJohn Marino result = comp1 >= 0 || switch_value == NULL;
8089e4b17023SJohn Marino break;
8090e4b17023SJohn Marino case '<' << 8:
8091e4b17023SJohn Marino result = comp1 < 0;
8092e4b17023SJohn Marino break;
8093e4b17023SJohn Marino case '!' << 8 | '>':
8094e4b17023SJohn Marino result = comp1 < 0 || switch_value == NULL;
8095e4b17023SJohn Marino break;
8096e4b17023SJohn Marino case '>' << 8 | '<':
8097e4b17023SJohn Marino result = comp1 >= 0 && comp2 < 0;
8098e4b17023SJohn Marino break;
8099e4b17023SJohn Marino case '<' << 8 | '>':
8100e4b17023SJohn Marino result = comp1 < 0 || comp2 >= 0;
8101e4b17023SJohn Marino break;
8102e4b17023SJohn Marino
8103e4b17023SJohn Marino default:
8104e4b17023SJohn Marino fatal_error ("unknown operator %qs in %%:version-compare", argv[0]);
8105e4b17023SJohn Marino }
8106e4b17023SJohn Marino if (! result)
8107e4b17023SJohn Marino return NULL;
8108e4b17023SJohn Marino
8109e4b17023SJohn Marino return argv[nargs + 2];
8110e4b17023SJohn Marino }
8111e4b17023SJohn Marino
8112e4b17023SJohn Marino /* %:include builtin spec function. This differs from %include in that it
8113e4b17023SJohn Marino can be nested inside a spec, and thus be conditionalized. It takes
8114e4b17023SJohn Marino one argument, the filename, and looks for it in the startfile path.
8115e4b17023SJohn Marino The result is always NULL, i.e. an empty expansion. */
8116e4b17023SJohn Marino
8117e4b17023SJohn Marino static const char *
include_spec_function(int argc,const char ** argv)8118e4b17023SJohn Marino include_spec_function (int argc, const char **argv)
8119e4b17023SJohn Marino {
8120e4b17023SJohn Marino char *file;
8121e4b17023SJohn Marino
8122e4b17023SJohn Marino if (argc != 1)
8123e4b17023SJohn Marino abort ();
8124e4b17023SJohn Marino
8125e4b17023SJohn Marino file = find_a_file (&startfile_prefixes, argv[0], R_OK, true);
8126e4b17023SJohn Marino read_specs (file ? file : argv[0], FALSE);
8127e4b17023SJohn Marino
8128e4b17023SJohn Marino return NULL;
8129e4b17023SJohn Marino }
8130e4b17023SJohn Marino
8131e4b17023SJohn Marino /* %:find-file spec function. This function replaces its argument by
8132e4b17023SJohn Marino the file found thru find_file, that is the -print-file-name gcc
8133e4b17023SJohn Marino program option. */
8134e4b17023SJohn Marino static const char *
find_file_spec_function(int argc,const char ** argv)8135e4b17023SJohn Marino find_file_spec_function (int argc, const char **argv)
8136e4b17023SJohn Marino {
8137e4b17023SJohn Marino const char *file;
8138e4b17023SJohn Marino
8139e4b17023SJohn Marino if (argc != 1)
8140e4b17023SJohn Marino abort ();
8141e4b17023SJohn Marino
8142e4b17023SJohn Marino file = find_file (argv[0]);
8143e4b17023SJohn Marino return file;
8144e4b17023SJohn Marino }
8145e4b17023SJohn Marino
8146e4b17023SJohn Marino
8147e4b17023SJohn Marino /* %:find-plugindir spec function. This function replaces its argument
8148e4b17023SJohn Marino by the -iplugindir=<dir> option. `dir' is found thru find_file, that
8149e4b17023SJohn Marino is the -print-file-name gcc program option. */
8150e4b17023SJohn Marino static const char *
find_plugindir_spec_function(int argc,const char ** argv ATTRIBUTE_UNUSED)8151e4b17023SJohn Marino find_plugindir_spec_function (int argc, const char **argv ATTRIBUTE_UNUSED)
8152e4b17023SJohn Marino {
8153e4b17023SJohn Marino const char *option;
8154e4b17023SJohn Marino
8155e4b17023SJohn Marino if (argc != 0)
8156e4b17023SJohn Marino abort ();
8157e4b17023SJohn Marino
8158e4b17023SJohn Marino option = concat ("-iplugindir=", find_file ("plugin"), NULL);
8159e4b17023SJohn Marino return option;
8160e4b17023SJohn Marino }
8161e4b17023SJohn Marino
8162e4b17023SJohn Marino
8163e4b17023SJohn Marino /* %:print-asm-header spec function. Print a banner to say that the
8164e4b17023SJohn Marino following output is from the assembler. */
8165e4b17023SJohn Marino
8166e4b17023SJohn Marino static const char *
print_asm_header_spec_function(int arg ATTRIBUTE_UNUSED,const char ** argv ATTRIBUTE_UNUSED)8167e4b17023SJohn Marino print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
8168e4b17023SJohn Marino const char **argv ATTRIBUTE_UNUSED)
8169e4b17023SJohn Marino {
8170e4b17023SJohn Marino printf (_("Assembler options\n=================\n\n"));
8171e4b17023SJohn Marino printf (_("Use \"-Wa,OPTION\" to pass \"OPTION\" to the assembler.\n\n"));
8172e4b17023SJohn Marino fflush (stdout);
8173e4b17023SJohn Marino return NULL;
8174e4b17023SJohn Marino }
8175e4b17023SJohn Marino
8176e4b17023SJohn Marino /* Get a random number for -frandom-seed */
8177e4b17023SJohn Marino
8178e4b17023SJohn Marino static unsigned HOST_WIDE_INT
get_random_number(void)8179e4b17023SJohn Marino get_random_number (void)
8180e4b17023SJohn Marino {
8181e4b17023SJohn Marino unsigned HOST_WIDE_INT ret = 0;
8182e4b17023SJohn Marino int fd;
8183e4b17023SJohn Marino
8184e4b17023SJohn Marino fd = open ("/dev/urandom", O_RDONLY);
8185e4b17023SJohn Marino if (fd >= 0)
8186e4b17023SJohn Marino {
8187e4b17023SJohn Marino read (fd, &ret, sizeof (HOST_WIDE_INT));
8188e4b17023SJohn Marino close (fd);
8189e4b17023SJohn Marino if (ret)
8190e4b17023SJohn Marino return ret;
8191e4b17023SJohn Marino }
8192e4b17023SJohn Marino
8193e4b17023SJohn Marino /* Get some more or less random data. */
8194e4b17023SJohn Marino #ifdef HAVE_GETTIMEOFDAY
8195e4b17023SJohn Marino {
8196e4b17023SJohn Marino struct timeval tv;
8197e4b17023SJohn Marino
8198e4b17023SJohn Marino gettimeofday (&tv, NULL);
8199e4b17023SJohn Marino ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
8200e4b17023SJohn Marino }
8201e4b17023SJohn Marino #else
8202e4b17023SJohn Marino {
8203e4b17023SJohn Marino time_t now = time (NULL);
8204e4b17023SJohn Marino
8205e4b17023SJohn Marino if (now != (time_t)-1)
8206e4b17023SJohn Marino ret = (unsigned) now;
8207e4b17023SJohn Marino }
8208e4b17023SJohn Marino #endif
8209e4b17023SJohn Marino
8210e4b17023SJohn Marino return ret ^ getpid();
8211e4b17023SJohn Marino }
8212e4b17023SJohn Marino
8213e4b17023SJohn Marino /* %:compare-debug-dump-opt spec function. Save the last argument,
8214e4b17023SJohn Marino expected to be the last -fdump-final-insns option, or generate a
8215e4b17023SJohn Marino temporary. */
8216e4b17023SJohn Marino
8217e4b17023SJohn Marino static const char *
compare_debug_dump_opt_spec_function(int arg,const char ** argv ATTRIBUTE_UNUSED)8218e4b17023SJohn Marino compare_debug_dump_opt_spec_function (int arg,
8219e4b17023SJohn Marino const char **argv ATTRIBUTE_UNUSED)
8220e4b17023SJohn Marino {
8221e4b17023SJohn Marino const char *ret;
8222e4b17023SJohn Marino char *name;
8223e4b17023SJohn Marino int which;
8224e4b17023SJohn Marino static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
8225e4b17023SJohn Marino
8226e4b17023SJohn Marino if (arg != 0)
8227e4b17023SJohn Marino fatal_error ("too many arguments to %%:compare-debug-dump-opt");
8228e4b17023SJohn Marino
8229e4b17023SJohn Marino do_spec_2 ("%{fdump-final-insns=*:%*}");
8230e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
8231e4b17023SJohn Marino
8232e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0
8233e4b17023SJohn Marino && strcmp (argv[VEC_length (const_char_p, argbuf) - 1], "."))
8234e4b17023SJohn Marino {
8235e4b17023SJohn Marino if (!compare_debug)
8236e4b17023SJohn Marino return NULL;
8237e4b17023SJohn Marino
8238e4b17023SJohn Marino name = xstrdup (argv[VEC_length (const_char_p, argbuf) - 1]);
8239e4b17023SJohn Marino ret = NULL;
8240e4b17023SJohn Marino }
8241e4b17023SJohn Marino else
8242e4b17023SJohn Marino {
8243e4b17023SJohn Marino const char *ext = NULL;
8244e4b17023SJohn Marino
8245e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0)
8246e4b17023SJohn Marino {
8247e4b17023SJohn Marino do_spec_2 ("%{o*:%*}%{!o:%{!S:%b%O}%{S:%b.s}}");
8248e4b17023SJohn Marino ext = ".gkd";
8249e4b17023SJohn Marino }
8250e4b17023SJohn Marino else if (!compare_debug)
8251e4b17023SJohn Marino return NULL;
8252e4b17023SJohn Marino else
8253e4b17023SJohn Marino do_spec_2 ("%g.gkd");
8254e4b17023SJohn Marino
8255e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
8256e4b17023SJohn Marino
8257e4b17023SJohn Marino gcc_assert (VEC_length (const_char_p, argbuf) > 0);
8258e4b17023SJohn Marino
8259e4b17023SJohn Marino name = concat (VEC_last (const_char_p, argbuf), ext, NULL);
8260e4b17023SJohn Marino
8261e4b17023SJohn Marino ret = concat ("-fdump-final-insns=", name, NULL);
8262e4b17023SJohn Marino }
8263e4b17023SJohn Marino
8264e4b17023SJohn Marino which = compare_debug < 0;
8265e4b17023SJohn Marino debug_check_temp_file[which] = name;
8266e4b17023SJohn Marino
8267e4b17023SJohn Marino if (!which)
8268e4b17023SJohn Marino {
8269e4b17023SJohn Marino unsigned HOST_WIDE_INT value = get_random_number ();
8270e4b17023SJohn Marino
8271e4b17023SJohn Marino sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
8272e4b17023SJohn Marino }
8273e4b17023SJohn Marino
8274e4b17023SJohn Marino if (*random_seed)
8275e4b17023SJohn Marino ret = concat ("%{!frandom-seed=*:-frandom-seed=", random_seed, "} ",
8276e4b17023SJohn Marino ret, NULL);
8277e4b17023SJohn Marino
8278e4b17023SJohn Marino if (which)
8279e4b17023SJohn Marino *random_seed = 0;
8280e4b17023SJohn Marino
8281e4b17023SJohn Marino return ret;
8282e4b17023SJohn Marino }
8283e4b17023SJohn Marino
8284e4b17023SJohn Marino static const char *debug_auxbase_opt;
8285e4b17023SJohn Marino
8286e4b17023SJohn Marino /* %:compare-debug-self-opt spec function. Expands to the options
8287e4b17023SJohn Marino that are to be passed in the second compilation of
8288e4b17023SJohn Marino compare-debug. */
8289e4b17023SJohn Marino
8290e4b17023SJohn Marino static const char *
compare_debug_self_opt_spec_function(int arg,const char ** argv ATTRIBUTE_UNUSED)8291e4b17023SJohn Marino compare_debug_self_opt_spec_function (int arg,
8292e4b17023SJohn Marino const char **argv ATTRIBUTE_UNUSED)
8293e4b17023SJohn Marino {
8294e4b17023SJohn Marino if (arg != 0)
8295e4b17023SJohn Marino fatal_error ("too many arguments to %%:compare-debug-self-opt");
8296e4b17023SJohn Marino
8297e4b17023SJohn Marino if (compare_debug >= 0)
8298e4b17023SJohn Marino return NULL;
8299e4b17023SJohn Marino
8300e4b17023SJohn Marino do_spec_2 ("%{c|S:%{o*:%*}}");
8301e4b17023SJohn Marino do_spec_1 (" ", 0, NULL);
8302e4b17023SJohn Marino
8303e4b17023SJohn Marino if (VEC_length (const_char_p, argbuf) > 0)
8304e4b17023SJohn Marino debug_auxbase_opt = concat ("-auxbase-strip ",
8305e4b17023SJohn Marino VEC_last (const_char_p, argbuf),
8306e4b17023SJohn Marino NULL);
8307e4b17023SJohn Marino else
8308e4b17023SJohn Marino debug_auxbase_opt = NULL;
8309e4b17023SJohn Marino
8310e4b17023SJohn Marino return concat ("\
8311e4b17023SJohn Marino %<o %<MD %<MMD %<MF* %<MG %<MP %<MQ* %<MT* \
8312e4b17023SJohn Marino %<fdump-final-insns=* -w -S -o %j \
8313e4b17023SJohn Marino %{!fcompare-debug-second:-fcompare-debug-second} \
8314e4b17023SJohn Marino ", compare_debug_opt, NULL);
8315e4b17023SJohn Marino }
8316e4b17023SJohn Marino
8317e4b17023SJohn Marino /* %:compare-debug-auxbase-opt spec function. Expands to the auxbase
8318e4b17023SJohn Marino options that are to be passed in the second compilation of
8319e4b17023SJohn Marino compare-debug. It expects, as an argument, the basename of the
8320e4b17023SJohn Marino current input file name, with the .gk suffix appended to it. */
8321e4b17023SJohn Marino
8322e4b17023SJohn Marino static const char *
compare_debug_auxbase_opt_spec_function(int arg,const char ** argv)8323e4b17023SJohn Marino compare_debug_auxbase_opt_spec_function (int arg,
8324e4b17023SJohn Marino const char **argv)
8325e4b17023SJohn Marino {
8326e4b17023SJohn Marino char *name;
8327e4b17023SJohn Marino int len;
8328e4b17023SJohn Marino
8329e4b17023SJohn Marino if (arg == 0)
8330e4b17023SJohn Marino fatal_error ("too few arguments to %%:compare-debug-auxbase-opt");
8331e4b17023SJohn Marino
8332e4b17023SJohn Marino if (arg != 1)
8333e4b17023SJohn Marino fatal_error ("too many arguments to %%:compare-debug-auxbase-opt");
8334e4b17023SJohn Marino
8335e4b17023SJohn Marino if (compare_debug >= 0)
8336e4b17023SJohn Marino return NULL;
8337e4b17023SJohn Marino
8338e4b17023SJohn Marino len = strlen (argv[0]);
8339e4b17023SJohn Marino if (len < 3 || strcmp (argv[0] + len - 3, ".gk") != 0)
8340e4b17023SJohn Marino fatal_error ("argument to %%:compare-debug-auxbase-opt "
8341e4b17023SJohn Marino "does not end in .gk");
8342e4b17023SJohn Marino
8343e4b17023SJohn Marino if (debug_auxbase_opt)
8344e4b17023SJohn Marino return debug_auxbase_opt;
8345e4b17023SJohn Marino
8346e4b17023SJohn Marino #define OPT "-auxbase "
8347e4b17023SJohn Marino
8348e4b17023SJohn Marino len -= 3;
8349e4b17023SJohn Marino name = (char*) xmalloc (sizeof (OPT) + len);
8350e4b17023SJohn Marino memcpy (name, OPT, sizeof (OPT) - 1);
8351e4b17023SJohn Marino memcpy (name + sizeof (OPT) - 1, argv[0], len);
8352e4b17023SJohn Marino name[sizeof (OPT) - 1 + len] = '\0';
8353e4b17023SJohn Marino
8354e4b17023SJohn Marino #undef OPT
8355e4b17023SJohn Marino
8356e4b17023SJohn Marino return name;
8357e4b17023SJohn Marino }
8358e4b17023SJohn Marino
8359e4b17023SJohn Marino /* %:pass-through-libs spec function. Finds all -l options and input
8360e4b17023SJohn Marino file names in the lib spec passed to it, and makes a list of them
8361e4b17023SJohn Marino prepended with the plugin option to cause them to be passed through
8362e4b17023SJohn Marino to the final link after all the new object files have been added. */
8363e4b17023SJohn Marino
8364e4b17023SJohn Marino const char *
pass_through_libs_spec_func(int argc,const char ** argv)8365e4b17023SJohn Marino pass_through_libs_spec_func (int argc, const char **argv)
8366e4b17023SJohn Marino {
8367e4b17023SJohn Marino char *prepended = xstrdup (" ");
8368e4b17023SJohn Marino int n;
8369e4b17023SJohn Marino /* Shlemiel the painter's algorithm. Innately horrible, but at least
8370e4b17023SJohn Marino we know that there will never be more than a handful of strings to
8371e4b17023SJohn Marino concat, and it's only once per run, so it's not worth optimising. */
8372e4b17023SJohn Marino for (n = 0; n < argc; n++)
8373e4b17023SJohn Marino {
8374e4b17023SJohn Marino char *old = prepended;
8375e4b17023SJohn Marino /* Anything that isn't an option is a full path to an output
8376e4b17023SJohn Marino file; pass it through if it ends in '.a'. Among options,
8377e4b17023SJohn Marino pass only -l. */
8378e4b17023SJohn Marino if (argv[n][0] == '-' && argv[n][1] == 'l')
8379e4b17023SJohn Marino {
8380e4b17023SJohn Marino const char *lopt = argv[n] + 2;
8381e4b17023SJohn Marino /* Handle both joined and non-joined -l options. If for any
8382e4b17023SJohn Marino reason there's a trailing -l with no joined or following
8383e4b17023SJohn Marino arg just discard it. */
8384e4b17023SJohn Marino if (!*lopt && ++n >= argc)
8385e4b17023SJohn Marino break;
8386e4b17023SJohn Marino else if (!*lopt)
8387e4b17023SJohn Marino lopt = argv[n];
8388e4b17023SJohn Marino prepended = concat (prepended, "-plugin-opt=-pass-through=-l",
8389e4b17023SJohn Marino lopt, " ", NULL);
8390e4b17023SJohn Marino }
8391e4b17023SJohn Marino else if (!strcmp (".a", argv[n] + strlen (argv[n]) - 2))
8392e4b17023SJohn Marino {
8393e4b17023SJohn Marino prepended = concat (prepended, "-plugin-opt=-pass-through=",
8394e4b17023SJohn Marino argv[n], " ", NULL);
8395e4b17023SJohn Marino }
8396e4b17023SJohn Marino if (prepended != old)
8397e4b17023SJohn Marino free (old);
8398e4b17023SJohn Marino }
8399e4b17023SJohn Marino return prepended;
8400e4b17023SJohn Marino }
84015ce9237cSJohn Marino
84025ce9237cSJohn Marino /* Insert backslash before spaces in ORIG (usually a file path), to
84035ce9237cSJohn Marino avoid being broken by spec parser.
84045ce9237cSJohn Marino
84055ce9237cSJohn Marino This function is needed as do_spec_1 treats white space (' ' and '\t')
84065ce9237cSJohn Marino as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
84075ce9237cSJohn Marino the file name should be treated as a single argument rather than being
84085ce9237cSJohn Marino broken into multiple. Solution is to insert '\\' before the space in a
84095ce9237cSJohn Marino file name.
84105ce9237cSJohn Marino
84115ce9237cSJohn Marino This function converts and only converts all occurrence of ' '
84125ce9237cSJohn Marino to '\\' + ' ' and '\t' to '\\' + '\t'. For example:
84135ce9237cSJohn Marino "a b" -> "a\\ b"
84145ce9237cSJohn Marino "a b" -> "a\\ \\ b"
84155ce9237cSJohn Marino "a\tb" -> "a\\\tb"
84165ce9237cSJohn Marino "a\\ b" -> "a\\\\ b"
84175ce9237cSJohn Marino
84185ce9237cSJohn Marino orig: input null-terminating string that was allocated by xalloc. The
84195ce9237cSJohn Marino memory it points to might be freed in this function. Behavior undefined
84205ce9237cSJohn Marino if ORIG wasn't xalloced or was freed already at entry.
84215ce9237cSJohn Marino
84225ce9237cSJohn Marino Return: ORIG if no conversion needed. Otherwise a newly allocated string
84235ce9237cSJohn Marino that was converted from ORIG. */
84245ce9237cSJohn Marino
84255ce9237cSJohn Marino static char *
convert_white_space(char * orig)84265ce9237cSJohn Marino convert_white_space (char *orig)
84275ce9237cSJohn Marino {
84285ce9237cSJohn Marino int len, number_of_space = 0;
84295ce9237cSJohn Marino
84305ce9237cSJohn Marino for (len = 0; orig[len]; len++)
84315ce9237cSJohn Marino if (orig[len] == ' ' || orig[len] == '\t') number_of_space++;
84325ce9237cSJohn Marino
84335ce9237cSJohn Marino if (number_of_space)
84345ce9237cSJohn Marino {
84355ce9237cSJohn Marino char *new_spec = (char *) xmalloc (len + number_of_space + 1);
84365ce9237cSJohn Marino int j, k;
84375ce9237cSJohn Marino for (j = 0, k = 0; j <= len; j++, k++)
84385ce9237cSJohn Marino {
84395ce9237cSJohn Marino if (orig[j] == ' ' || orig[j] == '\t')
84405ce9237cSJohn Marino new_spec[k++] = '\\';
84415ce9237cSJohn Marino new_spec[k] = orig[j];
84425ce9237cSJohn Marino }
84435ce9237cSJohn Marino free (orig);
84445ce9237cSJohn Marino return new_spec;
84455ce9237cSJohn Marino }
84465ce9237cSJohn Marino else
84475ce9237cSJohn Marino return orig;
84485ce9237cSJohn Marino }
8449