LCOV - code coverage report
Current view: top level - gcc - gcc.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 74.3 % 4428 3289
Test Date: 2026-06-20 15:32:29 Functions: 85.8 % 162 139
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Compiler driver program that can handle many languages.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : /* This program is the user interface to the C compiler and possibly to
      21              : other compilers.  It is used because compilation is a complicated procedure
      22              : which involves running several programs and passing temporary files between
      23              : them, forwarding the users switches to those programs selectively,
      24              : and deleting the temporary files at the end.
      25              : 
      26              : CC recognizes how to compile each input file by suffixes in the file names.
      27              : Once it knows which kind of compilation to perform, the procedure for
      28              : compilation is specified by a string called a "spec".  */
      29              : 
      30              : #define INCLUDE_STRING
      31              : #define INCLUDE_VECTOR
      32              : #include "config.h"
      33              : #include "system.h"
      34              : #ifdef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
      35              : #include <sys/personality.h>
      36              : #endif
      37              : #include "coretypes.h"
      38              : #include "multilib.h" /* before tm.h */
      39              : #include "tm.h"
      40              : #include "xregex.h"
      41              : #include "obstack.h"
      42              : #include "intl.h"
      43              : #include "prefix.h"
      44              : #include "opt-suggestions.h"
      45              : #include "gcc.h"
      46              : #include "diagnostic.h"
      47              : #include "diagnostics/sink.h"
      48              : #include "pretty-print-urlifier.h"
      49              : #include "flags.h"
      50              : #include "opts.h"
      51              : #include "filenames.h"
      52              : #include "spellcheck.h"
      53              : #include "opts-jobserver.h"
      54              : #include "common/common-target.h"
      55              : #include "gcc-urlifier.h"
      56              : #include "opts-diagnostic.h"
      57              : #include "auto-profile.h" /* for AUTO_PROFILE_VERSION.  */
      58              : 
      59              : #ifndef MATH_LIBRARY
      60              : #define MATH_LIBRARY "m"
      61              : #endif
      62              : 
      63              : 
      64              : /* Manage the manipulation of env vars.
      65              : 
      66              :    We poison "getenv" and "putenv", so that all environment-handling is
      67              :    done through this class.  Note that poisoning happens in the
      68              :    preprocessor at the identifier level, and doesn't distinguish between
      69              :      env.getenv ();
      70              :    and
      71              :      getenv ();
      72              :    Hence we need to use "get" for the accessor method, not "getenv".  */
      73              : 
      74              : struct env_manager
      75              : {
      76              :  public:
      77              :   void init (bool can_restore, bool debug);
      78              :   const char *get (const char *name);
      79              :   void xput (const char *string);
      80              :   void restore ();
      81              : 
      82              :  private:
      83              :   bool m_can_restore;
      84              :   bool m_debug;
      85              :   struct kv
      86              :   {
      87              :     char *m_key;
      88              :     char *m_value;
      89              :   };
      90              :   vec<kv> m_keys;
      91              : 
      92              : };
      93              : 
      94              : /* The singleton instance of class env_manager.  */
      95              : 
      96              : static env_manager env;
      97              : 
      98              : /* Initializer for class env_manager.
      99              : 
     100              :    We can't do this as a constructor since we have a statically
     101              :    allocated instance ("env" above).  */
     102              : 
     103              : void
     104       312002 : env_manager::init (bool can_restore, bool debug)
     105              : {
     106       312002 :   m_can_restore = can_restore;
     107       312002 :   m_debug = debug;
     108       312002 : }
     109              : 
     110              : /* Get the value of NAME within the environment.  Essentially
     111              :    a wrapper for ::getenv, but adding logging, and the possibility
     112              :    of caching results.  */
     113              : 
     114              : const char *
     115      1559077 : env_manager::get (const char *name)
     116              : {
     117      1559077 :   const char *result = ::getenv (name);
     118      1559077 :   if (m_debug)
     119            0 :     fprintf (stderr, "env_manager::getenv (%s) -> %s\n", name, result);
     120      1559077 :   return result;
     121              : }
     122              : 
     123              : /* Put the given KEY=VALUE entry STRING into the environment.
     124              :    If the env_manager was initialized with CAN_RESTORE set, then
     125              :    also record the old value of KEY within the environment, so that it
     126              :    can be later restored.  */
     127              : 
     128              : void
     129      1832069 : env_manager::xput (const char *string)
     130              : {
     131      1832069 :   if (m_debug)
     132            0 :     fprintf (stderr, "env_manager::xput (%s)\n", string);
     133      1832069 :   if (verbose_flag)
     134         6597 :     fnotice (stderr, "%s\n", string);
     135              : 
     136      1832069 :   if (m_can_restore)
     137              :     {
     138         6859 :       char *equals = strchr (const_cast <char *> (string), '=');
     139         6859 :       gcc_assert (equals);
     140              : 
     141         6859 :       struct kv kv;
     142         6859 :       kv.m_key = xstrndup (string, equals - string);
     143         6859 :       const char *cur_value = ::getenv (kv.m_key);
     144         6859 :       if (m_debug)
     145            0 :         fprintf (stderr, "saving old value: %s\n",cur_value);
     146         6859 :       kv.m_value = cur_value ? xstrdup (cur_value) : NULL;
     147         6859 :       m_keys.safe_push (kv);
     148              :     }
     149              : 
     150      1832069 :   ::putenv (const_cast<char *> (string));
     151      1832069 : }
     152              : 
     153              : /* Undo any xputenv changes made since last restore.
     154              :    Can only be called if the env_manager was initialized with
     155              :    CAN_RESTORE enabled.  */
     156              : 
     157              : void
     158         1144 : env_manager::restore ()
     159              : {
     160         1144 :   unsigned int i;
     161         1144 :   struct kv *item;
     162              : 
     163         1144 :   gcc_assert (m_can_restore);
     164              : 
     165         9147 :   FOR_EACH_VEC_ELT_REVERSE (m_keys, i, item)
     166              :     {
     167         6859 :       if (m_debug)
     168            0 :         printf ("restoring saved key: %s value: %s\n", item->m_key, item->m_value);
     169         6859 :       if (item->m_value)
     170         3427 :         ::setenv (item->m_key, item->m_value, 1);
     171              :       else
     172         3432 :         ::unsetenv (item->m_key);
     173         6859 :       free (item->m_key);
     174         6859 :       free (item->m_value);
     175              :     }
     176              : 
     177         1144 :   m_keys.truncate (0);
     178         1144 : }
     179              : 
     180              : /* Forbid other uses of getenv and putenv.  */
     181              : #if (GCC_VERSION >= 3000)
     182              : #pragma GCC poison getenv putenv
     183              : #endif
     184              : 
     185              : 
     186              : 
     187              : /* By default there is no special suffix for target executables.  */
     188              : #ifdef TARGET_EXECUTABLE_SUFFIX
     189              : #define HAVE_TARGET_EXECUTABLE_SUFFIX
     190              : #else
     191              : #define TARGET_EXECUTABLE_SUFFIX ""
     192              : #endif
     193              : 
     194              : /* By default there is no special suffix for host executables.  */
     195              : #ifdef HOST_EXECUTABLE_SUFFIX
     196              : #define HAVE_HOST_EXECUTABLE_SUFFIX
     197              : #else
     198              : #define HOST_EXECUTABLE_SUFFIX ""
     199              : #endif
     200              : 
     201              : /* By default, the suffix for target object files is ".o".  */
     202              : #ifdef TARGET_OBJECT_SUFFIX
     203              : #define HAVE_TARGET_OBJECT_SUFFIX
     204              : #else
     205              : #define TARGET_OBJECT_SUFFIX ".o"
     206              : #endif
     207              : 
     208              : static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
     209              : 
     210              : /* Most every one is fine with LIBRARY_PATH.  For some, it conflicts.  */
     211              : #ifndef LIBRARY_PATH_ENV
     212              : #define LIBRARY_PATH_ENV "LIBRARY_PATH"
     213              : #endif
     214              : 
     215              : /* If a stage of compilation returns an exit status >= 1,
     216              :    compilation of that file ceases.  */
     217              : 
     218              : #define MIN_FATAL_STATUS 1
     219              : 
     220              : /* Flag set by cppspec.cc to 1.  */
     221              : int is_cpp_driver;
     222              : 
     223              : /* Flag set to nonzero if an @file argument has been supplied to gcc.  */
     224              : static bool at_file_supplied;
     225              : 
     226              : /* Definition of string containing the arguments given to configure.  */
     227              : #include "configargs.h"
     228              : 
     229              : /* Flag saying to print the command line options understood by gcc and its
     230              :    sub-processes.  */
     231              : 
     232              : static int print_help_list;
     233              : 
     234              : /* Flag saying to print the version of gcc and its sub-processes.  */
     235              : 
     236              : static int print_version;
     237              : 
     238              : /* Flag that stores string prefix for which we provide bash completion.  */
     239              : 
     240              : static const char *completion = NULL;
     241              : 
     242              : /* Flag indicating whether we should ONLY print the command and
     243              :    arguments (like verbose_flag) without executing the command.
     244              :    Displayed arguments are quoted so that the generated command
     245              :    line is suitable for execution.  This is intended for use in
     246              :    shell scripts to capture the driver-generated command line.  */
     247              : static int verbose_only_flag;
     248              : 
     249              : /* Flag indicating how to print command line options of sub-processes.  */
     250              : 
     251              : static int print_subprocess_help;
     252              : 
     253              : /* Linker suffix passed to -fuse-ld=... */
     254              : static const char *use_ld;
     255              : 
     256              : /* Whether we should report subprocess execution times to a file.  */
     257              : 
     258              : FILE *report_times_to_file = NULL;
     259              : 
     260              : /* Nonzero means place this string before uses of /, so that include
     261              :    and library files can be found in an alternate location.  */
     262              : 
     263              : #ifdef TARGET_SYSTEM_ROOT
     264              : #define DEFAULT_TARGET_SYSTEM_ROOT (TARGET_SYSTEM_ROOT)
     265              : #else
     266              : #define DEFAULT_TARGET_SYSTEM_ROOT (0)
     267              : #endif
     268              : static const char *target_system_root = DEFAULT_TARGET_SYSTEM_ROOT;
     269              : 
     270              : /* Nonzero means pass the updated target_system_root to the compiler.  */
     271              : 
     272              : static int target_system_root_changed;
     273              : 
     274              : /* Nonzero means append this string to target_system_root.  */
     275              : 
     276              : static const char *target_sysroot_suffix = 0;
     277              : 
     278              : /* Nonzero means append this string to target_system_root for headers.  */
     279              : 
     280              : static const char *target_sysroot_hdrs_suffix = 0;
     281              : 
     282              : /* Nonzero means write "temp" files in source directory
     283              :    and use the source file's name in them, and don't delete them.  */
     284              : 
     285              : static enum save_temps {
     286              :   SAVE_TEMPS_NONE,              /* no -save-temps */
     287              :   SAVE_TEMPS_CWD,               /* -save-temps in current directory */
     288              :   SAVE_TEMPS_DUMP,              /* -save-temps in dumpdir */
     289              :   SAVE_TEMPS_OBJ                /* -save-temps in object directory */
     290              : } save_temps_flag;
     291              : 
     292              : /* Set this iff the dumppfx implied by a -save-temps=* option is to
     293              :    override a -dumpdir option, if any.  */
     294              : static bool save_temps_overrides_dumpdir = false;
     295              : 
     296              : /* -dumpdir, -dumpbase and -dumpbase-ext flags passed in, possibly
     297              :    rearranged as they are to be passed down, e.g., dumpbase and
     298              :    dumpbase_ext may be cleared if integrated with dumpdir or
     299              :    dropped.  */
     300              : static char *dumpdir, *dumpbase, *dumpbase_ext;
     301              : 
     302              : /* Usually the length of the string in dumpdir.  However, during
     303              :    linking, it may be shortened to omit a driver-added trailing dash,
     304              :    by then replaced with a trailing period, that is still to be passed
     305              :    to sub-processes in -dumpdir, but not to be generally used in spec
     306              :    filename expansions.  See maybe_run_linker.  */
     307              : static size_t dumpdir_length = 0;
     308              : 
     309              : /* Set if the last character in dumpdir is (or was) a dash that the
     310              :    driver added to dumpdir after dumpbase or linker output name.  */
     311              : static bool dumpdir_trailing_dash_added = false;
     312              : 
     313              : /* True if -r, -shared, -pie, -no-pie, -z lazy, or -z norelro were
     314              :    specified on the command line, and therefore -fhardened should not
     315              :    add -z now/relro.  */
     316              : static bool avoid_linker_hardening_p;
     317              : 
     318              : /* True if -static was specified on the command line.  */
     319              : static bool static_p;
     320              : 
     321              : /* Basename of dump and aux outputs, computed from dumpbase (given or
     322              :    derived from output name), to override input_basename in non-%w %b
     323              :    et al.  */
     324              : static char *outbase;
     325              : static size_t outbase_length = 0;
     326              : 
     327              : /* The compiler version.  */
     328              : 
     329              : static const char *compiler_version;
     330              : 
     331              : /* The target version.  */
     332              : 
     333              : static const char *const spec_version = DEFAULT_TARGET_VERSION;
     334              : 
     335              : /* The target machine.  */
     336              : 
     337              : static const char *spec_machine = DEFAULT_TARGET_MACHINE;
     338              : static const char *spec_host_machine = DEFAULT_REAL_TARGET_MACHINE;
     339              : 
     340              : /* List of offload targets.  Separated by colon.  Empty string for
     341              :    -foffload=disable.  */
     342              : 
     343              : static char *offload_targets = NULL;
     344              : 
     345              : #if OFFLOAD_DEFAULTED
     346              : /* Set to true if -foffload has not been used and offload_targets
     347              :    is set to the configured in default.  */
     348              : static bool offload_targets_default;
     349              : #endif
     350              : 
     351              : /* Nonzero if cross-compiling.
     352              :    When -b is used, the value comes from the `specs' file.  */
     353              : 
     354              : #ifdef CROSS_DIRECTORY_STRUCTURE
     355              : static const char *cross_compile = "1";
     356              : #else
     357              : static const char *cross_compile = "0";
     358              : #endif
     359              : 
     360              : /* Greatest exit code of sub-processes that has been encountered up to
     361              :    now.  */
     362              : static int greatest_status = 1;
     363              : 
     364              : /* This is the obstack which we use to allocate many strings.  */
     365              : 
     366              : static struct obstack obstack;
     367              : 
     368              : /* This is the obstack to build an environment variable to pass to
     369              :    collect2 that describes all of the relevant switches of what to
     370              :    pass the compiler in building the list of pointers to constructors
     371              :    and destructors.  */
     372              : 
     373              : static struct obstack collect_obstack;
     374              : 
     375              : /* Forward declaration for prototypes.  */
     376              : struct path_prefix;
     377              : struct prefix_list;
     378              : 
     379              : static void init_spec (void);
     380              : static void store_arg (const char *, int, int);
     381              : static void insert_wrapper (const char *);
     382              : static char *load_specs (const char *);
     383              : static void read_specs (const char *, bool, bool);
     384              : static void set_spec (const char *, const char *, bool);
     385              : static struct compiler *lookup_compiler (const char *, size_t, const char *);
     386              : static char *build_search_list (const struct path_prefix *, const char *,
     387              :                                 bool, bool);
     388              : static void xputenv (const char *);
     389              : static void putenv_from_prefixes (const struct path_prefix *, const char *,
     390              :                                   bool);
     391              : static int access_check (const char *, int);
     392              : static char *find_a_file (const struct path_prefix *, const char *, bool);
     393              : static char *find_a_program (const char *);
     394              : static void add_prefix (struct path_prefix *, const char *, const char *,
     395              :                         int, int, int);
     396              : static void add_sysrooted_prefix (struct path_prefix *, const char *,
     397              :                                   const char *, int, int, int);
     398              : static char *skip_whitespace (char *);
     399              : static void delete_if_ordinary (const char *);
     400              : static void delete_temp_files (void);
     401              : static void delete_failure_queue (void);
     402              : static void clear_failure_queue (void);
     403              : static int check_live_switch (int, int);
     404              : static const char *handle_braces (const char *);
     405              : static inline bool input_suffix_matches (const char *, const char *);
     406              : static inline bool switch_matches (const char *, const char *, int);
     407              : static inline void mark_matching_switches (const char *, const char *, int);
     408              : static inline void process_marked_switches (void);
     409              : static const char *process_brace_body (const char *, const char *, const char *, int, int);
     410              : static const struct spec_function *lookup_spec_function (const char *);
     411              : static const char *eval_spec_function (const char *, const char *, const char *);
     412              : static const char *handle_spec_function (const char *, bool *, const char *);
     413              : static char *save_string (const char *, int);
     414              : static void set_collect_gcc_options (void);
     415              : static int do_spec_1 (const char *, int, const char *);
     416              : static int do_spec_2 (const char *, const char *);
     417              : static void do_option_spec (const char *, const char *);
     418              : static void do_self_spec (const char *);
     419              : static const char *find_file (const char *);
     420              : static int is_directory (const char *);
     421              : static const char *validate_switches (const char *, bool, bool);
     422              : static void validate_all_switches (void);
     423              : static inline void validate_switches_from_spec (const char *, bool);
     424              : static void give_switch (int, int);
     425              : static int default_arg (const char *, int);
     426              : static void set_multilib_dir (void);
     427              : static void print_multilib_info (void);
     428              : static void display_help (void);
     429              : static void add_preprocessor_option (const char *, int);
     430              : static void add_assembler_option (const char *, int);
     431              : static void add_linker_option (const char *, int);
     432              : static void process_command (unsigned int, struct cl_decoded_option *);
     433              : static int execute (void);
     434              : static void alloc_args (void);
     435              : static void clear_args (void);
     436              : static void fatal_signal (int);
     437              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
     438              : static void init_gcc_specs (struct obstack *, const char *, const char *,
     439              :                             const char *);
     440              : #endif
     441              : #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
     442              : static const char *convert_filename (const char *, int, int);
     443              : #endif
     444              : 
     445              : static void try_generate_repro (const char **argv);
     446              : static const char *getenv_spec_function (int, const char **);
     447              : static const char *if_exists_spec_function (int, const char **);
     448              : static const char *if_exists_else_spec_function (int, const char **);
     449              : static const char *if_exists_then_else_spec_function (int, const char **);
     450              : static const char *sanitize_spec_function (int, const char **);
     451              : static const char *replace_outfile_spec_function (int, const char **);
     452              : static const char *remove_outfile_spec_function (int, const char **);
     453              : static const char *version_compare_spec_function (int, const char **);
     454              : static const char *include_spec_function (int, const char **);
     455              : static const char *find_file_spec_function (int, const char **);
     456              : static const char *find_plugindir_spec_function (int, const char **);
     457              : static const char *print_asm_header_spec_function (int, const char **);
     458              : static const char *compare_debug_dump_opt_spec_function (int, const char **);
     459              : static const char *compare_debug_self_opt_spec_function (int, const char **);
     460              : static const char *pass_through_libs_spec_func (int, const char **);
     461              : static const char *dumps_spec_func (int, const char **);
     462              : static const char *greater_than_spec_func (int, const char **);
     463              : static const char *debug_level_greater_than_spec_func (int, const char **);
     464              : static const char *dwarf_version_greater_than_spec_func (int, const char **);
     465              : static const char *find_fortran_preinclude_file (int, const char **);
     466              : static const char *join_spec_func (int, const char **);
     467              : static char *convert_white_space (char *);
     468              : static char *quote_spec (char *);
     469              : static char *quote_spec_arg (char *);
     470              : static bool not_actual_file_p (const char *);
     471              : 
     472              : 
     473              : /* The Specs Language
     474              : 
     475              : Specs are strings containing lines, each of which (if not blank)
     476              : is made up of a program name, and arguments separated by spaces.
     477              : The program name must be exact and start from root, since no path
     478              : is searched and it is unreliable to depend on the current working directory.
     479              : Redirection of input or output is not supported; the subprograms must
     480              : accept filenames saying what files to read and write.
     481              : 
     482              : In addition, the specs can contain %-sequences to substitute variable text
     483              : or for conditional text.  Here is a table of all defined %-sequences.
     484              : Note that spaces are not generated automatically around the results of
     485              : expanding these sequences; therefore, you can concatenate them together
     486              : or with constant text in a single argument.
     487              : 
     488              :  %%     substitute one % into the program name or argument.
     489              :  %"     substitute an empty argument.
     490              :  %i     substitute the name of the input file being processed.
     491              :  %b     substitute the basename for outputs related with the input file
     492              :         being processed.  This is often a substring of the input file name,
     493              :         up to (and not including) the last period but, unless %w is active,
     494              :         it is affected by the directory selected by -save-temps=*, by
     495              :         -dumpdir, and, in case of multiple compilations, even by -dumpbase
     496              :         and -dumpbase-ext and, in case of linking, by the linker output
     497              :         name.  When %w is active, it derives the main output name only from
     498              :         the input file base name; when it is not, it names aux/dump output
     499              :         file.
     500              :  %B     same as %b, but include the input file suffix (text after the last
     501              :         period).
     502              :  %gSUFFIX
     503              :         substitute a file name that has suffix SUFFIX and is chosen
     504              :         once per compilation, and mark the argument a la %d.  To reduce
     505              :         exposure to denial-of-service attacks, the file name is now
     506              :         chosen in a way that is hard to predict even when previously
     507              :         chosen file names are known.  For example, `%g.s ... %g.o ... %g.s'
     508              :         might turn into `ccUVUUAU.s ccXYAXZ12.o ccUVUUAU.s'.  SUFFIX matches
     509              :         the regexp "[.0-9A-Za-z]*%O"; "%O" is treated exactly as if it
     510              :         had been pre-processed.  Previously, %g was simply substituted
     511              :         with a file name chosen once per compilation, without regard
     512              :         to any appended suffix (which was therefore treated just like
     513              :         ordinary text), making such attacks more likely to succeed.
     514              :  %|SUFFIX
     515              :         like %g, but if -pipe is in effect, expands simply to "-".
     516              :  %mSUFFIX
     517              :         like %g, but if -pipe is in effect, expands to nothing.  (We have both
     518              :         %| and %m to accommodate differences between system assemblers; see
     519              :         the AS_NEEDS_DASH_FOR_PIPED_INPUT target macro.)
     520              :  %uSUFFIX
     521              :         like %g, but generates a new temporary file name even if %uSUFFIX
     522              :         was already seen.
     523              :  %USUFFIX
     524              :         substitutes the last file name generated with %uSUFFIX, generating a
     525              :         new one if there is no such last file name.  In the absence of any
     526              :         %uSUFFIX, this is just like %gSUFFIX, except they don't share
     527              :         the same suffix "space", so `%g.s ... %U.s ... %g.s ... %U.s'
     528              :         would involve the generation of two distinct file names, one
     529              :         for each `%g.s' and another for each `%U.s'.  Previously, %U was
     530              :         simply substituted with a file name chosen for the previous %u,
     531              :         without regard to any appended suffix.
     532              :  %jSUFFIX
     533              :         substitutes the name of the HOST_BIT_BUCKET, if any, and if it is
     534              :         writable, and if save-temps is off; otherwise, substitute the name
     535              :         of a temporary file, just like %u.  This temporary file is not
     536              :         meant for communication between processes, but rather as a junk
     537              :         disposal mechanism.
     538              :  %.SUFFIX
     539              :         substitutes .SUFFIX for the suffixes of a matched switch's args when
     540              :         it is subsequently output with %*. SUFFIX is terminated by the next
     541              :         space or %.
     542              :  %d     marks the argument containing or following the %d as a
     543              :         temporary file name, so that file will be deleted if GCC exits
     544              :         successfully.  Unlike %g, this contributes no text to the argument.
     545              :  %w     marks the argument containing or following the %w as the
     546              :         "output file" of this compilation.  This puts the argument
     547              :         into the sequence of arguments that %o will substitute later.
     548              :  %V     indicates that this compilation produces no "output file".
     549              :  %W{...}
     550              :         like %{...} but marks the last argument supplied within as a file
     551              :         to be deleted on failure.
     552              :  %@{...}
     553              :         like %{...} but puts the result into a FILE and substitutes @FILE
     554              :         if an @file argument has been supplied.
     555              :  %o     substitutes the names of all the output files, with spaces
     556              :         automatically placed around them.  You should write spaces
     557              :         around the %o as well or the results are undefined.
     558              :         %o is for use in the specs for running the linker.
     559              :         Input files whose names have no recognized suffix are not compiled
     560              :         at all, but they are included among the output files, so they will
     561              :         be linked.
     562              :  %O     substitutes the suffix for object files.  Note that this is
     563              :         handled specially when it immediately follows %g, %u, or %U
     564              :         (with or without a suffix argument) because of the need for
     565              :         those to form complete file names.  The handling is such that
     566              :         %O is treated exactly as if it had already been substituted,
     567              :         except that %g, %u, and %U do not currently support additional
     568              :         SUFFIX characters following %O as they would following, for
     569              :         example, `.o'.
     570              :  %I     Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
     571              :         (made from TARGET_SYSTEM_ROOT), -isystem (made from COMPILER_PATH
     572              :         and -B options) and -imultilib as necessary.
     573              :  %s     current argument is the name of a library or startup file of some sort.
     574              :         Search for that file in a standard list of directories
     575              :         and substitute the full name found.
     576              :  %T     current argument is the name of a linker script.
     577              :         Search for that file in the current list of directories to scan for
     578              :         libraries.  If the file is located, insert a --script option into the
     579              :         command line followed by the full path name found.  If the file is
     580              :         not found then generate an error message.
     581              :         Note: the current working directory is not searched.
     582              :  %eSTR  Print STR as an error message.  STR is terminated by a newline.
     583              :         Use this when inconsistent options are detected.
     584              :  %nSTR  Print STR as a notice.  STR is terminated by a newline.
     585              :  %x{OPTION}     Accumulate an option for %X.
     586              :  %X     Output the accumulated linker options specified by compilations.
     587              :  %Y     Output the accumulated assembler options specified by compilations.
     588              :  %Z     Output the accumulated preprocessor options specified by compilations.
     589              :  %a     process ASM_SPEC as a spec.
     590              :         This allows config.h to specify part of the spec for running as.
     591              :  %A     process ASM_FINAL_SPEC as a spec.  A capital A is actually
     592              :         used here.  This can be used to run a post-processor after the
     593              :         assembler has done its job.
     594              :  %D     Dump out a -L option for each directory in startfile_prefixes.
     595              :         If multilib_dir is set, extra entries are generated with it affixed.
     596              :  %l     process LINK_SPEC as a spec.
     597              :  %L     process LIB_SPEC as a spec.
     598              :  %M     Output multilib_os_dir.
     599              :  %P     Output a RUNPATH_OPTION for each directory in startfile_prefixes.
     600              :  %G     process LIBGCC_SPEC as a spec.
     601              :  %R     Output the concatenation of target_system_root and
     602              :         target_sysroot_suffix.
     603              :  %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
     604              :  %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
     605              :  %C     process CPP_SPEC as a spec.
     606              :  %1     process CC1_SPEC as a spec.
     607              :  %2     process CC1PLUS_SPEC as a spec.
     608              :  %*     substitute the variable part of a matched option.  (See below.)
     609              :         Note that each comma in the substituted string is replaced by
     610              :         a single space.  A space is appended after the last substitution
     611              :         unless there is more text in current sequence.
     612              :  %<S    remove all occurrences of -S from the command line.
     613              :         Note - this command is position dependent.  % commands in the
     614              :         spec string before this one will see -S, % commands in the
     615              :         spec string after this one will not.
     616              :  %>S Similar to "%<S", but keep it in the GCC command line.
     617              :  %<S*        remove all occurrences of all switches beginning with -S from the
     618              :         command line.
     619              :  %:function(args)
     620              :         Call the named function FUNCTION, passing it ARGS.  ARGS is
     621              :         first processed as a nested spec string, then split into an
     622              :         argument vector in the usual fashion.  The function returns
     623              :         a string which is processed as if it had appeared literally
     624              :         as part of the current spec.
     625              :  %{S}   substitutes the -S switch, if that switch was given to GCC.
     626              :         If that switch was not specified, this substitutes nothing.
     627              :         Here S is a metasyntactic variable.
     628              :  %{S*}  substitutes all the switches specified to GCC whose names start
     629              :         with -S.  This is used for -o, -I, etc; switches that take
     630              :         arguments.  GCC considers `-o foo' as being one switch whose
     631              :         name starts with `o'.  %{o*} would substitute this text,
     632              :         including the space; thus, two arguments would be generated.
     633              :  %{S*&T*} likewise, but preserve order of S and T options (the order
     634              :         of S and T in the spec is not significant).  Can be any number
     635              :         of ampersand-separated variables; for each the wild card is
     636              :         optional.  Useful for CPP as %{D*&U*&A*}.
     637              : 
     638              :  %{S:X}   substitutes X, if the -S switch was given to GCC.
     639              :  %{!S:X}  substitutes X, if the -S switch was NOT given to GCC.
     640              :  %{S*:X}  substitutes X if one or more switches whose names start
     641              :           with -S was given to GCC.  Normally X is substituted only
     642              :           once, no matter how many such switches appeared.  However,
     643              :           if %* appears somewhere in X, then X will be substituted
     644              :           once for each matching switch, with the %* replaced by the
     645              :           part of that switch that matched the '*'.  A space will be
     646              :           appended after the last substitution unless there is more
     647              :           text in current sequence.
     648              :  %{.S:X}  substitutes X, if processing a file with suffix S.
     649              :  %{!.S:X} substitutes X, if NOT processing a file with suffix S.
     650              :  %{,S:X}  substitutes X, if processing a file which will use spec S.
     651              :  %{!,S:X} substitutes X, if NOT processing a file which will use spec S.
     652              : 
     653              :  %{S|T:X} substitutes X if either -S or -T was given to GCC.  This may be
     654              :           combined with '!', '.', ',', and '*' as above binding stronger
     655              :           than the OR.
     656              :           If %* appears in X, all of the alternatives must be starred, and
     657              :           only the first matching alternative is substituted.
     658              :  %{%:function(args):X}
     659              :           Call function named FUNCTION with args ARGS.  If the function
     660              :           returns non-NULL, then X is substituted, if it returns
     661              :           NULL, it isn't substituted.
     662              :  %{S:X;   if S was given to GCC, substitutes X;
     663              :    T:Y;   else if T was given to GCC, substitutes Y;
     664              :     :D}   else substitutes D.  There can be as many clauses as you need.
     665              :           This may be combined with '.', '!', ',', '|', and '*' as above.
     666              : 
     667              :  %(Spec) processes a specification defined in a specs file as *Spec:
     668              : 
     669              : The switch matching text S in a %{S}, %{S:X}, or similar construct can use
     670              : a backslash to ignore the special meaning of the character following it,
     671              : thus allowing literal matching of a character that is otherwise specially
     672              : treated.  For example, %{std=iso9899\:1999:X} substitutes X if the
     673              : -std=iso9899:1999 option is given.
     674              : 
     675              : The conditional text X in a %{S:X} or similar construct may contain
     676              : other nested % constructs or spaces, or even newlines.  They are
     677              : processed as usual, as described above.  Trailing white space in X is
     678              : ignored.  White space may also appear anywhere on the left side of the
     679              : colon in these constructs, except between . or * and the corresponding
     680              : word.
     681              : 
     682              : The -O, -f, -g, -m, and -W switches are handled specifically in these
     683              : constructs.  If another value of -O or the negated form of a -f, -m, or
     684              : -W switch is found later in the command line, the earlier switch
     685              : value is ignored, except with {S*} where S is just one letter; this
     686              : passes all matching options.
     687              : 
     688              : The character | at the beginning of the predicate text is used to indicate
     689              : that a command should be piped to the following command, but only if -pipe
     690              : is specified.
     691              : 
     692              : Note that it is built into GCC which switches take arguments and which
     693              : do not.  You might think it would be useful to generalize this to
     694              : allow each compiler's spec to say which switches take arguments.  But
     695              : this cannot be done in a consistent fashion.  GCC cannot even decide
     696              : which input files have been specified without knowing which switches
     697              : take arguments, and it must know which input files to compile in order
     698              : to tell which compilers to run.
     699              : 
     700              : GCC also knows implicitly that arguments starting in `-l' are to be
     701              : treated as compiler output files, and passed to the linker in their
     702              : proper position among the other output files.  */
     703              : 
     704              : /* Define the macros used for specs %a, %l, %L, %S, %C, %1.  */
     705              : 
     706              : /* config.h can define ASM_SPEC to provide extra args to the assembler
     707              :    or extra switch-translations.  */
     708              : #ifndef ASM_SPEC
     709              : #define ASM_SPEC ""
     710              : #endif
     711              : 
     712              : /* config.h can define ASM_FINAL_SPEC to run a post processor after
     713              :    the assembler has run.  */
     714              : #ifndef ASM_FINAL_SPEC
     715              : #define ASM_FINAL_SPEC \
     716              :   "%{gsplit-dwarf: \n\
     717              :        objcopy --extract-dwo \
     718              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     719              :          %b.dwo \n\
     720              :        objcopy --strip-dwo \
     721              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     722              :     }"
     723              : #endif
     724              : 
     725              : /* config.h can define CPP_SPEC to provide extra args to the C preprocessor
     726              :    or extra switch-translations.  */
     727              : #ifndef CPP_SPEC
     728              : #define CPP_SPEC ""
     729              : #endif
     730              : 
     731              : /* libc can define LIBC_CPP_SPEC to provide extra args to the C preprocessor
     732              :    or extra switch-translations. */
     733              : 
     734              : #ifndef LIBC_CPP_SPEC
     735              : #define LIBC_CPP_SPEC ""
     736              : #endif
     737              : 
     738              : /* Operating systems can define OS_CC1_SPEC to provide extra args to cc1 and
     739              :    cc1plus or extra switch-translations.  The OS_CC1_SPEC is appended
     740              :    to CC1_SPEC in the initialization of cc1_spec.  */
     741              : #ifndef OS_CC1_SPEC
     742              : #define OS_CC1_SPEC ""
     743              : #endif
     744              : 
     745              : /* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
     746              :    or extra switch-translations.  */
     747              : #ifndef CC1_SPEC
     748              : #define CC1_SPEC ""
     749              : #endif
     750              : 
     751              : /* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
     752              :    or extra switch-translations.  */
     753              : #ifndef CC1PLUS_SPEC
     754              : #define CC1PLUS_SPEC ""
     755              : #endif
     756              : 
     757              : /* config.h can define LINK_SPEC to provide extra args to the linker
     758              :    or extra switch-translations.  */
     759              : #ifndef LINK_SPEC
     760              : #define LINK_SPEC ""
     761              : #endif
     762              : 
     763              : /* libc can define LIBC_LINK_SPEC to provide extra args to the linker
     764              :    or extra switch-translations.  */
     765              : #ifndef LIBC_LINK_SPEC
     766              : #define LIBC_LINK_SPEC ""
     767              : #endif
     768              : 
     769              : /* config.h can define LIB_SPEC to override the default libraries.  */
     770              : #ifndef LIB_SPEC
     771              : #define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
     772              : #endif
     773              : 
     774              : /* When using -fsplit-stack we need to wrap pthread_create, in order
     775              :    to initialize the stack guard.  We always use wrapping, rather than
     776              :    shared library ordering, and we keep the wrapper function in
     777              :    libgcc.  This is not yet a real spec, though it could become one;
     778              :    it is currently just stuffed into LINK_SPEC.  FIXME: This wrapping
     779              :    only works with GNU ld and gold.  */
     780              : #ifdef HAVE_GOLD_NON_DEFAULT_SPLIT_STACK
     781              : #define STACK_SPLIT_SPEC " %{fsplit-stack: -fuse-ld=gold --wrap=pthread_create}"
     782              : #else
     783              : #define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
     784              : #endif
     785              : 
     786              : #ifndef LIBASAN_SPEC
     787              : #define STATIC_LIBASAN_LIBS \
     788              :   " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}"
     789              : #ifdef LIBASAN_EARLY_SPEC
     790              : #define LIBASAN_SPEC STATIC_LIBASAN_LIBS
     791              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     792              : #define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
     793              :                      "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
     794              :                      STATIC_LIBASAN_LIBS
     795              : #else
     796              : #define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS
     797              : #endif
     798              : #endif
     799              : 
     800              : #ifndef LIBASAN_EARLY_SPEC
     801              : #define LIBASAN_EARLY_SPEC ""
     802              : #endif
     803              : 
     804              : #ifndef LIBHWASAN_SPEC
     805              : #define STATIC_LIBHWASAN_LIBS \
     806              :   " %{static-libhwasan|static:%:include(libsanitizer.spec)%(link_libhwasan)}"
     807              : #ifdef LIBHWASAN_EARLY_SPEC
     808              : #define LIBHWASAN_SPEC STATIC_LIBHWASAN_LIBS
     809              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     810              : #define LIBHWASAN_SPEC "%{static-libhwasan:" LD_STATIC_OPTION \
     811              :                      "} -lhwasan %{static-libhwasan:" LD_DYNAMIC_OPTION "}" \
     812              :                      STATIC_LIBHWASAN_LIBS
     813              : #else
     814              : #define LIBHWASAN_SPEC "-lhwasan" STATIC_LIBHWASAN_LIBS
     815              : #endif
     816              : #endif
     817              : 
     818              : #ifndef LIBHWASAN_EARLY_SPEC
     819              : #define LIBHWASAN_EARLY_SPEC ""
     820              : #endif
     821              : 
     822              : #ifndef LIBTSAN_SPEC
     823              : #define STATIC_LIBTSAN_LIBS \
     824              :   " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}"
     825              : #ifdef LIBTSAN_EARLY_SPEC
     826              : #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS
     827              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     828              : #define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
     829              :                      "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \
     830              :                      STATIC_LIBTSAN_LIBS
     831              : #else
     832              : #define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS
     833              : #endif
     834              : #endif
     835              : 
     836              : #ifndef LIBTSAN_EARLY_SPEC
     837              : #define LIBTSAN_EARLY_SPEC ""
     838              : #endif
     839              : 
     840              : #ifndef LIBLSAN_SPEC
     841              : #define STATIC_LIBLSAN_LIBS \
     842              :   " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}"
     843              : #ifdef LIBLSAN_EARLY_SPEC
     844              : #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS
     845              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     846              : #define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION \
     847              :                      "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \
     848              :                      STATIC_LIBLSAN_LIBS
     849              : #else
     850              : #define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS
     851              : #endif
     852              : #endif
     853              : 
     854              : #ifndef LIBLSAN_EARLY_SPEC
     855              : #define LIBLSAN_EARLY_SPEC ""
     856              : #endif
     857              : 
     858              : #ifndef LIBUBSAN_SPEC
     859              : #define STATIC_LIBUBSAN_LIBS \
     860              :   " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}"
     861              : #ifdef HAVE_LD_STATIC_DYNAMIC
     862              : #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
     863              :                      "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
     864              :                      STATIC_LIBUBSAN_LIBS
     865              : #else
     866              : #define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS
     867              : #endif
     868              : #endif
     869              : 
     870              : /* Linker options for compressed debug sections.  */
     871              : #if HAVE_LD_COMPRESS_DEBUG == 0
     872              : /* No linker support.  */
     873              : #define LINK_COMPRESS_DEBUG_SPEC \
     874              :         " %{gz*:%e-gz is not supported in this configuration} "
     875              : #elif HAVE_LD_COMPRESS_DEBUG == 1
     876              : /* ELF gABI style.  */
     877              : #define LINK_COMPRESS_DEBUG_SPEC \
     878              :         " %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
     879              :         " %{gz=none:"   LD_COMPRESS_DEBUG_OPTION "=none}" \
     880              :         " %{gz=zstd:%e-gz=zstd is not supported in this configuration} " \
     881              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     882              : #elif HAVE_LD_COMPRESS_DEBUG == 2
     883              : /* ELF gABI style and ZSTD.  */
     884              : #define LINK_COMPRESS_DEBUG_SPEC \
     885              :         " %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
     886              :         " %{gz=none:"   LD_COMPRESS_DEBUG_OPTION "=none}" \
     887              :         " %{gz=zstd:"   LD_COMPRESS_DEBUG_OPTION "=zstd}" \
     888              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     889              : #else
     890              : #error Unknown value for HAVE_LD_COMPRESS_DEBUG.
     891              : #endif
     892              : 
     893              : /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
     894              :    included.  */
     895              : #ifndef LIBGCC_SPEC
     896              : #if defined(REAL_LIBGCC_SPEC)
     897              : #define LIBGCC_SPEC REAL_LIBGCC_SPEC
     898              : #elif defined(LINK_LIBGCC_SPECIAL_1)
     899              : /* Have gcc do the search for libgcc.a.  */
     900              : #define LIBGCC_SPEC "libgcc.a%s"
     901              : #else
     902              : #define LIBGCC_SPEC "-lgcc"
     903              : #endif
     904              : #endif
     905              : 
     906              : /* config.h can define STARTFILE_SPEC to override the default crt0 files.  */
     907              : #ifndef STARTFILE_SPEC
     908              : #define STARTFILE_SPEC  \
     909              :   "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
     910              : #endif
     911              : 
     912              : /* config.h can define ENDFILE_SPEC to override the default crtn files.  */
     913              : #ifndef ENDFILE_SPEC
     914              : #define ENDFILE_SPEC ""
     915              : #endif
     916              : 
     917              : #ifndef LINKER_NAME
     918              : #define LINKER_NAME "collect2"
     919              : #endif
     920              : 
     921              : #ifdef HAVE_AS_DEBUG_PREFIX_MAP
     922              : #define ASM_MAP " %{ffile-prefix-map=*:--debug-prefix-map %*} %{fdebug-prefix-map=*:--debug-prefix-map %*}"
     923              : #else
     924              : #define ASM_MAP ""
     925              : #endif
     926              : 
     927              : /* Assembler options for compressed debug sections.  */
     928              : #if HAVE_LD_COMPRESS_DEBUG == 0
     929              : /* Reject if the linker cannot write compressed debug sections.  */
     930              : #define ASM_COMPRESS_DEBUG_SPEC \
     931              :         " %{gz*:%e-gz is not supported in this configuration} "
     932              : #else /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     933              : #if HAVE_AS_COMPRESS_DEBUG == 0
     934              : /* No assembler support.  Ignore silently.  */
     935              : #define ASM_COMPRESS_DEBUG_SPEC \
     936              :         " %{gz*:} "
     937              : #elif HAVE_AS_COMPRESS_DEBUG == 1
     938              : /* ELF gABI style.  */
     939              : #define ASM_COMPRESS_DEBUG_SPEC \
     940              :         " %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
     941              :         " %{gz=none:"   AS_COMPRESS_DEBUG_OPTION "=none}" \
     942              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     943              : #elif HAVE_AS_COMPRESS_DEBUG == 2
     944              : /* ELF gABI style and ZSTD.  */
     945              : #define ASM_COMPRESS_DEBUG_SPEC \
     946              :         " %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
     947              :         " %{gz=none:"   AS_COMPRESS_DEBUG_OPTION "=none}" \
     948              :         " %{gz=zstd:"   AS_COMPRESS_DEBUG_OPTION "=zstd}" \
     949              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     950              : #else
     951              : #error Unknown value for HAVE_AS_COMPRESS_DEBUG.
     952              : #endif
     953              : #endif /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     954              : 
     955              : /* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
     956              :    to the assembler, when compiling assembly sources only.  */
     957              : #ifndef ASM_DEBUG_SPEC
     958              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     959              : /* If --gdwarf-N is supported and as can handle even compiler generated
     960              :    .debug_line with it, supply --gdwarf-N in ASM_DEBUG_OPTION_SPEC rather
     961              :    than in ASM_DEBUG_SPEC, so that it applies to both .s and .c etc.
     962              :    compilations.  */
     963              : #  define ASM_DEBUG_DWARF_OPTION ""
     964              : # elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && !defined(HAVE_LD_BROKEN_PE_DWARF5)
     965              : #  define ASM_DEBUG_DWARF_OPTION "%{%:dwarf-version-gt(4):--gdwarf-5;" \
     966              :         "%:dwarf-version-gt(3):--gdwarf-4;"                           \
     967              :         "%:dwarf-version-gt(2):--gdwarf-3;"                           \
     968              :         ":--gdwarf2}"
     969              : # else
     970              : #  define ASM_DEBUG_DWARF_OPTION "--gdwarf2"
     971              : # endif
     972              : #  if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
     973              : #   define ASM_DEBUG_SPEC "%{g*:%{%:debug-level-gt(0):" \
     974              :         ASM_DEBUG_DWARF_OPTION "}}" ASM_MAP
     975              : #  endif
     976              : # endif
     977              : #ifndef ASM_DEBUG_SPEC
     978              : # define ASM_DEBUG_SPEC ""
     979              : #endif
     980              : 
     981              : /* Define ASM_DEBUG_OPTION_SPEC to be a spec suitable for translating '-g'
     982              :    to the assembler when compiling all sources.  */
     983              : #ifndef ASM_DEBUG_OPTION_SPEC
     984              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     985              : #  define ASM_DEBUG_OPTION_DWARF_OPT                                    \
     986              :         "%{%:dwarf-version-gt(4):--gdwarf-5 ;"                                \
     987              :         "%:dwarf-version-gt(3):--gdwarf-4 ;"                          \
     988              :         "%:dwarf-version-gt(2):--gdwarf-3 ;"                          \
     989              :         ":--gdwarf2 }"
     990              : # if defined(DWARF2_DEBUGGING_INFO)
     991              : #   define ASM_DEBUG_OPTION_SPEC "%{g*:%{%:debug-level-gt(0):" \
     992              :         ASM_DEBUG_OPTION_DWARF_OPT "}}"
     993              : #  endif
     994              : # endif
     995              : #endif
     996              : #ifndef ASM_DEBUG_OPTION_SPEC
     997              : # define ASM_DEBUG_OPTION_SPEC ""
     998              : #endif
     999              : 
    1000              : /* Here is the spec for running the linker, after compiling all files.  */
    1001              : 
    1002              : #if defined(TARGET_PROVIDES_LIBATOMIC) && defined(USE_LD_AS_NEEDED)
    1003              : #ifdef USE_LD_AS_NEEDED_LDSCRIPT
    1004              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:-latomic_asneeded} "
    1005              : #else
    1006              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:" LD_AS_NEEDED_OPTION \
    1007              :                             " -latomic " LD_NO_AS_NEEDED_OPTION "} "
    1008              : #endif
    1009              : #else
    1010              : #define LINK_LIBATOMIC_SPEC ""
    1011              : #endif
    1012              : 
    1013              : /* This is overridable by the target in case they need to specify the
    1014              :    -lgcc and -lc order specially, yet not require them to override all
    1015              :    of LINK_COMMAND_SPEC.  */
    1016              : #ifndef LINK_GCC_C_SEQUENCE_SPEC
    1017              : #define LINK_GCC_C_SEQUENCE_SPEC "%G %{!nolibc:%L %G}"
    1018              : #endif
    1019              : 
    1020              : #ifndef LINK_SSP_SPEC
    1021              : #ifdef TARGET_LIBC_PROVIDES_SSP
    1022              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1023              :                        "|fstack-protector-strong|fstack-protector-explicit:}"
    1024              : #else
    1025              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1026              :                        "|fstack-protector-strong|fstack-protector-explicit" \
    1027              :                        ":-lssp_nonshared -lssp}"
    1028              : #endif
    1029              : #endif
    1030              : 
    1031              : #ifdef ENABLE_DEFAULT_PIE
    1032              : #define PIE_SPEC                "!no-pie"
    1033              : #define NO_FPIE1_SPEC           "fno-pie"
    1034              : #define FPIE1_SPEC              NO_FPIE1_SPEC ":;"
    1035              : #define NO_FPIE2_SPEC           "fno-PIE"
    1036              : #define FPIE2_SPEC              NO_FPIE2_SPEC ":;"
    1037              : #define NO_FPIE_SPEC            NO_FPIE1_SPEC "|" NO_FPIE2_SPEC
    1038              : #define FPIE_SPEC               NO_FPIE_SPEC ":;"
    1039              : #define NO_FPIC1_SPEC           "fno-pic"
    1040              : #define FPIC1_SPEC              NO_FPIC1_SPEC ":;"
    1041              : #define NO_FPIC2_SPEC           "fno-PIC"
    1042              : #define FPIC2_SPEC              NO_FPIC2_SPEC ":;"
    1043              : #define NO_FPIC_SPEC            NO_FPIC1_SPEC "|" NO_FPIC2_SPEC
    1044              : #define FPIC_SPEC               NO_FPIC_SPEC ":;"
    1045              : #define NO_FPIE1_AND_FPIC1_SPEC NO_FPIE1_SPEC "|" NO_FPIC1_SPEC
    1046              : #define FPIE1_OR_FPIC1_SPEC     NO_FPIE1_AND_FPIC1_SPEC ":;"
    1047              : #define NO_FPIE2_AND_FPIC2_SPEC NO_FPIE2_SPEC "|" NO_FPIC2_SPEC
    1048              : #define FPIE2_OR_FPIC2_SPEC     NO_FPIE2_AND_FPIC2_SPEC ":;"
    1049              : #define NO_FPIE_AND_FPIC_SPEC   NO_FPIE_SPEC "|" NO_FPIC_SPEC
    1050              : #define FPIE_OR_FPIC_SPEC       NO_FPIE_AND_FPIC_SPEC ":;"
    1051              : #else
    1052              : #define PIE_SPEC                "pie"
    1053              : #define FPIE1_SPEC              "fpie"
    1054              : #define NO_FPIE1_SPEC           FPIE1_SPEC ":;"
    1055              : #define FPIE2_SPEC              "fPIE"
    1056              : #define NO_FPIE2_SPEC           FPIE2_SPEC ":;"
    1057              : #define FPIE_SPEC               FPIE1_SPEC "|" FPIE2_SPEC
    1058              : #define NO_FPIE_SPEC            FPIE_SPEC ":;"
    1059              : #define FPIC1_SPEC              "fpic"
    1060              : #define NO_FPIC1_SPEC           FPIC1_SPEC ":;"
    1061              : #define FPIC2_SPEC              "fPIC"
    1062              : #define NO_FPIC2_SPEC           FPIC2_SPEC ":;"
    1063              : #define FPIC_SPEC               FPIC1_SPEC "|" FPIC2_SPEC
    1064              : #define NO_FPIC_SPEC            FPIC_SPEC ":;"
    1065              : #define FPIE1_OR_FPIC1_SPEC     FPIE1_SPEC "|" FPIC1_SPEC
    1066              : #define NO_FPIE1_AND_FPIC1_SPEC FPIE1_OR_FPIC1_SPEC ":;"
    1067              : #define FPIE2_OR_FPIC2_SPEC     FPIE2_SPEC "|" FPIC2_SPEC
    1068              : #define NO_FPIE2_AND_FPIC2_SPEC FPIE1_OR_FPIC2_SPEC ":;"
    1069              : #define FPIE_OR_FPIC_SPEC       FPIE_SPEC "|" FPIC_SPEC
    1070              : #define NO_FPIE_AND_FPIC_SPEC   FPIE_OR_FPIC_SPEC ":;"
    1071              : #endif
    1072              : 
    1073              : #ifndef LINK_PIE_SPEC
    1074              : #ifdef HAVE_LD_PIE
    1075              : #ifndef LD_PIE_SPEC
    1076              : #define LD_PIE_SPEC "-pie"
    1077              : #endif
    1078              : #else
    1079              : #define LD_PIE_SPEC ""
    1080              : #endif
    1081              : #define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} "
    1082              : #endif
    1083              : 
    1084              : #ifndef LINK_BUILDID_SPEC
    1085              : # if defined(HAVE_LD_BUILDID) && defined(ENABLE_LD_BUILDID)
    1086              : #  define LINK_BUILDID_SPEC "%{!r:--build-id} "
    1087              : # endif
    1088              : #endif
    1089              : 
    1090              : #ifndef LTO_PLUGIN_SPEC
    1091              : #define LTO_PLUGIN_SPEC ""
    1092              : #endif
    1093              : 
    1094              : /* Conditional to test whether the LTO plugin is used or not.
    1095              :    FIXME: For slim LTO we will need to enable plugin unconditionally.  This
    1096              :    still cause problems with PLUGIN_LD != LD and when plugin is built but
    1097              :    not usable.  For GCC 4.6 we don't support slim LTO and thus we can enable
    1098              :    plugin only when LTO is enabled.  We still honor explicit
    1099              :    -fuse-linker-plugin if the linker used understands -plugin.  */
    1100              : 
    1101              : /* The linker has some plugin support.  */
    1102              : #if HAVE_LTO_PLUGIN > 0
    1103              : /* The linker used has full plugin support, use LTO plugin by default.  */
    1104              : #if HAVE_LTO_PLUGIN == 2
    1105              : #define PLUGIN_COND "!fno-use-linker-plugin:%{!fno-lto"
    1106              : #define PLUGIN_COND_CLOSE "}"
    1107              : #else
    1108              : /* The linker used has limited plugin support, use LTO plugin with explicit
    1109              :    -fuse-linker-plugin.  */
    1110              : #define PLUGIN_COND "fuse-linker-plugin"
    1111              : #define PLUGIN_COND_CLOSE ""
    1112              : #endif
    1113              : #define LINK_PLUGIN_SPEC \
    1114              :     "%{" PLUGIN_COND": \
    1115              :     -plugin %(linker_plugin_file) \
    1116              :     -plugin-opt=%(lto_wrapper) \
    1117              :     -plugin-opt=-fresolution=%u.res \
    1118              :     " LTO_PLUGIN_SPEC "\
    1119              :     %{flinker-output=*:-plugin-opt=-linker-output-known} \
    1120              :     %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
    1121              :     }" PLUGIN_COND_CLOSE
    1122              : #else
    1123              : /* The linker used doesn't support -plugin, reject -fuse-linker-plugin.  */
    1124              : #define LINK_PLUGIN_SPEC "%{fuse-linker-plugin:\
    1125              :     %e-fuse-linker-plugin is not supported in this configuration}"
    1126              : #endif
    1127              : 
    1128              : /* Linker command line options for -fsanitize= early on the command line.  */
    1129              : #ifndef SANITIZER_EARLY_SPEC
    1130              : #define SANITIZER_EARLY_SPEC "\
    1131              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
    1132              :     %{%:sanitize(hwaddress):" LIBHWASAN_EARLY_SPEC "} \
    1133              :     %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
    1134              :     %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}}"
    1135              : #endif
    1136              : 
    1137              : /* Linker command line options for -fsanitize= late on the command line.  */
    1138              : #ifndef SANITIZER_SPEC
    1139              : #define SANITIZER_SPEC "\
    1140              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
    1141              :     %{static:%ecannot specify -static with -fsanitize=address}}\
    1142              :     %{%:sanitize(hwaddress):" LIBHWASAN_SPEC "\
    1143              :         %{static:%ecannot specify -static with -fsanitize=hwaddress}}\
    1144              :     %{%:sanitize(thread):" LIBTSAN_SPEC "\
    1145              :     %{static:%ecannot specify -static with -fsanitize=thread}}\
    1146              :     %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
    1147              :     %{%:sanitize(leak):" LIBLSAN_SPEC "}}}}"
    1148              : #endif
    1149              : 
    1150              : #ifndef POST_LINK_SPEC
    1151              : #define POST_LINK_SPEC ""
    1152              : #endif
    1153              : 
    1154              : /*  This is the spec to use, once the code for creating the vtable
    1155              :     verification runtime library, libvtv.so, has been created.  Currently
    1156              :     the vtable verification runtime functions are in libstdc++, so we use
    1157              :     the spec just below this one.  */
    1158              : #ifndef VTABLE_VERIFICATION_SPEC
    1159              : #if ENABLE_VTABLE_VERIFY
    1160              : #define VTABLE_VERIFICATION_SPEC "\
    1161              : %{!nostdlib:%{!r:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
    1162              :     %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}}"
    1163              : #else
    1164              : #define VTABLE_VERIFICATION_SPEC "\
    1165              : %{fvtable-verify=none:} \
    1166              : %{fvtable-verify=std: \
    1167              :   %e-fvtable-verify=std is not supported in this configuration} \
    1168              : %{fvtable-verify=preinit: \
    1169              :   %e-fvtable-verify=preinit is not supported in this configuration}"
    1170              : #endif
    1171              : #endif
    1172              : 
    1173              : /* -u* was put back because both BSD and SysV seem to support it.  */
    1174              : /* %{static|no-pie|static-pie:} simply prevents an error message:
    1175              :    1. If the target machine doesn't handle -static.
    1176              :    2. If PIE isn't enabled by default.
    1177              :    3. If the target machine doesn't handle -static-pie.
    1178              :  */
    1179              : /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
    1180              :    scripts which exist in user specified directories, or in standard
    1181              :    directories.  */
    1182              : /* We pass any -flto flags on to the linker, which is expected
    1183              :    to understand them.  In practice, this means it had better be collect2.  */
    1184              : /* %{e*} includes -export-dynamic; see comment in common.opt.  */
    1185              : #ifndef LINK_COMMAND_SPEC
    1186              : #define LINK_COMMAND_SPEC "\
    1187              : %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
    1188              :     %(linker) " \
    1189              :     LINK_PLUGIN_SPEC \
    1190              :    "%{flto|flto=*:%<fcompare-debug*} \
    1191              :     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    1192              :    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    1193              :    "%X %{o*} %{e*} %{N} %{n} %{r}\
    1194              :     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
    1195              :     %{static|no-pie|static-pie:} %@{L*} %(link_libgcc) " \
    1196              :     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o "" \
    1197              :     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
    1198              :         %:include(libgomp.spec)%(link_gomp)}\
    1199              :     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
    1200              :     " STACK_SPLIT_SPEC "\
    1201              :     %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
    1202              :     %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\
    1203              :     %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*}  \n%(post_link) }}}}}}"
    1204              : #endif
    1205              : 
    1206              : #ifndef LINK_LIBGCC_SPEC
    1207              : /* Generate -L options for startfile prefix list.  */
    1208              : # define LINK_LIBGCC_SPEC "%D"
    1209              : #endif
    1210              : 
    1211              : #ifndef STARTFILE_PREFIX_SPEC
    1212              : # define STARTFILE_PREFIX_SPEC ""
    1213              : #endif
    1214              : 
    1215              : #ifndef SYSROOT_SPEC
    1216              : # define SYSROOT_SPEC "--sysroot=%R"
    1217              : #endif
    1218              : 
    1219              : #ifndef SYSROOT_SUFFIX_SPEC
    1220              : # define SYSROOT_SUFFIX_SPEC ""
    1221              : #endif
    1222              : 
    1223              : #ifndef SYSROOT_HEADERS_SUFFIX_SPEC
    1224              : # define SYSROOT_HEADERS_SUFFIX_SPEC ""
    1225              : #endif
    1226              : 
    1227              : #ifndef RUNPATH_OPTION
    1228              : # define RUNPATH_OPTION "-rpath"
    1229              : #endif
    1230              : 
    1231              : static const char *asm_debug = ASM_DEBUG_SPEC;
    1232              : static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC;
    1233              : static const char *cpp_spec = CPP_SPEC LIBC_CPP_SPEC;
    1234              : static const char *cc1_spec = CC1_SPEC OS_CC1_SPEC;
    1235              : static const char *cc1plus_spec = CC1PLUS_SPEC;
    1236              : static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
    1237              : static const char *link_ssp_spec = LINK_SSP_SPEC;
    1238              : static const char *asm_spec = ASM_SPEC;
    1239              : static const char *asm_final_spec = ASM_FINAL_SPEC;
    1240              : static const char *link_spec = LINK_SPEC LIBC_LINK_SPEC;
    1241              : static const char *lib_spec = LIB_SPEC;
    1242              : static const char *link_gomp_spec = "";
    1243              : static const char *libgcc_spec = LIBGCC_SPEC;
    1244              : static const char *endfile_spec = ENDFILE_SPEC;
    1245              : static const char *startfile_spec = STARTFILE_SPEC;
    1246              : static const char *linker_name_spec = LINKER_NAME;
    1247              : static const char *linker_plugin_file_spec = "";
    1248              : static const char *lto_wrapper_spec = "";
    1249              : static const char *lto_gcc_spec = "";
    1250              : static const char *post_link_spec = POST_LINK_SPEC;
    1251              : static const char *link_command_spec = LINK_COMMAND_SPEC;
    1252              : static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
    1253              : static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
    1254              : static const char *sysroot_spec = SYSROOT_SPEC;
    1255              : static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
    1256              : static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
    1257              : static const char *self_spec = "";
    1258              : 
    1259              : /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    1260              :    There should be no need to override these in target dependent files,
    1261              :    but we need to copy them to the specs file so that newer versions
    1262              :    of the GCC driver can correctly drive older tool chains with the
    1263              :    appropriate -B options.  */
    1264              : 
    1265              : /* When cpplib handles traditional preprocessing, get rid of this, and
    1266              :    call cc1 (or cc1obj in objc/lang-specs.h) from the main specs so
    1267              :    that we default the front end language better.  */
    1268              : static const char *trad_capable_cpp =
    1269              : "cc1 -E %{traditional|traditional-cpp:-traditional-cpp}";
    1270              : 
    1271              : /* We don't wrap .d files in %W{} since a missing .d file, and
    1272              :    therefore no dependency entry, confuses make into thinking a .o
    1273              :    file that happens to exist is up-to-date.  */
    1274              : static const char *cpp_unique_options =
    1275              : "%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %@{I*&F*} %{P} %I\
    1276              :  %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
    1277              :  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
    1278              :  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
    1279              :  %{Mmodules} %{Mno-modules}\
    1280              :  %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
    1281              :  %{remap} %{%:debug-level-gt(2):-dD}\
    1282              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1283              :  %{H} %C %{D*&U*&A*} %{i*} %Z %i\
    1284              :  %{E|M|MM:%W{o*}} %{-embed*}\
    1285              :  %{fdeps-format=*:%{!fdeps-file=*:-fdeps-file=%:join(%{!o:%b.ddi}%{o*:%.ddi%*})}}\
    1286              :  %{fdeps-format=*:%{!fdeps-target=*:-fdeps-target=%:join(%{!o:%b.o}%{o*:%.o%*})}}";
    1287              : 
    1288              : /* This contains cpp options which are common with cc1_options and are passed
    1289              :    only when preprocessing only to avoid duplication.  We pass the cc1 spec
    1290              :    options to the preprocessor so that it the cc1 spec may manipulate
    1291              :    options used to set target flags.  Those special target flags settings may
    1292              :    in turn cause preprocessor symbols to be defined specially.  */
    1293              : static const char *cpp_options =
    1294              : "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
    1295              :  %{f*} %{g*:%{%:debug-level-gt(0):%{g*}\
    1296              :  %{!fno-working-directory:-fworking-directory}}} %{O*}\
    1297              :  %{undef} %{save-temps*:-fpch-preprocess}";
    1298              : 
    1299              : /* Pass -d* flags, possibly modifying -dumpdir, -dumpbase et al.
    1300              : 
    1301              :    Make it easy for a language to override the argument for the
    1302              :    %:dumps specs function call.  */
    1303              : #define DUMPS_OPTIONS(EXTS) \
    1304              :   "%<dumpdir %<dumpbase %<dumpbase-ext %{d*} %:dumps(" EXTS ")"
    1305              : 
    1306              : /* This contains cpp options which are not passed when the preprocessor
    1307              :    output will be used by another program.  */
    1308              : static const char *cpp_debug_options = DUMPS_OPTIONS ("");
    1309              : 
    1310              : /* NB: This is shared amongst all front-ends, except for Ada.  */
    1311              : static const char *cc1_options =
    1312              : "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
    1313              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1314              :  %1 %{!Q:-quiet} %(cpp_debug_options) %{m*} %{aux-info*}\
    1315              :  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
    1316              :  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
    1317              :  %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
    1318              :  %{-target-help:--target-help}\
    1319              :  %{-version:--version}\
    1320              :  %{-help=*:--help=%*}\
    1321              :  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %w%b.s}}}\
    1322              :  %{fsyntax-only:-o %j} %{-param*}\
    1323              :  %{coverage:-fprofile-arcs -ftest-coverage}\
    1324              :  %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:\
    1325              :    %{!fprofile-update=single:\
    1326              :      %{pthread:-fprofile-update=prefer-atomic}}}";
    1327              : 
    1328              : static const char *asm_options =
    1329              : "%{-target-help:%:print-asm-header()} "
    1330              : #if HAVE_GNU_AS
    1331              : /* If GNU AS is used, then convert -w (no warnings), -I, and -v
    1332              :    to the assembler equivalents.  */
    1333              : "%{v} %{w:-W} %{I*} "
    1334              : #endif
    1335              : "%(asm_debug_option)"
    1336              : ASM_COMPRESS_DEBUG_SPEC
    1337              : "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
    1338              : 
    1339              : static const char *invoke_as =
    1340              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1341              : "%{!fwpa*:\
    1342              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1343              :    %{!S:-o %|.s |\n as %(asm_options) %|.s %A }\
    1344              :   }";
    1345              : #else
    1346              : "%{!fwpa*:\
    1347              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1348              :    %{!S:-o %|.s |\n as %(asm_options) %m.s %A }\
    1349              :   }";
    1350              : #endif
    1351              : 
    1352              : /* Some compilers have limits on line lengths, and the multilib_select
    1353              :    and/or multilib_matches strings can be very long, so we build them at
    1354              :    run time.  */
    1355              : static struct obstack multilib_obstack;
    1356              : static const char *multilib_select;
    1357              : static const char *multilib_matches;
    1358              : static const char *multilib_defaults;
    1359              : static const char *multilib_exclusions;
    1360              : static const char *multilib_reuse;
    1361              : 
    1362              : /* Check whether a particular argument is a default argument.  */
    1363              : 
    1364              : #ifndef MULTILIB_DEFAULTS
    1365              : #define MULTILIB_DEFAULTS { "" }
    1366              : #endif
    1367              : 
    1368              : static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
    1369              : 
    1370              : #ifndef DRIVER_SELF_SPECS
    1371              : #define DRIVER_SELF_SPECS ""
    1372              : #endif
    1373              : 
    1374              : /* Linking to libgomp implies pthreads.  This is particularly important
    1375              :    for targets that use different start files and suchlike.  */
    1376              : #ifndef GOMP_SELF_SPECS
    1377              : #define GOMP_SELF_SPECS \
    1378              :   "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): " \
    1379              :   "-pthread}"
    1380              : #endif
    1381              : 
    1382              : /* Likewise for -fgnu-tm.  */
    1383              : #ifndef GTM_SELF_SPECS
    1384              : #define GTM_SELF_SPECS "%{fgnu-tm: -pthread}"
    1385              : #endif
    1386              : 
    1387              : static const char *const driver_self_specs[] = {
    1388              :   "%{fdump-final-insns:-fdump-final-insns=.} %<fdump-final-insns",
    1389              :   DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS,
    1390              :   /* This discards -fmultiflags at the end of self specs processing in the
    1391              :      driver, so that it is effectively Ignored, without actually marking it as
    1392              :      Ignored, which would get it discarded before self specs could remap it.  */
    1393              :   "%<fmultiflags"
    1394              : };
    1395              : 
    1396              : #ifndef OPTION_DEFAULT_SPECS
    1397              : #define OPTION_DEFAULT_SPECS { "", "" }
    1398              : #endif
    1399              : 
    1400              : struct default_spec
    1401              : {
    1402              :   const char *name;
    1403              :   const char *spec;
    1404              : };
    1405              : 
    1406              : static const struct default_spec
    1407              :   option_default_specs[] = { OPTION_DEFAULT_SPECS };
    1408              : 
    1409              : struct user_specs
    1410              : {
    1411              :   struct user_specs *next;
    1412              :   const char *filename;
    1413              : };
    1414              : 
    1415              : static struct user_specs *user_specs_head, *user_specs_tail;
    1416              : 
    1417              : 
    1418              : /* Record the mapping from file suffixes for compilation specs.  */
    1419              : 
    1420              : struct compiler
    1421              : {
    1422              :   const char *suffix;           /* Use this compiler for input files
    1423              :                                    whose names end in this suffix.  */
    1424              : 
    1425              :   const char *spec;             /* To use this compiler, run this spec.  */
    1426              : 
    1427              :   const char *cpp_spec;         /* If non-NULL, substitute this spec
    1428              :                                    for `%C', rather than the usual
    1429              :                                    cpp_spec.  */
    1430              :   int combinable;               /* If nonzero, compiler can deal with
    1431              :                                     multiple source files at once (IMA).  */
    1432              :   int needs_preprocessing;       /* If nonzero, source files need to
    1433              :                                     be run through a preprocessor.  */
    1434              : };
    1435              : 
    1436              : /* Pointer to a vector of `struct compiler' that gives the spec for
    1437              :    compiling a file, based on its suffix.
    1438              :    A file that does not end in any of these suffixes will be passed
    1439              :    unchanged to the loader and nothing else will be done to it.
    1440              : 
    1441              :    An entry containing two 0s is used to terminate the vector.
    1442              : 
    1443              :    If multiple entries match a file, the last matching one is used.  */
    1444              : 
    1445              : static struct compiler *compilers;
    1446              : 
    1447              : /* Number of entries in `compilers', not counting the null terminator.  */
    1448              : 
    1449              : static int n_compilers;
    1450              : 
    1451              : /* The default list of file name suffixes and their compilation specs.  */
    1452              : 
    1453              : static const struct compiler default_compilers[] =
    1454              : {
    1455              :   /* Add lists of suffixes of known languages here.  If those languages
    1456              :      were not present when we built the driver, we will hit these copies
    1457              :      and be given a more meaningful error than "file not used since
    1458              :      linking is not done".  */
    1459              :   {".m",  "#Objective-C", 0, 0, 0}, {".mi",  "#Objective-C", 0, 0, 0},
    1460              :   {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
    1461              :   {".mii", "#Objective-C++", 0, 0, 0},
    1462              :   {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
    1463              :   {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
    1464              :   {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
    1465              :   {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
    1466              :   {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
    1467              :   {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
    1468              :   {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
    1469              :   {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0},
    1470              :   {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
    1471              :   {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0},
    1472              :   {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
    1473              :   {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0},
    1474              :   {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0},
    1475              :   {".r", "#Ratfor", 0, 0, 0},
    1476              :   {".go", "#Go", 0, 1, 0},
    1477              :   {".d", "#D", 0, 1, 0}, {".dd", "#D", 0, 1, 0}, {".di", "#D", 0, 1, 0},
    1478              :   {".mod", "#Modula-2", 0, 0, 0}, {".m2i", "#Modula-2", 0, 0, 0},
    1479              :   /* Next come the entries for C.  */
    1480              :   {".c", "@c", 0, 0, 1},
    1481              :   {"@c",
    1482              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1483              :       external preprocessor if -save-temps is given.  */
    1484              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1485              :       %{!E:%{!M:%{!MM:\
    1486              :           %{traditional:\
    1487              : %eGNU C no longer supports -traditional without -E}\
    1488              :       %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1489              :           %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1490              :             cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1491              :           %(cc1_options)}\
    1492              :       %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1493              :           cc1 %(cpp_unique_options) %(cc1_options)}}}\
    1494              :       %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
    1495              :   {"-",
    1496              :    "%{!E:%e-E or -x required when input is from standard input}\
    1497              :     %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
    1498              :   {".h", "@c-header", 0, 0, 0},
    1499              :   {"@c-header",
    1500              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1501              :       external preprocessor if -save-temps is given.  */
    1502              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1503              :       %{!E:%{!M:%{!MM:\
    1504              :           %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1505              :                 %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1506              :                     cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1507              :                         %(cc1_options)\
    1508              :                         %{!fsyntax-only:%{!S:-o %g.s} \
    1509              :                             %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1510              :                                                %W{o*:--output-pch %w%*}}%{!S:%V}}}\
    1511              :           %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1512              :                 cc1 %(cpp_unique_options) %(cc1_options)\
    1513              :                     %{!fsyntax-only:%{!S:-o %g.s} \
    1514              :                         %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1515              :                                            %W{o*:--output-pch %w%*}}%{!S:%V}}}}}}}}", 0, 0, 0},
    1516              :   {".i", "@cpp-output", 0, 0, 0},
    1517              :   {"@cpp-output",
    1518              :    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
    1519              :   {".s", "@assembler", 0, 0, 0},
    1520              :   {"@assembler",
    1521              :    "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
    1522              :   {".sx", "@assembler-with-cpp", 0, 0, 0},
    1523              :   {".S", "@assembler-with-cpp", 0, 0, 0},
    1524              :   {"@assembler-with-cpp",
    1525              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1526              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1527              :       %{E|M|MM:%(cpp_debug_options)}\
    1528              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1529              :        as %(asm_debug) %(asm_options) %|.s %A }}}}"
    1530              : #else
    1531              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1532              :       %{E|M|MM:%(cpp_debug_options)}\
    1533              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1534              :        as %(asm_debug) %(asm_options) %m.s %A }}}}"
    1535              : #endif
    1536              :    , 0, 0, 0},
    1537              : 
    1538              : #ifndef EXTRA_DEFAULT_COMPILERS
    1539              : #define EXTRA_DEFAULT_COMPILERS
    1540              : #endif
    1541              :   EXTRA_DEFAULT_COMPILERS
    1542              : 
    1543              : #include "specs.h"
    1544              :   /* Mark end of table.  */
    1545              :   {0, 0, 0, 0, 0}
    1546              : };
    1547              : 
    1548              : /* Number of elements in default_compilers, not counting the terminator.  */
    1549              : 
    1550              : static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
    1551              : 
    1552              : typedef char *char_p; /* For DEF_VEC_P.  */
    1553              : 
    1554              : /* A vector of options to give to the linker.
    1555              :    These options are accumulated by %x,
    1556              :    and substituted into the linker command with %X.  */
    1557              : static vec<char_p> linker_options;
    1558              : 
    1559              : /* A vector of options to give to the assembler.
    1560              :    These options are accumulated by -Wa,
    1561              :    and substituted into the assembler command with %Y.  */
    1562              : static vec<char_p> assembler_options;
    1563              : 
    1564              : /* A vector of options to give to the preprocessor.
    1565              :    These options are accumulated by -Wp,
    1566              :    and substituted into the preprocessor command with %Z.  */
    1567              : static vec<char_p> preprocessor_options;
    1568              : 
    1569              : static char *
    1570     29608280 : skip_whitespace (char *p)
    1571              : {
    1572     68621085 :   while (1)
    1573              :     {
    1574              :       /* A fully-blank line is a delimiter in the SPEC file and shouldn't
    1575              :          be considered whitespace.  */
    1576     68621085 :       if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
    1577      4968320 :         return p + 1;
    1578     63652765 :       else if (*p == '\n' || *p == ' ' || *p == '\t')
    1579     38892392 :         p++;
    1580     24760373 :       else if (*p == '#')
    1581              :         {
    1582      3739502 :           while (*p != '\n')
    1583      3619089 :             p++;
    1584       120413 :           p++;
    1585              :         }
    1586              :       else
    1587              :         break;
    1588              :     }
    1589              : 
    1590              :   return p;
    1591              : }
    1592              : /* Structures to keep track of prefixes to try when looking for files.  */
    1593              : 
    1594              : struct prefix_list
    1595              : {
    1596              :   const char *prefix;         /* String to prepend to the path.  */
    1597              :   struct prefix_list *next;   /* Next in linked list.  */
    1598              :   int require_machine_suffix; /* Don't use without machine_suffix.  */
    1599              :   /* 2 means try both machine_suffix and just_machine_suffix.  */
    1600              :   int priority;               /* Sort key - priority within list.  */
    1601              :   int os_multilib;            /* 1 if OS multilib scheme should be used,
    1602              :                                  0 for GCC multilib scheme.  */
    1603              : };
    1604              : 
    1605              : struct path_prefix
    1606              : {
    1607              :   struct prefix_list *plist;  /* List of prefixes to try */
    1608              :   int max_len;                /* Max length of a prefix in PLIST */
    1609              :   const char *name;           /* Name of this list (used in config stuff) */
    1610              : };
    1611              : 
    1612              : /* List of prefixes to try when looking for executables.  */
    1613              : 
    1614              : static struct path_prefix exec_prefixes = { 0, 0, "exec" };
    1615              : 
    1616              : /* List of prefixes to try when looking for startup (crt0) files.  */
    1617              : 
    1618              : static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };
    1619              : 
    1620              : /* List of prefixes to try when looking for include files.  */
    1621              : 
    1622              : static struct path_prefix include_prefixes = { 0, 0, "include" };
    1623              : 
    1624              : /* Suffix to attach to directories searched for commands.
    1625              :    This looks like `MACHINE/VERSION/'.  */
    1626              : 
    1627              : static const char *machine_suffix = 0;
    1628              : 
    1629              : /* Suffix to attach to directories searched for commands.
    1630              :    This is just `MACHINE/'.  */
    1631              : 
    1632              : static const char *just_machine_suffix = 0;
    1633              : 
    1634              : /* Prefix to attach to *basename* of commands being searched.
    1635              :    This is just `MACHINE-'.  */
    1636              : 
    1637              : static const char *just_machine_prefix = 0;
    1638              : 
    1639              : /* Adjusted value of GCC_EXEC_PREFIX envvar.  */
    1640              : 
    1641              : static const char *gcc_exec_prefix;
    1642              : 
    1643              : /* Adjusted value of standard_libexec_prefix.  */
    1644              : 
    1645              : static const char *gcc_libexec_prefix;
    1646              : 
    1647              : /* Default prefixes to attach to command names.  */
    1648              : 
    1649              : #ifndef STANDARD_STARTFILE_PREFIX_1
    1650              : #define STANDARD_STARTFILE_PREFIX_1 "/lib/"
    1651              : #endif
    1652              : #ifndef STANDARD_STARTFILE_PREFIX_2
    1653              : #define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
    1654              : #endif
    1655              : 
    1656              : #ifdef CROSS_DIRECTORY_STRUCTURE  /* Don't use these prefixes for a cross compiler.  */
    1657              : #undef MD_EXEC_PREFIX
    1658              : #undef MD_STARTFILE_PREFIX
    1659              : #undef MD_STARTFILE_PREFIX_1
    1660              : #endif
    1661              : 
    1662              : /* If no prefixes defined, use the null string, which will disable them.  */
    1663              : #ifndef MD_EXEC_PREFIX
    1664              : #define MD_EXEC_PREFIX ""
    1665              : #endif
    1666              : #ifndef MD_STARTFILE_PREFIX
    1667              : #define MD_STARTFILE_PREFIX ""
    1668              : #endif
    1669              : #ifndef MD_STARTFILE_PREFIX_1
    1670              : #define MD_STARTFILE_PREFIX_1 ""
    1671              : #endif
    1672              : 
    1673              : /* These directories are locations set at configure-time based on the
    1674              :    --prefix option provided to configure.  Their initializers are
    1675              :    defined in Makefile.in.  These paths are not *directly* used when
    1676              :    gcc_exec_prefix is set because, in that case, we know where the
    1677              :    compiler has been installed, and use paths relative to that
    1678              :    location instead.  */
    1679              : static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
    1680              : static const char *const standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
    1681              : static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
    1682              : static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
    1683              : 
    1684              : /* For native compilers, these are well-known paths containing
    1685              :    components that may be provided by the system.  For cross
    1686              :    compilers, these paths are not used.  */
    1687              : static const char *md_exec_prefix = MD_EXEC_PREFIX;
    1688              : static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
    1689              : static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
    1690              : static const char *const standard_startfile_prefix_1
    1691              :   = STANDARD_STARTFILE_PREFIX_1;
    1692              : static const char *const standard_startfile_prefix_2
    1693              :   = STANDARD_STARTFILE_PREFIX_2;
    1694              : 
    1695              : /* A relative path to be used in finding the location of tools
    1696              :    relative to the driver.  */
    1697              : static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
    1698              : 
    1699              : /* A prefix to be used when this is an accelerator compiler.  */
    1700              : static const char *const accel_dir_suffix = ACCEL_DIR_SUFFIX;
    1701              : 
    1702              : /* Subdirectory to use for locating libraries.  Set by
    1703              :    set_multilib_dir based on the compilation options.  */
    1704              : 
    1705              : static const char *multilib_dir;
    1706              : 
    1707              : /* Subdirectory to use for locating libraries in OS conventions.  Set by
    1708              :    set_multilib_dir based on the compilation options.  */
    1709              : 
    1710              : static const char *multilib_os_dir;
    1711              : 
    1712              : /* Subdirectory to use for locating libraries in multiarch conventions.  Set by
    1713              :    set_multilib_dir based on the compilation options.  */
    1714              : 
    1715              : static const char *multiarch_dir;
    1716              : 
    1717              : /* Structure to keep track of the specs that have been defined so far.
    1718              :    These are accessed using %(specname) in a compiler or link
    1719              :    spec.  */
    1720              : 
    1721              : struct spec_list
    1722              : {
    1723              :                                 /* The following 2 fields must be first */
    1724              :                                 /* to allow EXTRA_SPECS to be initialized */
    1725              :   const char *name;             /* name of the spec.  */
    1726              :   const char *ptr;              /* available ptr if no static pointer */
    1727              : 
    1728              :                                 /* The following fields are not initialized */
    1729              :                                 /* by EXTRA_SPECS */
    1730              :   const char **ptr_spec;        /* pointer to the spec itself.  */
    1731              :   struct spec_list *next;       /* Next spec in linked list.  */
    1732              :   int name_len;                 /* length of the name */
    1733              :   bool user_p;                  /* whether string come from file spec.  */
    1734              :   bool alloc_p;                 /* whether string was allocated */
    1735              :   const char *default_ptr;      /* The default value of *ptr_spec.  */
    1736              : };
    1737              : 
    1738              : #define INIT_STATIC_SPEC(NAME,PTR) \
    1739              :   { NAME, NULL, PTR, (struct spec_list *) 0, sizeof (NAME) - 1, false, false, \
    1740              :     *PTR }
    1741              : 
    1742              : /* List of statically defined specs.  */
    1743              : static struct spec_list static_specs[] =
    1744              : {
    1745              :   INIT_STATIC_SPEC ("asm",                    &asm_spec),
    1746              :   INIT_STATIC_SPEC ("asm_debug",              &asm_debug),
    1747              :   INIT_STATIC_SPEC ("asm_debug_option",               &asm_debug_option),
    1748              :   INIT_STATIC_SPEC ("asm_final",              &asm_final_spec),
    1749              :   INIT_STATIC_SPEC ("asm_options",            &asm_options),
    1750              :   INIT_STATIC_SPEC ("invoke_as",              &invoke_as),
    1751              :   INIT_STATIC_SPEC ("cpp",                    &cpp_spec),
    1752              :   INIT_STATIC_SPEC ("cpp_options",            &cpp_options),
    1753              :   INIT_STATIC_SPEC ("cpp_debug_options",      &cpp_debug_options),
    1754              :   INIT_STATIC_SPEC ("cpp_unique_options",     &cpp_unique_options),
    1755              :   INIT_STATIC_SPEC ("trad_capable_cpp",               &trad_capable_cpp),
    1756              :   INIT_STATIC_SPEC ("cc1",                    &cc1_spec),
    1757              :   INIT_STATIC_SPEC ("cc1_options",            &cc1_options),
    1758              :   INIT_STATIC_SPEC ("cc1plus",                        &cc1plus_spec),
    1759              :   INIT_STATIC_SPEC ("link_gcc_c_sequence",    &link_gcc_c_sequence_spec),
    1760              :   INIT_STATIC_SPEC ("link_ssp",                       &link_ssp_spec),
    1761              :   INIT_STATIC_SPEC ("endfile",                        &endfile_spec),
    1762              :   INIT_STATIC_SPEC ("link",                   &link_spec),
    1763              :   INIT_STATIC_SPEC ("lib",                    &lib_spec),
    1764              :   INIT_STATIC_SPEC ("link_gomp",              &link_gomp_spec),
    1765              :   INIT_STATIC_SPEC ("libgcc",                 &libgcc_spec),
    1766              :   INIT_STATIC_SPEC ("startfile",              &startfile_spec),
    1767              :   INIT_STATIC_SPEC ("cross_compile",          &cross_compile),
    1768              :   INIT_STATIC_SPEC ("version",                        &compiler_version),
    1769              :   INIT_STATIC_SPEC ("multilib",                       &multilib_select),
    1770              :   INIT_STATIC_SPEC ("multilib_defaults",      &multilib_defaults),
    1771              :   INIT_STATIC_SPEC ("multilib_extra",         &multilib_extra),
    1772              :   INIT_STATIC_SPEC ("multilib_matches",               &multilib_matches),
    1773              :   INIT_STATIC_SPEC ("multilib_exclusions",    &multilib_exclusions),
    1774              :   INIT_STATIC_SPEC ("multilib_options",               &multilib_options),
    1775              :   INIT_STATIC_SPEC ("multilib_reuse",         &multilib_reuse),
    1776              :   INIT_STATIC_SPEC ("linker",                 &linker_name_spec),
    1777              :   INIT_STATIC_SPEC ("linker_plugin_file",     &linker_plugin_file_spec),
    1778              :   INIT_STATIC_SPEC ("lto_wrapper",            &lto_wrapper_spec),
    1779              :   INIT_STATIC_SPEC ("lto_gcc",                        &lto_gcc_spec),
    1780              :   INIT_STATIC_SPEC ("post_link",              &post_link_spec),
    1781              :   INIT_STATIC_SPEC ("link_libgcc",            &link_libgcc_spec),
    1782              :   INIT_STATIC_SPEC ("md_exec_prefix",         &md_exec_prefix),
    1783              :   INIT_STATIC_SPEC ("md_startfile_prefix",    &md_startfile_prefix),
    1784              :   INIT_STATIC_SPEC ("md_startfile_prefix_1",  &md_startfile_prefix_1),
    1785              :   INIT_STATIC_SPEC ("startfile_prefix_spec",  &startfile_prefix_spec),
    1786              :   INIT_STATIC_SPEC ("sysroot_spec",             &sysroot_spec),
    1787              :   INIT_STATIC_SPEC ("sysroot_suffix_spec",    &sysroot_suffix_spec),
    1788              :   INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec",       &sysroot_hdrs_suffix_spec),
    1789              :   INIT_STATIC_SPEC ("self_spec",              &self_spec),
    1790              : };
    1791              : 
    1792              : #ifdef EXTRA_SPECS              /* additional specs needed */
    1793              : /* Structure to keep track of just the first two args of a spec_list.
    1794              :    That is all that the EXTRA_SPECS macro gives us.  */
    1795              : struct spec_list_1
    1796              : {
    1797              :   const char *const name;
    1798              :   const char *const ptr;
    1799              : };
    1800              : 
    1801              : static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
    1802              : static struct spec_list *extra_specs = (struct spec_list *) 0;
    1803              : #endif
    1804              : 
    1805              : /* List of dynamically allocates specs that have been defined so far.  */
    1806              : 
    1807              : static struct spec_list *specs = (struct spec_list *) 0;
    1808              : 
    1809              : /* List of static spec functions.  */
    1810              : 
    1811              : static const struct spec_function static_spec_functions[] =
    1812              : {
    1813              :   { "getenv",                   getenv_spec_function },
    1814              :   { "if-exists",              if_exists_spec_function },
    1815              :   { "if-exists-else",         if_exists_else_spec_function },
    1816              :   { "if-exists-then-else",    if_exists_then_else_spec_function },
    1817              :   { "sanitize",                       sanitize_spec_function },
    1818              :   { "replace-outfile",                replace_outfile_spec_function },
    1819              :   { "remove-outfile",         remove_outfile_spec_function },
    1820              :   { "version-compare",                version_compare_spec_function },
    1821              :   { "include",                        include_spec_function },
    1822              :   { "find-file",              find_file_spec_function },
    1823              :   { "find-plugindir",         find_plugindir_spec_function },
    1824              :   { "print-asm-header",               print_asm_header_spec_function },
    1825              :   { "compare-debug-dump-opt", compare_debug_dump_opt_spec_function },
    1826              :   { "compare-debug-self-opt", compare_debug_self_opt_spec_function },
    1827              :   { "pass-through-libs",      pass_through_libs_spec_func },
    1828              :   { "dumps",                    dumps_spec_func },
    1829              :   { "gt",                     greater_than_spec_func },
    1830              :   { "debug-level-gt",         debug_level_greater_than_spec_func },
    1831              :   { "dwarf-version-gt",               dwarf_version_greater_than_spec_func },
    1832              :   { "fortran-preinclude-file",        find_fortran_preinclude_file},
    1833              :   { "join",                   join_spec_func},
    1834              : #ifdef EXTRA_SPEC_FUNCTIONS
    1835              :   EXTRA_SPEC_FUNCTIONS
    1836              : #endif
    1837              :   { 0, 0 }
    1838              : };
    1839              : 
    1840              : static int processing_spec_function;
    1841              : 
    1842              : /* Add appropriate libgcc specs to OBSTACK, taking into account
    1843              :    various permutations of -shared-libgcc, -shared, and such.  */
    1844              : 
    1845              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1846              : 
    1847              : #ifndef USE_LD_AS_NEEDED
    1848              : #define USE_LD_AS_NEEDED 0
    1849              : #endif
    1850              : 
    1851              : static void
    1852         1197 : init_gcc_specs (struct obstack *obstack, const char *shared_name,
    1853              :                 const char *static_name, const char *eh_name)
    1854              : {
    1855         1197 :   char *buf;
    1856              : 
    1857              : #if USE_LD_AS_NEEDED
    1858              : #if defined(USE_LD_AS_NEEDED_LDSCRIPT) && !defined(USE_LIBUNWIND_EXCEPTIONS)
    1859         1197 :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1860              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1861              :                 "%{!shared-libgcc:",
    1862              :                 static_name, " ",
    1863              :                 shared_name, "_asneeded}"
    1864              :                 "%{shared-libgcc:",
    1865              :                 shared_name, "%{!shared: ", static_name, "}"
    1866              :                 "}}"
    1867              : #else
    1868              :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1869              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1870              :                 "%{!shared-libgcc:",
    1871              :                 static_name, " " LD_AS_NEEDED_OPTION " ",
    1872              :                 shared_name, " " LD_NO_AS_NEEDED_OPTION
    1873              :                 "}"
    1874              :                 "%{shared-libgcc:",
    1875              :                 shared_name, "%{!shared: ", static_name, "}"
    1876              :                 "}}"
    1877              : #endif
    1878              : #else
    1879              :   buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name, "}"
    1880              :                 "%{!static:%{!static-libgcc:"
    1881              :                 "%{!shared:"
    1882              :                 "%{!shared-libgcc:", static_name, " ", eh_name, "}"
    1883              :                 "%{shared-libgcc:", shared_name, " ", static_name, "}"
    1884              :                 "}"
    1885              : #ifdef LINK_EH_SPEC
    1886              :                 "%{shared:"
    1887              :                 "%{shared-libgcc:", shared_name, "}"
    1888              :                 "%{!shared-libgcc:", static_name, "}"
    1889              :                 "}"
    1890              : #else
    1891              :                 "%{shared:", shared_name, "}"
    1892              : #endif
    1893              : #endif
    1894              :                 "}}", NULL);
    1895              : 
    1896         1197 :   obstack_grow (obstack, buf, strlen (buf));
    1897         1197 :   free (buf);
    1898         1197 : }
    1899              : #endif /* ENABLE_SHARED_LIBGCC */
    1900              : 
    1901              : /* Initialize the specs lookup routines.  */
    1902              : 
    1903              : static void
    1904         1197 : init_spec (void)
    1905              : {
    1906         1197 :   struct spec_list *next = (struct spec_list *) 0;
    1907         1197 :   struct spec_list *sl   = (struct spec_list *) 0;
    1908         1197 :   int i;
    1909              : 
    1910         1197 :   if (specs)
    1911              :     return;                     /* Already initialized.  */
    1912              : 
    1913         1197 :   if (verbose_flag)
    1914          108 :     fnotice (stderr, "Using built-in specs.\n");
    1915              : 
    1916              : #ifdef EXTRA_SPECS
    1917         1197 :   extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1));
    1918              : 
    1919         2394 :   for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
    1920              :     {
    1921         1197 :       sl = &extra_specs[i];
    1922         1197 :       sl->name = extra_specs_1[i].name;
    1923         1197 :       sl->ptr = extra_specs_1[i].ptr;
    1924         1197 :       sl->next = next;
    1925         1197 :       sl->name_len = strlen (sl->name);
    1926         1197 :       sl->ptr_spec = &sl->ptr;
    1927         1197 :       gcc_assert (sl->ptr_spec != NULL);
    1928         1197 :       sl->default_ptr = sl->ptr;
    1929         1197 :       next = sl;
    1930              :     }
    1931              : #endif
    1932              : 
    1933        55062 :   for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    1934              :     {
    1935        53865 :       sl = &static_specs[i];
    1936        53865 :       sl->next = next;
    1937        53865 :       next = sl;
    1938              :     }
    1939              : 
    1940              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1941              :   /* ??? If neither -shared-libgcc nor --static-libgcc was
    1942              :      seen, then we should be making an educated guess.  Some proposed
    1943              :      heuristics for ELF include:
    1944              : 
    1945              :         (1) If "-Wl,--export-dynamic", then it's a fair bet that the
    1946              :             program will be doing dynamic loading, which will likely
    1947              :             need the shared libgcc.
    1948              : 
    1949              :         (2) If "-ldl", then it's also a fair bet that we're doing
    1950              :             dynamic loading.
    1951              : 
    1952              :         (3) For each ET_DYN we're linking against (either through -lfoo
    1953              :             or /some/path/foo.so), check to see whether it or one of
    1954              :             its dependencies depends on a shared libgcc.
    1955              : 
    1956              :         (4) If "-shared"
    1957              : 
    1958              :             If the runtime is fixed to look for program headers instead
    1959              :             of calling __register_frame_info at all, for each object,
    1960              :             use the shared libgcc if any EH symbol referenced.
    1961              : 
    1962              :             If crtstuff is fixed to not invoke __register_frame_info
    1963              :             automatically, for each object, use the shared libgcc if
    1964              :             any non-empty unwind section found.
    1965              : 
    1966              :      Doing any of this probably requires invoking an external program to
    1967              :      do the actual object file scanning.  */
    1968         1197 :   {
    1969         1197 :     const char *p = libgcc_spec;
    1970         1197 :     int in_sep = 1;
    1971              : 
    1972              :     /* Transform the extant libgcc_spec into one that uses the shared libgcc
    1973              :        when given the proper command line arguments.  */
    1974         2394 :     while (*p)
    1975              :       {
    1976         1197 :         if (in_sep && *p == '-' && startswith (p, "-lgcc"))
    1977              :           {
    1978         1197 :             init_gcc_specs (&obstack,
    1979              :                             "-lgcc_s"
    1980              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1981              :                             " -lunwind"
    1982              : #endif
    1983              :                             ,
    1984              :                             "-lgcc",
    1985              :                             "-lgcc_eh"
    1986              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1987              : # ifdef HAVE_LD_STATIC_DYNAMIC
    1988              :                             " %{!static:%{!static-pie:" LD_STATIC_OPTION "}} -lunwind"
    1989              :                             " %{!static:%{!static-pie:" LD_DYNAMIC_OPTION "}}"
    1990              : # else
    1991              :                             " -lunwind"
    1992              : # endif
    1993              : #endif
    1994              :                             );
    1995              : 
    1996         1197 :             p += 5;
    1997         1197 :             in_sep = 0;
    1998              :           }
    1999            0 :         else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
    2000              :           {
    2001              :             /* Ug.  We don't know shared library extensions.  Hope that
    2002              :                systems that use this form don't do shared libraries.  */
    2003            0 :             init_gcc_specs (&obstack,
    2004              :                             "-lgcc_s",
    2005              :                             "libgcc.a%s",
    2006              :                             "libgcc_eh.a%s"
    2007              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    2008              :                             " -lunwind"
    2009              : #endif
    2010              :                             );
    2011            0 :             p += 10;
    2012            0 :             in_sep = 0;
    2013              :           }
    2014              :         else
    2015              :           {
    2016            0 :             obstack_1grow (&obstack, *p);
    2017            0 :             in_sep = (*p == ' ');
    2018            0 :             p += 1;
    2019              :           }
    2020              :       }
    2021              : 
    2022         1197 :     obstack_1grow (&obstack, '\0');
    2023         1197 :     libgcc_spec = XOBFINISH (&obstack, const char *);
    2024              :   }
    2025              : #endif
    2026              : #ifdef USE_AS_TRADITIONAL_FORMAT
    2027              :   /* Prepend "--traditional-format" to whatever asm_spec we had before.  */
    2028              :   {
    2029              :     static const char tf[] = "--traditional-format ";
    2030              :     obstack_grow (&obstack, tf, sizeof (tf) - 1);
    2031              :     obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
    2032              :     asm_spec = XOBFINISH (&obstack, const char *);
    2033              :   }
    2034              : #endif
    2035              : 
    2036              : #if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC || \
    2037              :     defined LINKER_HASH_STYLE
    2038              : # ifdef LINK_BUILDID_SPEC
    2039              :   /* Prepend LINK_BUILDID_SPEC to whatever link_spec we had before.  */
    2040              :   obstack_grow (&obstack, LINK_BUILDID_SPEC, sizeof (LINK_BUILDID_SPEC) - 1);
    2041              : # endif
    2042              : # ifdef LINK_EH_SPEC
    2043              :   /* Prepend LINK_EH_SPEC to whatever link_spec we had before.  */
    2044         1197 :   obstack_grow (&obstack, LINK_EH_SPEC, sizeof (LINK_EH_SPEC) - 1);
    2045              : # endif
    2046              : # ifdef LINKER_HASH_STYLE
    2047              :   /* Prepend --hash-style=LINKER_HASH_STYLE to whatever link_spec we had
    2048              :      before.  */
    2049              :   {
    2050              :     static const char hash_style[] = "--hash-style=";
    2051              :     obstack_grow (&obstack, hash_style, sizeof (hash_style) - 1);
    2052              :     obstack_grow (&obstack, LINKER_HASH_STYLE, sizeof (LINKER_HASH_STYLE) - 1);
    2053              :     obstack_1grow (&obstack, ' ');
    2054              :   }
    2055              : # endif
    2056         1197 :   obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    2057         1197 :   link_spec = XOBFINISH (&obstack, const char *);
    2058              : #endif
    2059              : 
    2060         1197 :   specs = sl;
    2061              : }
    2062              : 
    2063              : /* Update the entry for SPEC in the static_specs table to point to VALUE,
    2064              :    ensuring that we free the previous value if necessary.  Set alloc_p for the
    2065              :    entry to ALLOC_P: this determines whether we take ownership of VALUE (i.e.
    2066              :    whether we need to free it later on).  */
    2067              : static void
    2068       215819 : set_static_spec (const char **spec, const char *value, bool alloc_p)
    2069              : {
    2070       215819 :   struct spec_list *sl = NULL;
    2071              : 
    2072      7450877 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
    2073              :     {
    2074      7450877 :       if (static_specs[i].ptr_spec == spec)
    2075              :         {
    2076       215819 :           sl = static_specs + i;
    2077       215819 :           break;
    2078              :         }
    2079              :     }
    2080              : 
    2081            0 :   gcc_assert (sl);
    2082              : 
    2083       215819 :   if (sl->alloc_p)
    2084              :     {
    2085       215819 :       const char *old = *spec;
    2086       215819 :       free (const_cast <char *> (old));
    2087              :     }
    2088              : 
    2089       215819 :   *spec = value;
    2090       215819 :   sl->alloc_p = alloc_p;
    2091       215819 : }
    2092              : 
    2093              : /* Update a static spec to a new string, taking ownership of that
    2094              :    string's memory.  */
    2095       113099 : static void set_static_spec_owned (const char **spec, const char *val)
    2096              : {
    2097            0 :   return set_static_spec (spec, val, true);
    2098              : }
    2099              : 
    2100              : /* Update a static spec to point to a new value, but don't take
    2101              :    ownership of (i.e. don't free) that string.  */
    2102       102720 : static void set_static_spec_shared (const char **spec, const char *val)
    2103              : {
    2104            0 :   return set_static_spec (spec, val, false);
    2105              : }
    2106              : 
    2107              : 
    2108              : /* Change the value of spec NAME to SPEC.  If SPEC is empty, then the spec is
    2109              :    removed; If the spec starts with a + then SPEC is added to the end of the
    2110              :    current spec.  */
    2111              : 
    2112              : static void
    2113     14333379 : set_spec (const char *name, const char *spec, bool user_p)
    2114              : {
    2115     14333379 :   struct spec_list *sl;
    2116     14333379 :   const char *old_spec;
    2117     14333379 :   int name_len = strlen (name);
    2118     14333379 :   int i;
    2119              : 
    2120              :   /* If this is the first call, initialize the statically allocated specs.  */
    2121     14333379 :   if (!specs)
    2122              :     {
    2123              :       struct spec_list *next = (struct spec_list *) 0;
    2124     14283920 :       for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    2125              :         {
    2126     13973400 :           sl = &static_specs[i];
    2127     13973400 :           sl->next = next;
    2128     13973400 :           next = sl;
    2129              :         }
    2130       310520 :       specs = sl;
    2131              :     }
    2132              : 
    2133              :   /* See if the spec already exists.  */
    2134    337275181 :   for (sl = specs; sl; sl = sl->next)
    2135    336942957 :     if (name_len == sl->name_len && !strcmp (sl->name, name))
    2136              :       break;
    2137              : 
    2138     14333379 :   if (!sl)
    2139              :     {
    2140              :       /* Not found - make it.  */
    2141       332224 :       sl = XNEW (struct spec_list);
    2142       332224 :       sl->name = xstrdup (name);
    2143       332224 :       sl->name_len = name_len;
    2144       332224 :       sl->ptr_spec = &sl->ptr;
    2145       332224 :       sl->alloc_p = 0;
    2146       332224 :       *(sl->ptr_spec) = "";
    2147       332224 :       sl->next = specs;
    2148       332224 :       sl->default_ptr = NULL;
    2149       332224 :       specs = sl;
    2150              :     }
    2151              : 
    2152     14333379 :   old_spec = *(sl->ptr_spec);
    2153     14333379 :   *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
    2154            1 :                      ? concat (old_spec, spec + 1, NULL)
    2155     14333378 :                      : xstrdup (spec));
    2156              : 
    2157              : #ifdef DEBUG_SPECS
    2158              :   if (verbose_flag)
    2159              :     fnotice (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
    2160              : #endif
    2161              : 
    2162              :   /* Free the old spec.  */
    2163     14333379 :   if (old_spec && sl->alloc_p)
    2164         6144 :     free (const_cast<char *> (old_spec));
    2165              : 
    2166     14333379 :   sl->user_p = user_p;
    2167     14333379 :   sl->alloc_p = true;
    2168     14333379 : }
    2169              : 
    2170              : /* Accumulate a command (program name and args), and run it.  */
    2171              : 
    2172              : typedef const char *const_char_p; /* For DEF_VEC_P.  */
    2173              : 
    2174              : /* Vector of pointers to arguments in the current line of specifications.  */
    2175              : static vec<const_char_p> argbuf;
    2176              : 
    2177              : /* Likewise, but for the current @file.  */
    2178              : static vec<const_char_p> at_file_argbuf;
    2179              : 
    2180              : /* Whether an @file is currently open.  */
    2181              : static bool in_at_file = false;
    2182              : 
    2183              : /* Were the options -c, -S or -E passed.  */
    2184              : static int have_c = 0;
    2185              : 
    2186              : /* Was the option -o passed.  */
    2187              : static int have_o = 0;
    2188              : 
    2189              : /* Was the option -E passed.  */
    2190              : static int have_E = 0;
    2191              : 
    2192              : /* Pointer to output file name passed in with -o. */
    2193              : static const char *output_file = 0;
    2194              : 
    2195              : /* Pointer to input file name passed in with -truncate.
    2196              :    This file should be truncated after linking. */
    2197              : static const char *totruncate_file = 0;
    2198              : 
    2199              : /* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
    2200              :    temp file.  If the HOST_BIT_BUCKET is used for %j, no entry is made for
    2201              :    it here.  */
    2202              : 
    2203              : static struct temp_name {
    2204              :   const char *suffix;   /* suffix associated with the code.  */
    2205              :   int length;           /* strlen (suffix).  */
    2206              :   int unique;           /* Indicates whether %g or %u/%U was used.  */
    2207              :   const char *filename; /* associated filename.  */
    2208              :   int filename_length;  /* strlen (filename).  */
    2209              :   struct temp_name *next;
    2210              : } *temp_names;
    2211              : 
    2212              : /* Number of commands executed so far.  */
    2213              : 
    2214              : static int execution_count;
    2215              : 
    2216              : /* Number of commands that exited with a signal.  */
    2217              : 
    2218              : static int signal_count;
    2219              : 
    2220              : /* Allocate the argument vector.  */
    2221              : 
    2222              : static void
    2223      2444633 : alloc_args (void)
    2224              : {
    2225      2444633 :   argbuf.create (10);
    2226      2444633 :   at_file_argbuf.create (10);
    2227      2444633 : }
    2228              : 
    2229              : /* Clear out the vector of arguments (after a command is executed).  */
    2230              : 
    2231              : static void
    2232      5794688 : clear_args (void)
    2233              : {
    2234      5794688 :   argbuf.truncate (0);
    2235      5794688 :   at_file_argbuf.truncate (0);
    2236      5794688 : }
    2237              : 
    2238              : /* Add one argument to the vector at the end.
    2239              :    This is done when a space is seen or at the end of the line.
    2240              :    If DELETE_ALWAYS is nonzero, the arg is a filename
    2241              :     and the file should be deleted eventually.
    2242              :    If DELETE_FAILURE is nonzero, the arg is a filename
    2243              :     and the file should be deleted if this compilation fails.  */
    2244              : 
    2245              : static void
    2246     19911415 : store_arg (const char *arg, int delete_always, int delete_failure)
    2247              : {
    2248     19911415 :   if (in_at_file)
    2249        14818 :     at_file_argbuf.safe_push (arg);
    2250              :   else
    2251     19896597 :     argbuf.safe_push (arg);
    2252              : 
    2253     19911415 :   if (delete_always || delete_failure)
    2254              :     {
    2255       538121 :       const char *p;
    2256              :       /* If the temporary file we should delete is specified as
    2257              :          part of a joined argument extract the filename.  */
    2258       538121 :       if (arg[0] == '-'
    2259       538121 :           && (p = strrchr (arg, '=')))
    2260        93514 :         arg = p + 1;
    2261       538121 :       record_temp_file (arg, delete_always, delete_failure);
    2262              :     }
    2263     19911415 : }
    2264              : 
    2265              : /* Open a temporary @file into which subsequent arguments will be stored.  */
    2266              : 
    2267              : static void
    2268        13892 : open_at_file (void)
    2269              : {
    2270        13892 :    if (in_at_file)
    2271            0 :      fatal_error (input_location, "cannot open nested response file");
    2272              :    else
    2273        13892 :      in_at_file = true;
    2274        13892 : }
    2275              : 
    2276              : /* Create a temporary @file name.  */
    2277              : 
    2278        13756 : static char *make_at_file (void)
    2279              : {
    2280        13756 :   static int fileno = 0;
    2281        13756 :   char filename[20];
    2282        13756 :   const char *base, *ext;
    2283              : 
    2284        13756 :   if (!save_temps_flag)
    2285        13718 :     return make_temp_file ("");
    2286              : 
    2287           38 :   base = dumpbase;
    2288           38 :   if (!(base && *base))
    2289           11 :     base = dumpdir;
    2290           38 :   if (!(base && *base))
    2291            0 :     base = "a";
    2292              : 
    2293           38 :   sprintf (filename, ".args.%d", fileno++);
    2294           38 :   ext = filename;
    2295              : 
    2296           38 :   if (base == dumpdir && dumpdir_trailing_dash_added)
    2297           38 :     ext++;
    2298              : 
    2299           38 :   return concat (base, ext, NULL);
    2300              : }
    2301              : 
    2302              : /* Close the temporary @file and add @file to the argument list.  */
    2303              : 
    2304              : static void
    2305        13892 : close_at_file (void)
    2306              : {
    2307        13892 :   if (!in_at_file)
    2308            0 :     fatal_error (input_location, "cannot close nonexistent response file");
    2309              : 
    2310        13892 :   in_at_file = false;
    2311              : 
    2312        13892 :   const unsigned int n_args = at_file_argbuf.length ();
    2313        13892 :   if (n_args == 0)
    2314              :     return;
    2315              : 
    2316        13756 :   char **argv = XALLOCAVEC (char *, n_args + 1);
    2317        13756 :   char *temp_file = make_at_file ();
    2318        13756 :   char *at_argument = concat ("@", temp_file, NULL);
    2319        13756 :   FILE *f = fopen (temp_file, "w");
    2320        13756 :   int status;
    2321        13756 :   unsigned int i;
    2322              : 
    2323              :   /* Copy the strings over.  */
    2324        42330 :   for (i = 0; i < n_args; i++)
    2325        14818 :     argv[i] = const_cast<char *> (at_file_argbuf[i]);
    2326        13756 :   argv[i] = NULL;
    2327              : 
    2328        13756 :   at_file_argbuf.truncate (0);
    2329              : 
    2330        13756 :   if (f == NULL)
    2331            0 :     fatal_error (input_location, "could not open temporary response file %s",
    2332              :                  temp_file);
    2333              : 
    2334        13756 :   status = writeargv (argv, f);
    2335              : 
    2336        13756 :   if (status)
    2337            0 :     fatal_error (input_location,
    2338              :                  "could not write to temporary response file %s",
    2339              :                  temp_file);
    2340              : 
    2341        13756 :   status = fclose (f);
    2342              : 
    2343        13756 :   if (status == EOF)
    2344            0 :     fatal_error (input_location, "could not close temporary response file %s",
    2345              :                  temp_file);
    2346              : 
    2347        13756 :   store_arg (at_argument, 0, 0);
    2348              : 
    2349        13756 :   record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
    2350              : }
    2351              : 
    2352              : /* Load specs from a file name named FILENAME, replacing occurrences of
    2353              :    various different types of line-endings, \r\n, \n\r and just \r, with
    2354              :    a single \n.  */
    2355              : 
    2356              : static char *
    2357       342094 : load_specs (const char *filename)
    2358              : {
    2359       342094 :   int desc;
    2360       342094 :   int readlen;
    2361       342094 :   struct stat statbuf;
    2362       342094 :   char *buffer;
    2363       342094 :   char *buffer_p;
    2364       342094 :   char *specs;
    2365       342094 :   char *specs_p;
    2366              : 
    2367       342094 :   if (verbose_flag)
    2368         1552 :     fnotice (stderr, "Reading specs from %s\n", filename);
    2369              : 
    2370              :   /* Open and stat the file.  */
    2371       342094 :   desc = open (filename, O_RDONLY, 0);
    2372       342094 :   if (desc < 0)
    2373              :     {
    2374            1 :     failed:
    2375              :       /* This leaves DESC open, but the OS will save us.  */
    2376            1 :       fatal_error (input_location, "cannot read spec file %qs: %m", filename);
    2377              :     }
    2378              : 
    2379       342093 :   if (stat (filename, &statbuf) < 0)
    2380            0 :     goto failed;
    2381              : 
    2382              :   /* Read contents of file into BUFFER.  */
    2383       342093 :   buffer = XNEWVEC (char, statbuf.st_size + 1);
    2384       342093 :   readlen = read (desc, buffer, (unsigned) statbuf.st_size);
    2385       342093 :   if (readlen < 0)
    2386            0 :     goto failed;
    2387       342093 :   buffer[readlen] = 0;
    2388       342093 :   close (desc);
    2389              : 
    2390       342093 :   specs = XNEWVEC (char, readlen + 1);
    2391       342093 :   specs_p = specs;
    2392   3122533652 :   for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
    2393              :     {
    2394   3122191559 :       int skip = 0;
    2395   3122191559 :       char c = *buffer_p;
    2396   3122191559 :       if (c == '\r')
    2397              :         {
    2398            0 :           if (buffer_p > buffer && *(buffer_p - 1) == '\n')  /* \n\r */
    2399              :             skip = 1;
    2400            0 :           else if (*(buffer_p + 1) == '\n')                     /* \r\n */
    2401              :             skip = 1;
    2402              :           else                                                  /* \r */
    2403              :             c = '\n';
    2404              :         }
    2405              :       if (! skip)
    2406   3122191559 :         *specs_p++ = c;
    2407              :     }
    2408       342093 :   *specs_p = '\0';
    2409              : 
    2410       342093 :   free (buffer);
    2411       342093 :   return (specs);
    2412              : }
    2413              : 
    2414              : /* Read compilation specs from a file named FILENAME,
    2415              :    replacing the default ones.
    2416              : 
    2417              :    A suffix which starts with `*' is a definition for
    2418              :    one of the machine-specific sub-specs.  The "suffix" should be
    2419              :    *asm, *cc1, *cpp, *link, *startfile, etc.
    2420              :    The corresponding spec is stored in asm_spec, etc.,
    2421              :    rather than in the `compilers' vector.
    2422              : 
    2423              :    Anything invalid in the file is a fatal error.  */
    2424              : 
    2425              : static void
    2426       342094 : read_specs (const char *filename, bool main_p, bool user_p)
    2427              : {
    2428       342094 :   char *buffer;
    2429       342094 :   char *p;
    2430              : 
    2431       342094 :   buffer = load_specs (filename);
    2432              : 
    2433              :   /* Scan BUFFER for specs, putting them in the vector.  */
    2434       342094 :   p = buffer;
    2435     14985992 :   while (1)
    2436              :     {
    2437     14985992 :       char *suffix;
    2438     14985992 :       char *spec;
    2439     14985992 :       char *in, *out, *p1, *p2, *p3;
    2440              : 
    2441              :       /* Advance P in BUFFER to the next nonblank nocomment line.  */
    2442     14985992 :       p = skip_whitespace (p);
    2443     14985992 :       if (*p == 0)
    2444              :         break;
    2445              : 
    2446              :       /* Is this a special command that starts with '%'? */
    2447              :       /* Don't allow this for the main specs file, since it would
    2448              :          encourage people to overwrite it.  */
    2449     14643899 :       if (*p == '%' && !main_p)
    2450              :         {
    2451       432220 :           p1 = p;
    2452       432220 :           while (*p && *p != '\n')
    2453       410609 :             p++;
    2454              : 
    2455              :           /* Skip '\n'.  */
    2456        21611 :           p++;
    2457              : 
    2458        21611 :           if (startswith (p1, "%include")
    2459        21611 :               && (p1[sizeof "%include" - 1] == ' '
    2460            0 :                   || p1[sizeof "%include" - 1] == '\t'))
    2461              :             {
    2462            0 :               char *new_filename;
    2463              : 
    2464            0 :               p1 += sizeof ("%include");
    2465            0 :               while (*p1 == ' ' || *p1 == '\t')
    2466            0 :                 p1++;
    2467              : 
    2468            0 :               if (*p1++ != '<' || p[-2] != '>')
    2469            0 :                 fatal_error (input_location,
    2470              :                              "specs %%include syntax malformed after "
    2471            0 :                              "%td characters", p1 - buffer + 1);
    2472              : 
    2473            0 :               p[-2] = '\0';
    2474            0 :               new_filename = find_a_file (&startfile_prefixes, p1, true);
    2475            0 :               read_specs (new_filename ? new_filename : p1, false, user_p);
    2476            0 :               continue;
    2477            0 :             }
    2478        21611 :           else if (startswith (p1, "%include_noerr")
    2479        21611 :                    && (p1[sizeof "%include_noerr" - 1] == ' '
    2480            0 :                        || p1[sizeof "%include_noerr" - 1] == '\t'))
    2481              :             {
    2482            0 :               char *new_filename;
    2483              : 
    2484            0 :               p1 += sizeof "%include_noerr";
    2485            0 :               while (*p1 == ' ' || *p1 == '\t')
    2486            0 :                 p1++;
    2487              : 
    2488            0 :               if (*p1++ != '<' || p[-2] != '>')
    2489            0 :                 fatal_error (input_location,
    2490              :                              "specs %%include syntax malformed after "
    2491            0 :                              "%td characters", p1 - buffer + 1);
    2492              : 
    2493            0 :               p[-2] = '\0';
    2494            0 :               new_filename = find_a_file (&startfile_prefixes, p1, true);
    2495            0 :               if (new_filename)
    2496            0 :                 read_specs (new_filename, false, user_p);
    2497            0 :               else if (verbose_flag)
    2498            0 :                 fnotice (stderr, "could not find specs file %s\n", p1);
    2499            0 :               continue;
    2500            0 :             }
    2501        21611 :           else if (startswith (p1, "%rename")
    2502        21611 :                    && (p1[sizeof "%rename" - 1] == ' '
    2503            0 :                        || p1[sizeof "%rename" - 1] == '\t'))
    2504              :             {
    2505        21611 :               int name_len;
    2506        21611 :               struct spec_list *sl;
    2507        21611 :               struct spec_list *newsl;
    2508              : 
    2509              :               /* Get original name.  */
    2510        21611 :               p1 += sizeof "%rename";
    2511        21611 :               while (*p1 == ' ' || *p1 == '\t')
    2512            0 :                 p1++;
    2513              : 
    2514        21611 :               if (! ISALPHA ((unsigned char) *p1))
    2515            0 :                 fatal_error (input_location,
    2516              :                              "specs %%rename syntax malformed after "
    2517              :                              "%td characters", p1 - buffer);
    2518              : 
    2519              :               p2 = p1;
    2520        86444 :               while (*p2 && !ISSPACE ((unsigned char) *p2))
    2521        64833 :                 p2++;
    2522              : 
    2523        21611 :               if (*p2 != ' ' && *p2 != '\t')
    2524            0 :                 fatal_error (input_location,
    2525              :                              "specs %%rename syntax malformed after "
    2526              :                              "%td characters", p2 - buffer);
    2527              : 
    2528        21611 :               name_len = p2 - p1;
    2529        21611 :               *p2++ = '\0';
    2530        21611 :               while (*p2 == ' ' || *p2 == '\t')
    2531            0 :                 p2++;
    2532              : 
    2533        21611 :               if (! ISALPHA ((unsigned char) *p2))
    2534            0 :                 fatal_error (input_location,
    2535              :                              "specs %%rename syntax malformed after "
    2536              :                              "%td characters", p2 - buffer);
    2537              : 
    2538              :               /* Get new spec name.  */
    2539              :               p3 = p2;
    2540       172888 :               while (*p3 && !ISSPACE ((unsigned char) *p3))
    2541       151277 :                 p3++;
    2542              : 
    2543        21611 :               if (p3 != p - 1)
    2544            0 :                 fatal_error (input_location,
    2545              :                              "specs %%rename syntax malformed after "
    2546              :                              "%td characters", p3 - buffer);
    2547        21611 :               *p3 = '\0';
    2548              : 
    2549       432220 :               for (sl = specs; sl; sl = sl->next)
    2550       432220 :                 if (name_len == sl->name_len && !strcmp (sl->name, p1))
    2551              :                   break;
    2552              : 
    2553        21611 :               if (!sl)
    2554            0 :                 fatal_error (input_location,
    2555              :                              "specs %s spec was not found to be renamed", p1);
    2556              : 
    2557        21611 :               if (strcmp (p1, p2) == 0)
    2558            0 :                 continue;
    2559              : 
    2560      1015717 :               for (newsl = specs; newsl; newsl = newsl->next)
    2561       994106 :                 if (strcmp (newsl->name, p2) == 0)
    2562            0 :                   fatal_error (input_location,
    2563              :                                "%s: attempt to rename spec %qs to "
    2564              :                                "already defined spec %qs",
    2565              :                     filename, p1, p2);
    2566              : 
    2567        21611 :               if (verbose_flag)
    2568              :                 {
    2569            0 :                   fnotice (stderr, "rename spec %s to %s\n", p1, p2);
    2570              : #ifdef DEBUG_SPECS
    2571              :                   fnotice (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
    2572              : #endif
    2573              :                 }
    2574              : 
    2575        21611 :               set_spec (p2, *(sl->ptr_spec), user_p);
    2576        21611 :               if (sl->alloc_p)
    2577        21611 :                 free (const_cast<char *> (*(sl->ptr_spec)));
    2578              : 
    2579        21611 :               *(sl->ptr_spec) = "";
    2580        21611 :               sl->alloc_p = 0;
    2581        21611 :               continue;
    2582        21611 :             }
    2583              :           else
    2584            0 :             fatal_error (input_location,
    2585              :                          "specs unknown %% command after %td characters",
    2586              :                          p1 - buffer);
    2587              :         }
    2588              : 
    2589              :       /* Find the colon that should end the suffix.  */
    2590              :       p1 = p;
    2591    200772822 :       while (*p1 && *p1 != ':' && *p1 != '\n')
    2592    186150534 :         p1++;
    2593              : 
    2594              :       /* The colon shouldn't be missing.  */
    2595     14622288 :       if (*p1 != ':')
    2596            0 :         fatal_error (input_location,
    2597              :                      "specs file malformed after %td characters",
    2598              :                      p1 - buffer);
    2599              : 
    2600              :       /* Skip back over trailing whitespace.  */
    2601              :       p2 = p1;
    2602     14622288 :       while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t'))
    2603            0 :         p2--;
    2604              : 
    2605              :       /* Copy the suffix to a string.  */
    2606     14622288 :       suffix = save_string (p, p2 - p);
    2607              :       /* Find the next line.  */
    2608     14622288 :       p = skip_whitespace (p1 + 1);
    2609     14622288 :       if (p[1] == 0)
    2610            0 :         fatal_error (input_location,
    2611              :                      "specs file malformed after %td characters",
    2612              :                      p - buffer);
    2613              : 
    2614              :       p1 = p;
    2615              :       /* Find next blank line or end of string.  */
    2616   2888008591 :       while (*p1 && !(*p1 == '\n' && (p1[1] == '\n' || p1[1] == '\0')))
    2617   2873386303 :         p1++;
    2618              : 
    2619              :       /* Specs end at the blank line and do not include the newline.  */
    2620     14622288 :       spec = save_string (p, p1 - p);
    2621     14622288 :       p = p1;
    2622              : 
    2623              :       /* Delete backslash-newline sequences from the spec.  */
    2624     14622288 :       in = spec;
    2625     14622288 :       out = spec;
    2626   2902630877 :       while (*in != 0)
    2627              :         {
    2628   2873386301 :           if (in[0] == '\\' && in[1] == '\n')
    2629            2 :             in += 2;
    2630   2873386299 :           else if (in[0] == '#')
    2631            0 :             while (*in && *in != '\n')
    2632            0 :               in++;
    2633              : 
    2634              :           else
    2635   2873386299 :             *out++ = *in++;
    2636              :         }
    2637     14622288 :       *out = 0;
    2638              : 
    2639     14622288 :       if (suffix[0] == '*')
    2640              :         {
    2641     14622288 :           if (! strcmp (suffix, "*link_command"))
    2642       310520 :             link_command_spec = spec;
    2643              :           else
    2644              :             {
    2645     14311768 :               set_spec (suffix + 1, spec, user_p);
    2646     14311768 :               free (spec);
    2647              :             }
    2648              :         }
    2649              :       else
    2650              :         {
    2651              :           /* Add this pair to the vector.  */
    2652            0 :           compilers
    2653            0 :             = XRESIZEVEC (struct compiler, compilers, n_compilers + 2);
    2654              : 
    2655            0 :           compilers[n_compilers].suffix = suffix;
    2656            0 :           compilers[n_compilers].spec = spec;
    2657            0 :           n_compilers++;
    2658            0 :           memset (&compilers[n_compilers], 0, sizeof compilers[n_compilers]);
    2659              :         }
    2660              : 
    2661     14622288 :       if (*suffix == 0)
    2662            0 :         link_command_spec = spec;
    2663              :     }
    2664              : 
    2665       342093 :   if (link_command_spec == 0)
    2666            0 :     fatal_error (input_location, "spec file has no spec for linking");
    2667              : 
    2668       342093 :   XDELETEVEC (buffer);
    2669       342093 : }
    2670              : 
    2671              : /* Record the names of temporary files we tell compilers to write,
    2672              :    and delete them at the end of the run.  */
    2673              : 
    2674              : /* This is the common prefix we use to make temp file names.
    2675              :    It is chosen once for each run of this program.
    2676              :    It is substituted into a spec by %g or %j.
    2677              :    Thus, all temp file names contain this prefix.
    2678              :    In practice, all temp file names start with this prefix.
    2679              : 
    2680              :    This prefix comes from the envvar TMPDIR if it is defined;
    2681              :    otherwise, from the P_tmpdir macro if that is defined;
    2682              :    otherwise, in /usr/tmp or /tmp;
    2683              :    or finally the current directory if all else fails.  */
    2684              : 
    2685              : static const char *temp_filename;
    2686              : 
    2687              : /* Length of the prefix.  */
    2688              : 
    2689              : static int temp_filename_length;
    2690              : 
    2691              : /* Define the list of temporary files to delete.  */
    2692              : 
    2693              : struct temp_file
    2694              : {
    2695              :   const char *name;
    2696              :   struct temp_file *next;
    2697              : };
    2698              : 
    2699              : /* Queue of files to delete on success or failure of compilation.  */
    2700              : static struct temp_file *always_delete_queue;
    2701              : /* Queue of files to delete on failure of compilation.  */
    2702              : static struct temp_file *failure_delete_queue;
    2703              : 
    2704              : /* Record FILENAME as a file to be deleted automatically.
    2705              :    ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
    2706              :    otherwise delete it in any case.
    2707              :    FAIL_DELETE nonzero means delete it if a compilation step fails;
    2708              :    otherwise delete it in any case.  */
    2709              : 
    2710              : void
    2711       930767 : record_temp_file (const char *filename, int always_delete, int fail_delete)
    2712              : {
    2713       930767 :   char *const name = xstrdup (filename);
    2714              : 
    2715       930767 :   if (always_delete)
    2716              :     {
    2717       749529 :       struct temp_file *temp;
    2718      1898489 :       for (temp = always_delete_queue; temp; temp = temp->next)
    2719      1319686 :         if (! filename_cmp (name, temp->name))
    2720              :           {
    2721       170726 :             free (name);
    2722       170726 :             goto already1;
    2723              :           }
    2724              : 
    2725       578803 :       temp = XNEW (struct temp_file);
    2726       578803 :       temp->next = always_delete_queue;
    2727       578803 :       temp->name = name;
    2728       578803 :       always_delete_queue = temp;
    2729              : 
    2730       930767 :     already1:;
    2731              :     }
    2732              : 
    2733       930767 :   if (fail_delete)
    2734              :     {
    2735       494884 :       struct temp_file *temp;
    2736       695795 :       for (temp = failure_delete_queue; temp; temp = temp->next)
    2737       201000 :         if (! filename_cmp (name, temp->name))
    2738              :           {
    2739           89 :             free (name);
    2740           89 :             goto already2;
    2741              :           }
    2742              : 
    2743       494795 :       temp = XNEW (struct temp_file);
    2744       494795 :       temp->next = failure_delete_queue;
    2745       494795 :       temp->name = name;
    2746       494795 :       failure_delete_queue = temp;
    2747              : 
    2748       930767 :     already2:;
    2749              :     }
    2750       930767 : }
    2751              : 
    2752              : /* Delete all the temporary files whose names we previously recorded.  */
    2753              : 
    2754              : #ifndef DELETE_IF_ORDINARY
    2755              : #define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG)        \
    2756              : do                                                      \
    2757              :   {                                                     \
    2758              :     if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode))  \
    2759              :       if (unlink (NAME) < 0)                            \
    2760              :         if (VERBOSE_FLAG)                               \
    2761              :           error ("%s: %m", (NAME));                   \
    2762              :   } while (0)
    2763              : #endif
    2764              : 
    2765              : static void
    2766       605457 : delete_if_ordinary (const char *name)
    2767              : {
    2768       605457 :   struct stat st;
    2769              : #ifdef DEBUG
    2770              :   int i, c;
    2771              : 
    2772              :   printf ("Delete %s? (y or n) ", name);
    2773              :   fflush (stdout);
    2774              :   i = getchar ();
    2775              :   if (i != '\n')
    2776              :     while ((c = getchar ()) != '\n' && c != EOF)
    2777              :       ;
    2778              : 
    2779              :   if (i == 'y' || i == 'Y')
    2780              : #endif /* DEBUG */
    2781       605457 :   DELETE_IF_ORDINARY (name, st, verbose_flag);
    2782       605457 : }
    2783              : 
    2784              : static void
    2785       606069 : delete_temp_files (void)
    2786              : {
    2787       606069 :   struct temp_file *temp;
    2788              : 
    2789      1184872 :   for (temp = always_delete_queue; temp; temp = temp->next)
    2790       578803 :     delete_if_ordinary (temp->name);
    2791       606069 :   always_delete_queue = 0;
    2792       606069 : }
    2793              : 
    2794              : /* Delete all the files to be deleted on error.  */
    2795              : 
    2796              : static void
    2797        60941 : delete_failure_queue (void)
    2798              : {
    2799        60941 :   struct temp_file *temp;
    2800              : 
    2801        87595 :   for (temp = failure_delete_queue; temp; temp = temp->next)
    2802        26654 :     delete_if_ordinary (temp->name);
    2803        60941 : }
    2804              : 
    2805              : static void
    2806       559812 : clear_failure_queue (void)
    2807              : {
    2808       559812 :   failure_delete_queue = 0;
    2809       559812 : }
    2810              : 
    2811              : /* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
    2812              :    returns non-NULL.
    2813              :    If DO_MULTI is true iterate over the paths twice, first with multilib
    2814              :    suffix then without, otherwise iterate over the paths once without
    2815              :    adding a multilib suffix.  When DO_MULTI is true, some attempt is made
    2816              :    to avoid visiting the same path twice, but we could do better.  For
    2817              :    instance, /usr/lib/../lib is considered different from /usr/lib.
    2818              :    At least EXTRA_SPACE chars past the end of the path passed to
    2819              :    CALLBACK are available for use by the callback.
    2820              :    CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
    2821              : 
    2822              :    Returns the value returned by CALLBACK.  */
    2823              : 
    2824              : template<typename fun>
    2825              : auto *
    2826      2931991 : for_each_path (const struct path_prefix *paths,
    2827              :                bool do_multi,
    2828              :                size_t extra_space,
    2829              :                fun && callback)
    2830              : {
    2831              :   struct prefix_list *pl;
    2832      2931991 :   const char *multi_dir = NULL;
    2833      2931991 :   const char *multi_os_dir = NULL;
    2834      2931991 :   const char *multiarch_suffix = NULL;
    2835              :   const char *multi_suffix;
    2836              :   const char *just_multi_suffix;
    2837      2931991 :   char *path = NULL;
    2838      2931991 :   decltype (callback (nullptr, false)) ret = nullptr;
    2839      2931991 :   bool skip_multi_dir = false;
    2840      2931991 :   bool skip_multi_os_dir = false;
    2841              : 
    2842      2931991 :   multi_suffix = machine_suffix;
    2843      2931991 :   just_multi_suffix = just_machine_suffix;
    2844      2931991 :   if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
    2845              :     {
    2846        15853 :       multi_dir = concat (multilib_dir, dir_separator_str, NULL);
    2847        15853 :       multi_suffix = concat (multi_suffix, multi_dir, NULL);
    2848        15853 :       just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
    2849              :     }
    2850      1274316 :   if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
    2851       962598 :     multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
    2852      2931991 :   if (multiarch_dir)
    2853            0 :     multiarch_suffix = concat (multiarch_dir, dir_separator_str, NULL);
    2854              : 
    2855              :   while (1)
    2856              :     {
    2857      3369141 :       size_t multi_dir_len = 0;
    2858      3369141 :       size_t multi_os_dir_len = 0;
    2859      3369141 :       size_t multiarch_len = 0;
    2860              :       size_t suffix_len;
    2861              :       size_t just_suffix_len;
    2862              :       size_t len;
    2863              : 
    2864      3369141 :       if (multi_dir)
    2865        15853 :         multi_dir_len = strlen (multi_dir);
    2866      3369141 :       if (multi_os_dir)
    2867       962598 :         multi_os_dir_len = strlen (multi_os_dir);
    2868      3369141 :       if (multiarch_suffix)
    2869            0 :         multiarch_len = strlen (multiarch_suffix);
    2870      3369141 :       suffix_len = strlen (multi_suffix);
    2871      3369141 :       just_suffix_len = strlen (just_multi_suffix);
    2872              : 
    2873      3369141 :       if (path == NULL)
    2874              :         {
    2875      2931991 :           len = paths->max_len + extra_space + 1;
    2876      2931991 :           len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len);
    2877      2931991 :           path = XNEWVEC (char, len);
    2878              :         }
    2879              : 
    2880     13161762 :       for (pl = paths->plist; pl != 0; pl = pl->next)
    2881              :         {
    2882     11525878 :           len = strlen (pl->prefix);
    2883     11525878 :           memcpy (path, pl->prefix, len);
    2884              : 
    2885              :           /* Look first in MACHINE/VERSION subdirectory.  */
    2886     11525878 :           if (!skip_multi_dir)
    2887              :             {
    2888      8427269 :               memcpy (path + len, multi_suffix, suffix_len + 1);
    2889      8427269 :               ret = callback (path, true);
    2890      5415431 :               if (ret)
    2891              :                 break;
    2892              :             }
    2893              : 
    2894              :           /* Some paths are tried with just the machine (ie. target)
    2895              :              subdir.  This is used for finding as, ld, etc.  */
    2896              :           if (!skip_multi_dir
    2897      8427269 :               && pl->require_machine_suffix == 2)
    2898              :             {
    2899            0 :               memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
    2900            0 :               ret = callback (path, true);
    2901            0 :               if (ret)
    2902              :                 break;
    2903              :             }
    2904              : 
    2905              :           /* Now try the multiarch path.  */
    2906              :           if (!skip_multi_dir
    2907      8427269 :               && !pl->require_machine_suffix && multiarch_dir)
    2908              :             {
    2909            0 :               memcpy (path + len, multiarch_suffix, multiarch_len + 1);
    2910            0 :               ret = callback (path, true);
    2911            0 :               if (ret)
    2912              :                 break;
    2913              :             }
    2914              : 
    2915              :           /* Now try the base path.  */
    2916     11525878 :           if (!pl->require_machine_suffix
    2917     18318446 :               && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
    2918              :             {
    2919              :               const char *this_multi;
    2920              :               size_t this_multi_len;
    2921              : 
    2922     10307704 :               if (pl->os_multilib)
    2923              :                 {
    2924              :                   this_multi = multi_os_dir;
    2925              :                   this_multi_len = multi_os_dir_len;
    2926              :                 }
    2927              :               else
    2928              :                 {
    2929      5574394 :                   this_multi = multi_dir;
    2930      5574394 :                   this_multi_len = multi_dir_len;
    2931              :                 }
    2932              : 
    2933     10307704 :               if (this_multi_len)
    2934      2873123 :                 memcpy (path + len, this_multi, this_multi_len + 1);
    2935              :               else
    2936      7434581 :                 path[len] = '\0';
    2937              : 
    2938     10307704 :               ret = callback (path, false);
    2939      6093975 :               if (ret)
    2940              :                 break;
    2941              :             }
    2942              :         }
    2943      2579787 :       if (pl)
    2944              :         break;
    2945              : 
    2946      1635884 :       if (multi_dir == NULL && multi_os_dir == NULL)
    2947              :         break;
    2948              : 
    2949              :       /* Run through the paths again, this time without multilibs.
    2950              :          Don't repeat any we have already seen.  */
    2951       437150 :       if (multi_dir)
    2952              :         {
    2953        10156 :           free (const_cast<char *> (multi_dir));
    2954        10156 :           multi_dir = NULL;
    2955        10156 :           free (const_cast<char *> (multi_suffix));
    2956        10156 :           multi_suffix = machine_suffix;
    2957        10156 :           free (const_cast<char *> (just_multi_suffix));
    2958        10156 :           just_multi_suffix = just_machine_suffix;
    2959              :         }
    2960              :       else
    2961              :         skip_multi_dir = true;
    2962       437150 :       if (multi_os_dir)
    2963              :         {
    2964       437150 :           free (const_cast<char *> (multi_os_dir));
    2965       437150 :           multi_os_dir = NULL;
    2966              :         }
    2967              :       else
    2968              :         skip_multi_os_dir = true;
    2969              :     }
    2970              : 
    2971      2931991 :   if (multi_dir)
    2972              :     {
    2973         5697 :       free (const_cast<char *> (multi_dir));
    2974         5697 :       free (const_cast<char *> (multi_suffix));
    2975         5697 :       free (const_cast<char *> (just_multi_suffix));
    2976              :     }
    2977      2931991 :   if (multi_os_dir)
    2978       525448 :     free (const_cast<char *> (multi_os_dir));
    2979      2405755 :   if (ret != path)
    2980      1198734 :     free (path);
    2981      2931991 :   return ret;
    2982              : }
    2983              : 
    2984              : /* Add or change the value of an environment variable, outputting the
    2985              :    change to standard error if in verbose mode.  */
    2986              : static void
    2987      1832069 : xputenv (const char *string)
    2988              : {
    2989            0 :   env.xput (string);
    2990       142665 : }
    2991              : 
    2992              : /* Build a list of search directories from PATHS.
    2993              :    PREFIX is a string to prepend to the list.
    2994              :    If CHECK_DIR_P is true we ensure the directory exists.
    2995              :    If DO_MULTI is true, multilib paths are output first, then
    2996              :    non-multilib paths.
    2997              :    This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
    2998              :    It is also used by the --print-search-dirs flag.  */
    2999              : 
    3000              : static char *
    3001       526236 : build_search_list (const struct path_prefix *paths, const char *prefix,
    3002              :                    bool check_dir, bool do_multi)
    3003              : {
    3004       526236 :   struct obstack *const ob = &collect_obstack;
    3005       526236 :   bool first_time = true;
    3006              : 
    3007       526236 :   obstack_grow (&collect_obstack, prefix, strlen (prefix));
    3008       526236 :   obstack_1grow (&collect_obstack, '=');
    3009              : 
    3010              :   /* Callback adds path to obstack being built.  */
    3011       526236 :   for_each_path (paths, do_multi, 0, [&](char *path, bool) -> void*
    3012              :     {
    3013      7225567 :       if (check_dir && !is_directory (path))
    3014              :         return NULL;
    3015              : 
    3016      2668735 :       if (!first_time)
    3017      2143643 :         obstack_1grow (ob, PATH_SEPARATOR);
    3018              : 
    3019      2668735 :       obstack_grow (ob, path, strlen (path));
    3020              : 
    3021      2668735 :       first_time = false;
    3022      2668735 :       return NULL;
    3023              :     });
    3024              : 
    3025       526236 :   obstack_1grow (&collect_obstack, '\0');
    3026       526236 :   return XOBFINISH (&collect_obstack, char *);
    3027              : }
    3028              : 
    3029              : /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    3030              :    for collect.  */
    3031              : 
    3032              : static void
    3033       526180 : putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
    3034              :                       bool do_multi)
    3035              : {
    3036       526180 :   xputenv (build_search_list (paths, env_var, true, do_multi));
    3037       526180 : }
    3038              : 
    3039              : /* Check whether NAME can be accessed in MODE.  This is like access,
    3040              :    except that it never considers directories to be executable.  */
    3041              : 
    3042              : static int
    3043      8866700 : access_check (const char *name, int mode)
    3044              : {
    3045      2351046 :   if (mode == X_OK)
    3046              :     {
    3047      2351046 :       struct stat st;
    3048              : 
    3049      2351046 :       if (stat (name, &st) < 0
    3050      2351046 :           || S_ISDIR (st.st_mode))
    3051      1580391 :         return -1;
    3052              :     }
    3053              : 
    3054       770655 :   return access (name, mode);
    3055              : }
    3056              : 
    3057              : 
    3058              : /* Search for NAME using the prefix list PREFIXES.  MODE is passed to
    3059              :    access to check permissions.  If DO_MULTI is true, search multilib
    3060              :    paths then non-multilib paths, otherwise do not search multilib paths.
    3061              :    Return 0 if not found, otherwise return its name, allocated with malloc.  */
    3062              : 
    3063              : static char *
    3064      1059103 : find_a_file (const struct path_prefix *pprefix, const char *name,
    3065              :              bool do_multi)
    3066              : {
    3067              :   /* Find the filename in question (special case for absolute paths).  */
    3068              : 
    3069      1059103 :   if (IS_ABSOLUTE_PATH (name))
    3070              :     {
    3071            1 :       if (access (name, R_OK) == 0)
    3072            1 :         return xstrdup (name);
    3073              : 
    3074              :       return NULL;
    3075              :     }
    3076              : 
    3077      1059102 :   const int name_len = strlen (name);
    3078              : 
    3079              : 
    3080              :   /* Callback appends the file name to the directory path.  If the
    3081              :      resulting file exists in the right mode, return the full pathname
    3082              :      to the file.  */
    3083      1059102 :   return for_each_path (pprefix, do_multi,
    3084              :                         name_len,
    3085      1059102 :                         [=](char *path, bool) -> char*
    3086              :     {
    3087      6515654 :       memcpy (path + strlen (path), name, name_len + 1);
    3088              : 
    3089      6515654 :       if (access_check (path, R_OK) == 0)
    3090       962602 :         return path;
    3091              : 
    3092              :       return NULL;
    3093              :     });
    3094              : }
    3095              : 
    3096              : /* Specialization of find_a_file for programs that also takes into account
    3097              :    configure-specified default programs. */
    3098              : 
    3099              : static char*
    3100       776857 : find_a_program (const char *name)
    3101              : {
    3102              :   /* Do not search if default matches query. */
    3103              : 
    3104              : #ifdef DEFAULT_ASSEMBLER
    3105              :   if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, X_OK) == 0)
    3106              :     return xstrdup (DEFAULT_ASSEMBLER);
    3107              : #endif
    3108              : 
    3109              : #ifdef DEFAULT_LINKER
    3110              :   if (! strcmp (name, "ld") && access (DEFAULT_LINKER, X_OK) == 0)
    3111              :     return xstrdup (DEFAULT_LINKER);
    3112              : #endif
    3113              : 
    3114              : #ifdef DEFAULT_DSYMUTIL
    3115              :   if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, X_OK) == 0)
    3116              :     return xstrdup (DEFAULT_DSYMUTIL);
    3117              : #endif
    3118              : 
    3119              : #ifdef DEFAULT_WINDRES
    3120              :   if (! strcmp (name, "windres") && access (DEFAULT_WINDRES, X_OK) == 0)
    3121              :     return xstrdup (DEFAULT_WINDRES);
    3122              : #endif
    3123              : 
    3124              :   /* Find the filename in question (special case for absolute paths).  */
    3125              : 
    3126       776857 :   if (IS_ABSOLUTE_PATH (name))
    3127              :     {
    3128            0 :       if (access (name, X_OK) == 0)
    3129            0 :         return xstrdup (name);
    3130              : 
    3131              :       return NULL;
    3132              :     }
    3133              : 
    3134       776857 :   const char *suffix = HOST_EXECUTABLE_SUFFIX;
    3135       776857 :   const int name_len = strlen (name);
    3136       776857 :   const int prefix_len = strlen (just_machine_prefix);
    3137       776857 :   const int suffix_len = strlen (suffix);
    3138              : 
    3139              :   /* Callback appends the file name to the directory path.  If the
    3140              :      resulting file exists in the right mode, return the full pathname
    3141              :      to the file.  */
    3142       776857 :   return for_each_path (&exec_prefixes, false,
    3143       776857 :                         prefix_len + name_len + suffix_len,
    3144       776857 :                         [=](char *path, bool machine_specific) -> char*
    3145              :     {
    3146      1567364 :       size_t path_len = strlen (path);
    3147              : 
    3148      3918410 :       auto search = [=](size_t len) -> char*
    3149              :         {
    3150      2351046 :           memcpy (path + len, name, name_len + 1);
    3151      2351046 :           len += name_len;
    3152              : 
    3153              :           /* Some systems have a suffix for executable files.
    3154              :              So try appending that first.  */
    3155      2351046 :           if (suffix_len)
    3156              :             {
    3157            0 :               memcpy (path + len, suffix, suffix_len + 1);
    3158            0 :               if (access_check (path, X_OK) == 0)
    3159            0 :                 return path;
    3160              :             }
    3161              : 
    3162      2351046 :           path[len] = '\0';
    3163      2351046 :           if (access_check (path, X_OK) == 0)
    3164       770655 :             return path;
    3165              : 
    3166              :           return NULL;
    3167      1567364 :         };
    3168              : 
    3169              :       /* Additionally search for $target-prog in machine-agnostic dirs,
    3170              :          as an additional way to disambiguate targets. Do not do this in
    3171              :          machine-specific dirs because so further disambiguation is
    3172              :          needed. */
    3173      1567364 :       if (!machine_specific)
    3174              :         {
    3175       783682 :           memcpy (path + path_len, just_machine_prefix, prefix_len);
    3176       783682 :           auto ret = search(path_len + prefix_len);
    3177       783682 :           if (ret)
    3178              :             return ret;
    3179              :         }
    3180              : 
    3181      1567364 :       return search(path_len);
    3182              :     });
    3183              : }
    3184              : 
    3185              : /* Ranking of prefixes in the sort list. -B prefixes are put before
    3186              :    all others.  */
    3187              : 
    3188              : enum path_prefix_priority
    3189              : {
    3190              :   PREFIX_PRIORITY_B_OPT,
    3191              :   PREFIX_PRIORITY_LAST
    3192              : };
    3193              : 
    3194              : /* Add an entry for PREFIX in PLIST.  The PLIST is kept in ascending
    3195              :    order according to PRIORITY.  Within each PRIORITY, new entries are
    3196              :    appended.
    3197              : 
    3198              :    If WARN is nonzero, we will warn if no file is found
    3199              :    through this prefix.  WARN should point to an int
    3200              :    which will be set to 1 if this entry is used.
    3201              : 
    3202              :    COMPONENT is the value to be passed to update_path.
    3203              : 
    3204              :    REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
    3205              :    the complete value of machine_suffix.
    3206              :    2 means try both machine_suffix and just_machine_suffix.  */
    3207              : 
    3208              : static void
    3209      4050902 : add_prefix (struct path_prefix *pprefix, const char *prefix,
    3210              :             const char *component, /* enum prefix_priority */ int priority,
    3211              :             int require_machine_suffix, int os_multilib)
    3212              : {
    3213      4050902 :   struct prefix_list *pl, **prev;
    3214      4050902 :   int len;
    3215              : 
    3216      4050902 :   for (prev = &pprefix->plist;
    3217     12823102 :        (*prev) != NULL && (*prev)->priority <= priority;
    3218      8772200 :        prev = &(*prev)->next)
    3219              :     ;
    3220              : 
    3221              :   /* Keep track of the longest prefix.  */
    3222              : 
    3223      4050902 :   prefix = update_path (prefix, component);
    3224      4050902 :   len = strlen (prefix);
    3225      4050902 :   if (len > pprefix->max_len)
    3226      2201984 :     pprefix->max_len = len;
    3227              : 
    3228      4050902 :   pl = XNEW (struct prefix_list);
    3229      4050902 :   pl->prefix = prefix;
    3230      4050902 :   pl->require_machine_suffix = require_machine_suffix;
    3231      4050902 :   pl->priority = priority;
    3232      4050902 :   pl->os_multilib = os_multilib;
    3233              : 
    3234              :   /* Insert after PREV.  */
    3235      4050902 :   pl->next = (*prev);
    3236      4050902 :   (*prev) = pl;
    3237      4050902 : }
    3238              : 
    3239              : /* Same as add_prefix, but prepending target_system_root to prefix.  */
    3240              : /* The target_system_root prefix has been relocated by gcc_exec_prefix.  */
    3241              : static void
    3242       623432 : add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
    3243              :                       const char *component,
    3244              :                       /* enum prefix_priority */ int priority,
    3245              :                       int require_machine_suffix, int os_multilib)
    3246              : {
    3247       623432 :   if (!IS_ABSOLUTE_PATH (prefix))
    3248            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3249              : 
    3250       623432 :   if (target_system_root)
    3251              :     {
    3252            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3253            0 :       size_t sysroot_len = strlen (target_system_root);
    3254              : 
    3255            0 :       if (sysroot_len > 0
    3256            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3257            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3258              : 
    3259            0 :       if (target_sysroot_suffix)
    3260            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3261              :                          target_sysroot_suffix, prefix, NULL);
    3262              :       else
    3263            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3264              : 
    3265            0 :       free (sysroot_no_trailing_dir_separator);
    3266              : 
    3267              :       /* We have to override this because GCC's notion of sysroot
    3268              :          moves along with GCC.  */
    3269            0 :       component = "GCC";
    3270              :     }
    3271              : 
    3272       623432 :   add_prefix (pprefix, prefix, component, priority,
    3273              :               require_machine_suffix, os_multilib);
    3274       623432 : }
    3275              : 
    3276              : /* Same as add_prefix, but prepending target_sysroot_hdrs_suffix to prefix.  */
    3277              : 
    3278              : static void
    3279        31763 : add_sysrooted_hdrs_prefix (struct path_prefix *pprefix, const char *prefix,
    3280              :                            const char *component,
    3281              :                            /* enum prefix_priority */ int priority,
    3282              :                            int require_machine_suffix, int os_multilib)
    3283              : {
    3284        31763 :   if (!IS_ABSOLUTE_PATH (prefix))
    3285            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3286              : 
    3287        31763 :   if (target_system_root)
    3288              :     {
    3289            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3290            0 :       size_t sysroot_len = strlen (target_system_root);
    3291              : 
    3292            0 :       if (sysroot_len > 0
    3293            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3294            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3295              : 
    3296            0 :       if (target_sysroot_hdrs_suffix)
    3297            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3298              :                          target_sysroot_hdrs_suffix, prefix, NULL);
    3299              :       else
    3300            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3301              : 
    3302            0 :       free (sysroot_no_trailing_dir_separator);
    3303              : 
    3304              :       /* We have to override this because GCC's notion of sysroot
    3305              :          moves along with GCC.  */
    3306            0 :       component = "GCC";
    3307              :     }
    3308              : 
    3309        31763 :   add_prefix (pprefix, prefix, component, priority,
    3310              :               require_machine_suffix, os_multilib);
    3311        31763 : }
    3312              : 
    3313              : 
    3314              : /* Execute the command specified by the arguments on the current line of spec.
    3315              :    When using pipes, this includes several piped-together commands
    3316              :    with `|' between them.
    3317              : 
    3318              :    Return 0 if successful, -1 if failed.  */
    3319              : 
    3320              : static int
    3321       563056 : execute (void)
    3322              : {
    3323       563056 :   int i;
    3324       563056 :   int n_commands;               /* # of command.  */
    3325       563056 :   char *string;
    3326       563056 :   struct pex_obj *pex;
    3327       563056 :   struct command
    3328              :   {
    3329              :     const char *prog;           /* program name.  */
    3330              :     const char **argv;          /* vector of args.  */
    3331              :   };
    3332       563056 :   const char *arg;
    3333              : 
    3334       563056 :   struct command *commands;     /* each command buffer with above info.  */
    3335              : 
    3336       563056 :   gcc_assert (!processing_spec_function);
    3337              : 
    3338       563056 :   if (wrapper_string)
    3339              :     {
    3340            0 :       string = find_a_program (argbuf[0]);
    3341            0 :       if (string)
    3342            0 :         argbuf[0] = string;
    3343            0 :       insert_wrapper (wrapper_string);
    3344              :     }
    3345              : 
    3346              :   /* Count # of piped commands.  */
    3347     17238921 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3348     16675865 :     if (strcmp (arg, "|") == 0)
    3349            0 :       n_commands++;
    3350              : 
    3351              :   /* Get storage for each command.  */
    3352       563056 :   commands = XALLOCAVEC (struct command, n_commands);
    3353              : 
    3354              :   /* Split argbuf into its separate piped processes,
    3355              :      and record info about each one.
    3356              :      Also search for the programs that are to be run.  */
    3357              : 
    3358       563056 :   argbuf.safe_push (0);
    3359              : 
    3360       563056 :   commands[0].prog = argbuf[0]; /* first command.  */
    3361       563056 :   commands[0].argv = argbuf.address ();
    3362              : 
    3363       563056 :   if (!wrapper_string)
    3364              :     {
    3365       563056 :       string = find_a_program(commands[0].prog);
    3366       563056 :       if (string)
    3367       560401 :         commands[0].argv[0] = string;
    3368              :     }
    3369              : 
    3370     17801977 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3371     17238921 :     if (arg && strcmp (arg, "|") == 0)
    3372              :       {                         /* each command.  */
    3373              : #if defined (__MSDOS__) || defined (OS2) || defined (VMS)
    3374              :         fatal_error (input_location, "%<-pipe%> not supported");
    3375              : #endif
    3376            0 :         argbuf[i] = 0; /* Termination of command args.  */
    3377            0 :         commands[n_commands].prog = argbuf[i + 1];
    3378            0 :         commands[n_commands].argv
    3379            0 :           = &(argbuf.address ())[i + 1];
    3380            0 :         string = find_a_program(commands[n_commands].prog);
    3381            0 :         if (string)
    3382            0 :           commands[n_commands].argv[0] = string;
    3383            0 :         n_commands++;
    3384              :       }
    3385              : 
    3386              :   /* If -v, print what we are about to do, and maybe query.  */
    3387              : 
    3388       563056 :   if (verbose_flag)
    3389              :     {
    3390              :       /* For help listings, put a blank line between sub-processes.  */
    3391         1522 :       if (print_help_list)
    3392            9 :         fputc ('\n', stderr);
    3393              : 
    3394              :       /* Print each piped command as a separate line.  */
    3395         3044 :       for (i = 0; i < n_commands; i++)
    3396              :         {
    3397         1522 :           const char *const *j;
    3398              : 
    3399         1522 :           if (verbose_only_flag)
    3400              :             {
    3401        17904 :               for (j = commands[i].argv; *j; j++)
    3402              :                 {
    3403              :                   const char *p;
    3404       427623 :                   for (p = *j; *p; ++p)
    3405       413226 :                     if (!ISALNUM ((unsigned char) *p)
    3406        97811 :                         && *p != '_' && *p != '/' && *p != '-' && *p != '.')
    3407              :                       break;
    3408        16887 :                   if (*p || !*j)
    3409              :                     {
    3410         2490 :                       fprintf (stderr, " \"");
    3411       129656 :                       for (p = *j; *p; ++p)
    3412              :                         {
    3413       127166 :                           if (*p == '"' || *p == '\\' || *p == '$')
    3414            0 :                             fputc ('\\', stderr);
    3415       127166 :                           fputc (*p, stderr);
    3416              :                         }
    3417         2490 :                       fputc ('"', stderr);
    3418              :                     }
    3419              :                   /* If it's empty, print "".  */
    3420        14397 :                   else if (!**j)
    3421            0 :                     fprintf (stderr, " \"\"");
    3422              :                   else
    3423        14397 :                     fprintf (stderr, " %s", *j);
    3424              :                 }
    3425              :             }
    3426              :           else
    3427        18415 :             for (j = commands[i].argv; *j; j++)
    3428              :               /* If it's empty, print "".  */
    3429        17910 :               if (!**j)
    3430            0 :                 fprintf (stderr, " \"\"");
    3431              :               else
    3432        17910 :                 fprintf (stderr, " %s", *j);
    3433              : 
    3434              :           /* Print a pipe symbol after all but the last command.  */
    3435         1522 :           if (i + 1 != n_commands)
    3436            0 :             fprintf (stderr, " |");
    3437         1522 :           fprintf (stderr, "\n");
    3438              :         }
    3439         1522 :       fflush (stderr);
    3440         1522 :       if (verbose_only_flag != 0)
    3441              :         {
    3442              :           /* verbose_only_flag should act as if the spec was
    3443              :              executed, so increment execution_count before
    3444              :              returning.  This prevents spurious warnings about
    3445              :              unused linker input files, etc.  */
    3446         1017 :           execution_count++;
    3447         1017 :           return 0;
    3448              :         }
    3449              : #ifdef DEBUG
    3450              :       fnotice (stderr, "\nGo ahead? (y or n) ");
    3451              :       fflush (stderr);
    3452              :       i = getchar ();
    3453              :       if (i != '\n')
    3454              :         while (getchar () != '\n')
    3455              :           ;
    3456              : 
    3457              :       if (i != 'y' && i != 'Y')
    3458              :         return 0;
    3459              : #endif /* DEBUG */
    3460              :     }
    3461              : 
    3462              : #ifdef ENABLE_VALGRIND_CHECKING
    3463              :   /* Run the each command through valgrind.  To simplify prepending the
    3464              :      path to valgrind and the option "-q" (for quiet operation unless
    3465              :      something triggers), we allocate a separate argv array.  */
    3466              : 
    3467              :   for (i = 0; i < n_commands; i++)
    3468              :     {
    3469              :       const char **argv;
    3470              :       int argc;
    3471              :       int j;
    3472              : 
    3473              :       for (argc = 0; commands[i].argv[argc] != NULL; argc++)
    3474              :         ;
    3475              : 
    3476              :       argv = XALLOCAVEC (const char *, argc + 3);
    3477              : 
    3478              :       argv[0] = VALGRIND_PATH;
    3479              :       argv[1] = "-q";
    3480              :       for (j = 2; j < argc + 2; j++)
    3481              :         argv[j] = commands[i].argv[j - 2];
    3482              :       argv[j] = NULL;
    3483              : 
    3484              :       commands[i].argv = argv;
    3485              :       commands[i].prog = argv[0];
    3486              :     }
    3487              : #endif
    3488              : 
    3489              :   /* Run each piped subprocess.  */
    3490              : 
    3491       562039 :   pex = pex_init (PEX_USE_PIPES | ((report_times || report_times_to_file)
    3492              :                                    ? PEX_RECORD_TIMES : 0),
    3493              :                   progname, temp_filename);
    3494       562039 :   if (pex == NULL)
    3495              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    3496              : 
    3497      1124078 :   for (i = 0; i < n_commands; i++)
    3498              :     {
    3499       562039 :       const char *errmsg;
    3500       562039 :       int err;
    3501       562039 :       const char *string = commands[i].argv[0];
    3502              : 
    3503       562039 :       errmsg = pex_run (pex,
    3504       562039 :                         ((i + 1 == n_commands ? PEX_LAST : 0)
    3505       562039 :                          | (string == commands[i].prog ? PEX_SEARCH : 0)),
    3506              :                         string, const_cast<char **> (commands[i].argv),
    3507              :                         NULL, NULL, &err);
    3508       562039 :       if (errmsg != NULL)
    3509              :         {
    3510            0 :           errno = err;
    3511            0 :           fatal_error (input_location,
    3512              :                        err ? G_("cannot execute %qs: %s: %m")
    3513              :                        : G_("cannot execute %qs: %s"),
    3514              :                        string, errmsg);
    3515              :         }
    3516              : 
    3517       562039 :       if (i && string != commands[i].prog)
    3518            0 :         free (const_cast<char *> (string));
    3519              :     }
    3520              : 
    3521       562039 :   execution_count++;
    3522              : 
    3523              :   /* Wait for all the subprocesses to finish.  */
    3524              : 
    3525       562039 :   {
    3526       562039 :     int *statuses;
    3527       562039 :     struct pex_time *times = NULL;
    3528       562039 :     int ret_code = 0;
    3529              : 
    3530       562039 :     statuses = XALLOCAVEC (int, n_commands);
    3531       562039 :     if (!pex_get_status (pex, n_commands, statuses))
    3532            0 :       fatal_error (input_location, "failed to get exit status: %m");
    3533              : 
    3534       562039 :     if (report_times || report_times_to_file)
    3535              :       {
    3536            0 :         times = XALLOCAVEC (struct pex_time, n_commands);
    3537            0 :         if (!pex_get_times (pex, n_commands, times))
    3538            0 :           fatal_error (input_location, "failed to get process times: %m");
    3539              :       }
    3540              : 
    3541       562039 :     pex_free (pex);
    3542              : 
    3543      1124078 :     for (i = 0; i < n_commands; ++i)
    3544              :       {
    3545       562039 :         int status = statuses[i];
    3546              : 
    3547       562039 :         if (WIFSIGNALED (status))
    3548            0 :           switch (WTERMSIG (status))
    3549              :             {
    3550            0 :             case SIGINT:
    3551            0 :             case SIGTERM:
    3552              :               /* SIGQUIT and SIGKILL are not available on MinGW.  */
    3553              : #ifdef SIGQUIT
    3554            0 :             case SIGQUIT:
    3555              : #endif
    3556              : #ifdef SIGKILL
    3557            0 :             case SIGKILL:
    3558              : #endif
    3559              :               /* The user (or environment) did something to the
    3560              :                  inferior.  Making this an ICE confuses the user into
    3561              :                  thinking there's a compiler bug.  Much more likely is
    3562              :                  the user or OOM killer nuked it.  */
    3563            0 :               fatal_error (input_location,
    3564              :                            "%s signal terminated program %s",
    3565              :                            strsignal (WTERMSIG (status)),
    3566            0 :                            commands[i].prog);
    3567            0 :               break;
    3568              : 
    3569              : #ifdef SIGPIPE
    3570            0 :             case SIGPIPE:
    3571              :               /* SIGPIPE is a special case.  It happens in -pipe mode
    3572              :                  when the compiler dies before the preprocessor is
    3573              :                  done, or the assembler dies before the compiler is
    3574              :                  done.  There's generally been an error already, and
    3575              :                  this is just fallout.  So don't generate another
    3576              :                  error unless we would otherwise have succeeded.  */
    3577            0 :               if (signal_count || greatest_status >= MIN_FATAL_STATUS)
    3578              :                 {
    3579            0 :                   signal_count++;
    3580            0 :                   ret_code = -1;
    3581            0 :                   break;
    3582              :                 }
    3583              : #endif
    3584              :               /* FALLTHROUGH */
    3585              : 
    3586            0 :             default:
    3587              :               /* The inferior failed to catch the signal.  */
    3588            0 :               internal_error_no_backtrace ("%s signal terminated program %s",
    3589              :                                            strsignal (WTERMSIG (status)),
    3590            0 :                                            commands[i].prog);
    3591              :             }
    3592       562039 :         else if (WIFEXITED (status)
    3593       562039 :                  && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
    3594              :           {
    3595              :             /* For ICEs in cc1, cc1obj, cc1plus see if it is
    3596              :                reproducible or not.  */
    3597        30522 :             const char *p;
    3598        30522 :             if (flag_report_bug
    3599            0 :                 && WEXITSTATUS (status) == ICE_EXIT_CODE
    3600            0 :                 && i == 0
    3601            0 :                 && (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
    3602        30522 :                 && startswith (p + 1, "cc1"))
    3603            0 :               try_generate_repro (commands[0].argv);
    3604        30522 :             if (WEXITSTATUS (status) > greatest_status)
    3605           23 :               greatest_status = WEXITSTATUS (status);
    3606              :             ret_code = -1;
    3607              :           }
    3608              : 
    3609       562039 :         if (report_times || report_times_to_file)
    3610              :           {
    3611            0 :             struct pex_time *pt = &times[i];
    3612            0 :             double ut, st;
    3613              : 
    3614            0 :             ut = ((double) pt->user_seconds
    3615            0 :                   + (double) pt->user_microseconds / 1.0e6);
    3616            0 :             st = ((double) pt->system_seconds
    3617            0 :                   + (double) pt->system_microseconds / 1.0e6);
    3618              : 
    3619            0 :             if (ut + st != 0)
    3620              :               {
    3621            0 :                 if (report_times)
    3622            0 :                   fnotice (stderr, "# %s %.2f %.2f\n",
    3623            0 :                            commands[i].prog, ut, st);
    3624              : 
    3625            0 :                 if (report_times_to_file)
    3626              :                   {
    3627            0 :                     int c = 0;
    3628            0 :                     const char *const *j;
    3629              : 
    3630            0 :                     fprintf (report_times_to_file, "%g %g", ut, st);
    3631              : 
    3632            0 :                     for (j = &commands[i].prog; *j; j = &commands[i].argv[++c])
    3633              :                       {
    3634              :                         const char *p;
    3635            0 :                         for (p = *j; *p; ++p)
    3636            0 :                           if (*p == '"' || *p == '\\' || *p == '$'
    3637            0 :                               || ISSPACE (*p))
    3638              :                             break;
    3639              : 
    3640            0 :                         if (*p)
    3641              :                           {
    3642            0 :                             fprintf (report_times_to_file, " \"");
    3643            0 :                             for (p = *j; *p; ++p)
    3644              :                               {
    3645            0 :                                 if (*p == '"' || *p == '\\' || *p == '$')
    3646            0 :                                   fputc ('\\', report_times_to_file);
    3647            0 :                                 fputc (*p, report_times_to_file);
    3648              :                               }
    3649            0 :                             fputc ('"', report_times_to_file);
    3650              :                           }
    3651              :                         else
    3652            0 :                           fprintf (report_times_to_file, " %s", *j);
    3653              :                       }
    3654              : 
    3655            0 :                     fputc ('\n', report_times_to_file);
    3656              :                   }
    3657              :               }
    3658              :           }
    3659              :       }
    3660              : 
    3661       562039 :    if (commands[0].argv[0] != commands[0].prog)
    3662       559384 :      free (const_cast<char *> (commands[0].argv[0]));
    3663              : 
    3664              :     return ret_code;
    3665              :   }
    3666              : }
    3667              : 
    3668              : static struct switchstr *switches;
    3669              : 
    3670              : static int n_switches;
    3671              : 
    3672              : static int n_switches_alloc;
    3673              : 
    3674              : /* Set to zero if -fcompare-debug is disabled, positive if it's
    3675              :    enabled and we're running the first compilation, negative if it's
    3676              :    enabled and we're running the second compilation.  For most of the
    3677              :    time, it's in the range -1..1, but it can be temporarily set to 2
    3678              :    or 3 to indicate that the -fcompare-debug flags didn't come from
    3679              :    the command-line, but rather from the GCC_COMPARE_DEBUG environment
    3680              :    variable, until a synthesized -fcompare-debug flag is added to the
    3681              :    command line.  */
    3682              : int compare_debug;
    3683              : 
    3684              : /* Set to nonzero if we've seen the -fcompare-debug-second flag.  */
    3685              : int compare_debug_second;
    3686              : 
    3687              : /* Set to the flags that should be passed to the second compilation in
    3688              :    a -fcompare-debug compilation.  */
    3689              : const char *compare_debug_opt;
    3690              : 
    3691              : static struct switchstr *switches_debug_check[2];
    3692              : 
    3693              : static int n_switches_debug_check[2];
    3694              : 
    3695              : static int n_switches_alloc_debug_check[2];
    3696              : 
    3697              : static char *debug_check_temp_file[2];
    3698              : 
    3699              : /* Language is one of three things:
    3700              : 
    3701              :    1) The name of a real programming language.
    3702              :    2) NULL, indicating that no one has figured out
    3703              :    what it is yet.
    3704              :    3) '*', indicating that the file should be passed
    3705              :    to the linker.  */
    3706              : struct infile
    3707              : {
    3708              :   const char *name;
    3709              :   const char *language;
    3710              :   struct compiler *incompiler;
    3711              :   bool compiled;
    3712              :   bool preprocessed;
    3713              :   bool artificial;
    3714              : };
    3715              : 
    3716              : /* Also a vector of input files specified.  */
    3717              : 
    3718              : static struct infile *infiles;
    3719              : 
    3720              : int n_infiles;
    3721              : 
    3722              : static int n_infiles_alloc;
    3723              : 
    3724              : /* True if undefined environment variables encountered during spec processing
    3725              :    are ok to ignore, typically when we're running for --help or --version.  */
    3726              : 
    3727              : static bool spec_undefvar_allowed;
    3728              : 
    3729              : /* True if multiple input files are being compiled to a single
    3730              :    assembly file.  */
    3731              : 
    3732              : static bool combine_inputs;
    3733              : 
    3734              : /* This counts the number of libraries added by lang_specific_driver, so that
    3735              :    we can tell if there were any user supplied any files or libraries.  */
    3736              : 
    3737              : static int added_libraries;
    3738              : 
    3739              : /* And a vector of corresponding output files is made up later.  */
    3740              : 
    3741              : const char **outfiles;
    3742              : 
    3743              : #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3744              : 
    3745              : /* Convert NAME to a new name if it is the standard suffix.  DO_EXE
    3746              :    is true if we should look for an executable suffix.  DO_OBJ
    3747              :    is true if we should look for an object suffix.  */
    3748              : 
    3749              : static const char *
    3750              : convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
    3751              :                   int do_obj ATTRIBUTE_UNUSED)
    3752              : {
    3753              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3754              :   int i;
    3755              : #endif
    3756              :   int len;
    3757              : 
    3758              :   if (name == NULL)
    3759              :     return NULL;
    3760              : 
    3761              :   len = strlen (name);
    3762              : 
    3763              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    3764              :   /* Convert x.o to x.obj if TARGET_OBJECT_SUFFIX is ".obj".  */
    3765              :   if (do_obj && len > 2
    3766              :       && name[len - 2] == '.'
    3767              :       && name[len - 1] == 'o')
    3768              :     {
    3769              :       obstack_grow (&obstack, name, len - 2);
    3770              :       obstack_grow0 (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    3771              :       name = XOBFINISH (&obstack, const char *);
    3772              :     }
    3773              : #endif
    3774              : 
    3775              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3776              :   /* If there is no filetype, make it the executable suffix (which includes
    3777              :      the ".").  But don't get confused if we have just "-o".  */
    3778              :   if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || not_actual_file_p (name))
    3779              :     return name;
    3780              : 
    3781              :   for (i = len - 1; i >= 0; i--)
    3782              :     if (IS_DIR_SEPARATOR (name[i]))
    3783              :       break;
    3784              : 
    3785              :   for (i++; i < len; i++)
    3786              :     if (name[i] == '.')
    3787              :       return name;
    3788              : 
    3789              :   obstack_grow (&obstack, name, len);
    3790              :   obstack_grow0 (&obstack, TARGET_EXECUTABLE_SUFFIX,
    3791              :                  strlen (TARGET_EXECUTABLE_SUFFIX));
    3792              :   name = XOBFINISH (&obstack, const char *);
    3793              : #endif
    3794              : 
    3795              :   return name;
    3796              : }
    3797              : #endif
    3798              : 
    3799              : /* Display the command line switches accepted by gcc.  */
    3800              : static void
    3801            4 : display_help (void)
    3802              : {
    3803            4 :   printf (_("Usage: %s [options] file...\n"), progname);
    3804            4 :   fputs (_("Options:\n"), stdout);
    3805              : 
    3806            4 :   fputs (_("  -pass-exit-codes         Exit with highest error code from a phase.\n"), stdout);
    3807            4 :   fputs (_("  --help                   Display this information.\n"), stdout);
    3808            4 :   fputs (_("  --target-help            Display target specific command line options "
    3809              :            "(including assembler and linker options).\n"), stdout);
    3810            4 :   fputs (_("  --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].\n"), stdout);
    3811            4 :   fputs (_("                           Display specific types of command line options.\n"), stdout);
    3812            4 :   if (! verbose_flag)
    3813            1 :     fputs (_("  (Use '-v --help' to display command line options of sub-processes).\n"), stdout);
    3814            4 :   fputs (_("  --version                Display compiler version information.\n"), stdout);
    3815            4 :   fputs (_("  -dumpspecs               Display all of the built in spec strings.\n"), stdout);
    3816            4 :   fputs (_("  -dumpversion             Display the version of the compiler.\n"), stdout);
    3817            4 :   fputs (_("  -dumpmachine             Display the compiler's target processor.\n"), stdout);
    3818            4 :   fputs (_("  -foffload=<targets>      Specify offloading targets.\n"), stdout);
    3819            4 :   fputs (_("  -print-search-dirs       Display the directories in the compiler's search path.\n"), stdout);
    3820            4 :   fputs (_("  -print-libgcc-file-name  Display the name of the compiler's companion library.\n"), stdout);
    3821            4 :   fputs (_("  -print-file-name=<lib>   Display the full path to library <lib>.\n"), stdout);
    3822            4 :   fputs (_("  -print-prog-name=<prog>  Display the full path to compiler component <prog>.\n"), stdout);
    3823            4 :   fputs (_("\
    3824              :   -print-multiarch         Display the target's normalized GNU triplet, used as\n\
    3825              :                            a component in the library path.\n"), stdout);
    3826            4 :   fputs (_("  -print-multi-directory   Display the root directory for versions of libgcc.\n"), stdout);
    3827            4 :   fputs (_("\
    3828              :   -print-multi-lib         Display the mapping between command line options and\n\
    3829              :                            multiple library search directories.\n"), stdout);
    3830            4 :   fputs (_("  -print-multi-os-directory Display the relative path to OS libraries.\n"), stdout);
    3831            4 :   fputs (_("  -print-sysroot           Display the target libraries directory.\n"), stdout);
    3832            4 :   fputs (_("  -print-sysroot-headers-suffix Display the sysroot suffix used to find headers.\n"), stdout);
    3833            4 :   fputs (_("  -Wa,<options>            Pass comma-separated <options> on to the assembler.\n"), stdout);
    3834            4 :   fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor.\n"), stdout);
    3835            4 :   fputs (_("  -Wl,<options>            Pass comma-separated <options> on to the linker.\n"), stdout);
    3836            4 :   fputs (_("  -Xassembler <arg>        Pass <arg> on to the assembler.\n"), stdout);
    3837            4 :   fputs (_("  -Xpreprocessor <arg>     Pass <arg> on to the preprocessor.\n"), stdout);
    3838            4 :   fputs (_("  -Xlinker <arg>           Pass <arg> on to the linker.\n"), stdout);
    3839            4 :   fputs (_("  -save-temps              Do not delete intermediate files.\n"), stdout);
    3840            4 :   fputs (_("  -save-temps=<arg>        Do not delete intermediate files.\n"), stdout);
    3841            4 :   fputs (_("\
    3842              :   -no-canonical-prefixes   Do not canonicalize paths when building relative\n\
    3843              :                            prefixes to other gcc components.\n"), stdout);
    3844            4 :   fputs (_("  -pipe                    Use pipes rather than intermediate files.\n"), stdout);
    3845            4 :   fputs (_("  -time                    Time the execution of each subprocess.\n"), stdout);
    3846            4 :   fputs (_("  -specs=<file>            Override built-in specs with the contents of <file>.\n"), stdout);
    3847            4 :   fputs (_("  -std=<standard>          Assume that the input sources are for <standard>.\n"), stdout);
    3848            4 :   fputs (_("\
    3849              :   --sysroot=<directory>    Use <directory> as the root directory for headers\n\
    3850              :                            and libraries.\n"), stdout);
    3851            4 :   fputs (_("  -B <directory>           Add <directory> to the compiler's search paths.\n"), stdout);
    3852            4 :   fputs (_("  -v                       Display the programs invoked by the compiler.\n"), stdout);
    3853            4 :   fputs (_("  -###                     Like -v but options quoted and commands not executed.\n"), stdout);
    3854            4 :   fputs (_("  -E                       Preprocess only; do not compile, assemble or link.\n"), stdout);
    3855            4 :   fputs (_("  -S                       Compile only; do not assemble or link.\n"), stdout);
    3856            4 :   fputs (_("  -c                       Compile and assemble, but do not link.\n"), stdout);
    3857            4 :   fputs (_("  -o <file>                Place the output into <file>.\n"), stdout);
    3858            4 :   fputs (_("  -pie                     Create a dynamically linked position independent\n\
    3859              :                            executable.\n"), stdout);
    3860            4 :   fputs (_("  -shared                  Create a shared library.\n"), stdout);
    3861            4 :   fputs (_("\
    3862              :   -x <language>            Specify the language of the following input files.\n\
    3863              :                            Permissible languages include: c c++ assembler none\n\
    3864              :                            'none' means revert to the default behavior of\n\
    3865              :                            guessing the language based on the file's extension.\n\
    3866              : "), stdout);
    3867              : 
    3868            4 :   printf (_("\
    3869              : \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
    3870              :  passed on to the various sub-processes invoked by %s.  In order to pass\n\
    3871              :  other options on to these processes the -W<letter> options must be used.\n\
    3872              : "), progname);
    3873              : 
    3874              :   /* The rest of the options are displayed by invocations of the various
    3875              :      sub-processes.  */
    3876            4 : }
    3877              : 
    3878              : static void
    3879            0 : add_preprocessor_option (const char *option, int len)
    3880              : {
    3881            0 :   preprocessor_options.safe_push (save_string (option, len));
    3882            0 : }
    3883              : 
    3884              : static void
    3885          195 : add_assembler_option (const char *option, int len)
    3886              : {
    3887          195 :   assembler_options.safe_push (save_string (option, len));
    3888          195 : }
    3889              : 
    3890              : static void
    3891           82 : add_linker_option (const char *option, int len)
    3892              : {
    3893           82 :   linker_options.safe_push (save_string (option, len));
    3894           82 : }
    3895              : 
    3896              : /* Allocate space for an input file in infiles.  */
    3897              : 
    3898              : static void
    3899       920630 : alloc_infile (void)
    3900              : {
    3901       920630 :   if (n_infiles_alloc == 0)
    3902              :     {
    3903       311717 :       n_infiles_alloc = 16;
    3904       311717 :       infiles = XNEWVEC (struct infile, n_infiles_alloc);
    3905              :     }
    3906       608913 :   else if (n_infiles_alloc == n_infiles)
    3907              :     {
    3908          247 :       n_infiles_alloc *= 2;
    3909          247 :       infiles = XRESIZEVEC (struct infile, infiles, n_infiles_alloc);
    3910              :     }
    3911       920630 : }
    3912              : 
    3913              : /* Store an input file with the given NAME and LANGUAGE in
    3914              :    infiles.  */
    3915              : 
    3916              : static void
    3917       608914 : add_infile (const char *name, const char *language, bool art = false)
    3918              : {
    3919       608914 :   alloc_infile ();
    3920       608914 :   infiles[n_infiles].name = name;
    3921       608914 :   infiles[n_infiles].artificial = art;
    3922       608914 :   infiles[n_infiles++].language = language;
    3923       608914 : }
    3924              : 
    3925              : /* Allocate space for a switch in switches.  */
    3926              : 
    3927              : static void
    3928      7886136 : alloc_switch (void)
    3929              : {
    3930      7886136 :   if (n_switches_alloc == 0)
    3931              :     {
    3932       312031 :       n_switches_alloc = 16;
    3933       312031 :       switches = XNEWVEC (struct switchstr, n_switches_alloc);
    3934              :     }
    3935      7574105 :   else if (n_switches_alloc == n_switches)
    3936              :     {
    3937       278183 :       n_switches_alloc *= 2;
    3938       278183 :       switches = XRESIZEVEC (struct switchstr, switches, n_switches_alloc);
    3939              :     }
    3940      7886136 : }
    3941              : 
    3942              : /* Save an option OPT with N_ARGS arguments in array ARGS, marking it
    3943              :    as validated if VALIDATED and KNOWN if it is an internal switch.  */
    3944              : 
    3945              : static void
    3946      6985922 : save_switch (const char *opt, size_t n_args, const char *const *args,
    3947              :              bool validated, bool known)
    3948              : {
    3949      6985922 :   alloc_switch ();
    3950      6985922 :   switches[n_switches].part1 = opt + 1;
    3951      6985922 :   if (n_args == 0)
    3952      5405775 :     switches[n_switches].args = 0;
    3953              :   else
    3954              :     {
    3955      1580147 :       switches[n_switches].args = XNEWVEC (const char *, n_args + 1);
    3956      1580147 :       memcpy (switches[n_switches].args, args, n_args * sizeof (const char *));
    3957      1580147 :       switches[n_switches].args[n_args] = NULL;
    3958              :     }
    3959              : 
    3960      6985922 :   switches[n_switches].live_cond = 0;
    3961      6985922 :   switches[n_switches].validated = validated;
    3962      6985922 :   switches[n_switches].known = known;
    3963      6985922 :   switches[n_switches].ordering = 0;
    3964      6985922 :   n_switches++;
    3965      6985922 : }
    3966              : 
    3967              : /* Set the SOURCE_DATE_EPOCH environment variable to the current time if it is
    3968              :    not set already.  */
    3969              : 
    3970              : static void
    3971          635 : set_source_date_epoch_envvar ()
    3972              : {
    3973              :   /* Array size is 21 = ceil(log_10(2^64)) + 1 to hold string representations
    3974              :      of 64 bit integers.  */
    3975          635 :   char source_date_epoch[21];
    3976          635 :   time_t tt;
    3977              : 
    3978          635 :   errno = 0;
    3979          635 :   tt = time (NULL);
    3980          635 :   if (tt < (time_t) 0 || errno != 0)
    3981            0 :     tt = (time_t) 0;
    3982              : 
    3983          635 :   snprintf (source_date_epoch, 21, "%llu", (unsigned long long) tt);
    3984              :   /* Using setenv instead of xputenv because we want the variable to remain
    3985              :      after finalizing so that it's still set in the second run when using
    3986              :      -fcompare-debug.  */
    3987          635 :   setenv ("SOURCE_DATE_EPOCH", source_date_epoch, 0);
    3988          635 : }
    3989              : 
    3990              : /* Handle an option DECODED that is unknown to the option-processing
    3991              :    machinery.  */
    3992              : 
    3993              : static bool
    3994          794 : driver_unknown_option_callback (const struct cl_decoded_option *decoded)
    3995              : {
    3996          794 :   const char *opt = decoded->arg;
    3997          794 :   if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
    3998           95 :       && !(decoded->errors & CL_ERR_NEGATIVE))
    3999              :     {
    4000              :       /* Leave unknown -Wno-* options for the compiler proper, to be
    4001              :          diagnosed only if there are warnings.  */
    4002           94 :       save_switch (decoded->canonical_option[0],
    4003           94 :                    decoded->canonical_option_num_elements - 1,
    4004              :                    &decoded->canonical_option[1], false, true);
    4005           94 :       return false;
    4006              :     }
    4007          700 :   if (decoded->opt_index == OPT_SPECIAL_unknown)
    4008              :     {
    4009              :       /* Give it a chance to define it a spec file.  */
    4010          700 :       save_switch (decoded->canonical_option[0],
    4011          700 :                    decoded->canonical_option_num_elements - 1,
    4012              :                    &decoded->canonical_option[1], false, false);
    4013          700 :       return false;
    4014              :     }
    4015              :   else
    4016              :     return true;
    4017              : }
    4018              : 
    4019              : /* Handle an option DECODED that is not marked as CL_DRIVER.
    4020              :    LANG_MASK will always be CL_DRIVER.  */
    4021              : 
    4022              : static void
    4023      4513210 : driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
    4024              :                             unsigned int lang_mask ATTRIBUTE_UNUSED)
    4025              : {
    4026              :   /* At this point, non-driver options are accepted (and expected to
    4027              :      be passed down by specs) unless marked to be rejected by the
    4028              :      driver.  Options to be rejected by the driver but accepted by the
    4029              :      compilers proper are treated just like completely unknown
    4030              :      options.  */
    4031      4513210 :   const struct cl_option *option = &cl_options[decoded->opt_index];
    4032              : 
    4033      4513210 :   if (option->cl_reject_driver)
    4034            0 :     error ("unrecognized command-line option %qs",
    4035            0 :            decoded->orig_option_with_args_text);
    4036              :   else
    4037      4513210 :     save_switch (decoded->canonical_option[0],
    4038      4513210 :                  decoded->canonical_option_num_elements - 1,
    4039              :                  &decoded->canonical_option[1], false, true);
    4040      4513210 : }
    4041              : 
    4042              : static const char *spec_lang = 0;
    4043              : static int last_language_n_infiles;
    4044              : 
    4045              : 
    4046              : /* Check that GCC is configured to support the offload target.  */
    4047              : 
    4048              : static bool
    4049          152 : check_offload_target_name (const char *target, ptrdiff_t len)
    4050              : {
    4051          152 :   const char *n, *c = OFFLOAD_TARGETS;
    4052          304 :   while (c)
    4053              :     {
    4054          152 :       n = strchr (c, ',');
    4055          152 :       if (n == NULL)
    4056          152 :         n = strchr (c, '\0');
    4057          152 :       if (len == n - c && strncmp (target, c, n - c) == 0)
    4058              :         break;
    4059          152 :       c = *n ? n + 1 : NULL;
    4060              :     }
    4061          152 :   if (!c)
    4062              :     {
    4063          152 :       auto_vec<const char*> candidates;
    4064          152 :       size_t olen = strlen (OFFLOAD_TARGETS) + 1;
    4065          152 :       char *cand = XALLOCAVEC (char, olen);
    4066          152 :       memcpy (cand, OFFLOAD_TARGETS, olen);
    4067          152 :       for (c = strtok (cand, ","); c; c = strtok (NULL, ","))
    4068            0 :         candidates.safe_push (c);
    4069          152 :       candidates.safe_push ("default");
    4070          152 :       candidates.safe_push ("disable");
    4071              : 
    4072          152 :       char *target2 = XALLOCAVEC (char, len + 1);
    4073          152 :       memcpy (target2, target, len);
    4074          152 :       target2[len] = '\0';
    4075              : 
    4076          152 :       error ("GCC is not configured to support %qs as %<-foffload=%> argument",
    4077              :              target2);
    4078              : 
    4079          152 :       char *s;
    4080          152 :       const char *hint = candidates_list_and_hint (target2, s, candidates);
    4081          152 :       if (hint)
    4082            0 :         inform (UNKNOWN_LOCATION,
    4083              :                 "valid %<-foffload=%> arguments are: %s; "
    4084              :                 "did you mean %qs?", s, hint);
    4085              :       else
    4086          152 :         inform (UNKNOWN_LOCATION, "valid %<-foffload=%> arguments are: %s", s);
    4087          152 :       XDELETEVEC (s);
    4088          152 :       return false;
    4089          152 :     }
    4090              :   return true;
    4091              : }
    4092              : 
    4093              : /* Sanity check for -foffload-options.  */
    4094              : 
    4095              : static void
    4096           27 : check_foffload_target_names (const char *arg)
    4097              : {
    4098           27 :   const char *cur, *next, *end;
    4099              :   /* If option argument starts with '-' then no target is specified and we
    4100              :      do not need to parse it.  */
    4101           27 :   if (arg[0] == '-')
    4102              :     return;
    4103            0 :   end = strchr (arg, '=');
    4104            0 :   if (end == NULL)
    4105              :     {
    4106            0 :       error ("%<=%>options missing after %<-foffload-options=%>target");
    4107            0 :       return;
    4108              :     }
    4109              : 
    4110              :   cur = arg;
    4111            0 :   while (cur < end)
    4112              :     {
    4113            0 :       next = strchr (cur, ',');
    4114            0 :       if (next == NULL)
    4115            0 :         next = end;
    4116            0 :       next = (next > end) ? end : next;
    4117              : 
    4118              :       /* Retain non-supported targets after printing an error as those will not
    4119              :          be processed; each enabled target only processes its triplet.  */
    4120            0 :       check_offload_target_name (cur, next - cur);
    4121            0 :       cur = next + 1;
    4122              :    }
    4123              : }
    4124              : 
    4125              : /* Parse -foffload option argument.  */
    4126              : 
    4127              : static void
    4128         2886 : handle_foffload_option (const char *arg)
    4129              : {
    4130         2886 :   const char *c, *cur, *n, *next, *end;
    4131         2886 :   char *target;
    4132              : 
    4133              :   /* If option argument starts with '-' then no target is specified and we
    4134              :      do not need to parse it.  */
    4135         2886 :   if (arg[0] == '-')
    4136              :     return;
    4137              : 
    4138         2047 :   end = strchr (arg, '=');
    4139         2047 :   if (end == NULL)
    4140         2047 :     end = strchr (arg, '\0');
    4141         2047 :   cur = arg;
    4142              : 
    4143         2047 :   while (cur < end)
    4144              :     {
    4145         2047 :       next = strchr (cur, ',');
    4146         2047 :       if (next == NULL)
    4147         2047 :         next = end;
    4148         2047 :       next = (next > end) ? end : next;
    4149              : 
    4150         2047 :       target = XNEWVEC (char, next - cur + 1);
    4151         2047 :       memcpy (target, cur, next - cur);
    4152         2047 :       target[next - cur] = '\0';
    4153              : 
    4154              :       /* Reset offloading list and continue.  */
    4155         2047 :       if (strcmp (target, "default") == 0)
    4156              :         {
    4157            0 :           free (offload_targets);
    4158            0 :           offload_targets = NULL;
    4159            0 :           goto next_item;
    4160              :         }
    4161              : 
    4162              :       /* If 'disable' is passed to the option, clean the list of
    4163              :          offload targets and return, even if more targets follow.
    4164              :          Likewise if GCC is not configured to support that offload target.  */
    4165         2047 :       if (strcmp (target, "disable") == 0
    4166         2047 :           || !check_offload_target_name (target, next - cur))
    4167              :         {
    4168         2047 :           free (offload_targets);
    4169         2047 :           offload_targets = xstrdup ("");
    4170         2047 :           return;
    4171              :         }
    4172              : 
    4173            0 :       if (!offload_targets)
    4174              :         {
    4175            0 :           offload_targets = target;
    4176            0 :           target = NULL;
    4177              :         }
    4178              :       else
    4179              :         {
    4180              :           /* Check that the target hasn't already presented in the list.  */
    4181              :           c = offload_targets;
    4182            0 :           do
    4183              :             {
    4184            0 :               n = strchr (c, ':');
    4185            0 :               if (n == NULL)
    4186            0 :                 n = strchr (c, '\0');
    4187              : 
    4188            0 :               if (next - cur == n - c && strncmp (c, target, n - c) == 0)
    4189              :                 break;
    4190              : 
    4191            0 :               c = n + 1;
    4192              :             }
    4193            0 :           while (*n);
    4194              : 
    4195              :           /* If duplicate is not found, append the target to the list.  */
    4196            0 :           if (c > n)
    4197              :             {
    4198            0 :               size_t offload_targets_len = strlen (offload_targets);
    4199            0 :               offload_targets
    4200            0 :                 = XRESIZEVEC (char, offload_targets,
    4201              :                               offload_targets_len + 1 + next - cur + 1);
    4202            0 :               offload_targets[offload_targets_len++] = ':';
    4203            0 :               memcpy (offload_targets + offload_targets_len, target, next - cur + 1);
    4204              :             }
    4205              :         }
    4206            0 : next_item:
    4207            0 :       cur = next + 1;
    4208            0 :       XDELETEVEC (target);
    4209              :     }
    4210              : }
    4211              : 
    4212              : /* Forward certain options to offloading compilation.  */
    4213              : 
    4214              : static void
    4215            0 : forward_offload_option (size_t opt_index, const char *arg, bool validated)
    4216              : {
    4217            0 :   switch (opt_index)
    4218              :     {
    4219            0 :     case OPT_l:
    4220              :       /* Use a '_GCC_' prefix and standard name ('-l_GCC_m' irrespective of the
    4221              :          host's 'MATH_LIBRARY', for example), so that the 'mkoffload's can tell
    4222              :          this has been synthesized here, and translate/drop as necessary.  */
    4223              :       /* Note that certain libraries ('-lc', '-lgcc', '-lgomp', for example)
    4224              :          are injected by default in offloading compilation, and therefore not
    4225              :          forwarded here.  */
    4226              :       /* GCC libraries.  */
    4227            0 :       if (/* '-lgfortran' */ strcmp (arg, "gfortran") == 0
    4228            0 :           || /* '-lstdc++' */ strcmp (arg, "stdc++") == 0)
    4229            0 :         save_switch (concat ("-foffload-options=-l_GCC_", arg, NULL),
    4230              :                      0, NULL, validated, true);
    4231              :       /* Other libraries.  */
    4232              :       else
    4233              :         {
    4234              :           /* The case will need special consideration where on the host
    4235              :              '!need_math', but for offloading compilation still need
    4236              :              '-foffload-options=-l_GCC_m'.  The problem is that we don't get
    4237              :              here anything like '-lm', because it's not synthesized in
    4238              :              'gcc/fortran/gfortranspec.cc:lang_specific_driver', for example.
    4239              :              Generally synthesizing '-foffload-options=-l_GCC_m' etc. in the
    4240              :              language specific drivers is non-trivial, needs very careful
    4241              :              review of their options handling.  However, this issue is not
    4242              :              actually relevant for the current set of supported host/offloading
    4243              :              configurations.  */
    4244            0 :           int need_math = (MATH_LIBRARY[0] != '\0');
    4245            0 :           if (/* '-lm' */ (need_math && strcmp (arg, MATH_LIBRARY) == 0))
    4246            0 :             save_switch ("-foffload-options=-l_GCC_m",
    4247              :                          0, NULL, validated, true);
    4248              :         }
    4249            0 :       break;
    4250            0 :     default:
    4251            0 :       gcc_unreachable ();
    4252              :     }
    4253            0 : }
    4254              : 
    4255              : /* Handle a driver option; arguments and return value as for
    4256              :    handle_option.  */
    4257              : 
    4258              : static bool
    4259      2827380 : driver_handle_option (struct gcc_options *opts,
    4260              :                       struct gcc_options *opts_set,
    4261              :                       const struct cl_decoded_option *decoded,
    4262              :                       unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
    4263              :                       location_t loc,
    4264              :                       const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
    4265              :                       diagnostics::context *dc,
    4266              :                       void (*) (void))
    4267              : {
    4268      2827380 :   size_t opt_index = decoded->opt_index;
    4269      2827380 :   const char *arg = decoded->arg;
    4270      2827380 :   const char *compare_debug_replacement_opt;
    4271      2827380 :   int value = decoded->value;
    4272      2827380 :   bool validated = false;
    4273      2827380 :   bool do_save = true;
    4274              : 
    4275      2827380 :   gcc_assert (opts == &global_options);
    4276      2827380 :   gcc_assert (opts_set == &global_options_set);
    4277      2827380 :   gcc_assert (static_cast<diagnostics::kind> (kind)
    4278              :               == diagnostics::kind::unspecified);
    4279      2827380 :   gcc_assert (loc == UNKNOWN_LOCATION);
    4280      2827380 :   gcc_assert (dc == global_dc);
    4281              : 
    4282      2827380 :   switch (opt_index)
    4283              :     {
    4284            1 :     case OPT_dumpspecs:
    4285            1 :       {
    4286            1 :         struct spec_list *sl;
    4287            1 :         init_spec ();
    4288           47 :         for (sl = specs; sl; sl = sl->next)
    4289           46 :           printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
    4290            1 :         if (link_command_spec)
    4291            1 :           printf ("*link_command:\n%s\n\n", link_command_spec);
    4292            1 :         exit (0);
    4293              :       }
    4294              : 
    4295          280 :     case OPT_dumpversion:
    4296          280 :       printf ("%s\n", spec_version);
    4297          280 :       exit (0);
    4298              : 
    4299            0 :     case OPT_dumpmachine:
    4300            0 :       printf ("%s\n", spec_machine);
    4301            0 :       exit (0);
    4302              : 
    4303            0 :     case OPT_dumpfullversion:
    4304            0 :       printf ("%s\n", BASEVER);
    4305            0 :       exit (0);
    4306              : 
    4307           78 :     case OPT__version:
    4308           78 :       print_version = 1;
    4309              : 
    4310              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4311           78 :       if (is_cpp_driver)
    4312            0 :         add_preprocessor_option ("--version", strlen ("--version"));
    4313           78 :       add_assembler_option ("--version", strlen ("--version"));
    4314           78 :       add_linker_option ("--version", strlen ("--version"));
    4315           78 :       break;
    4316              : 
    4317            5 :     case OPT__completion_:
    4318            5 :       validated = true;
    4319            5 :       completion = decoded->arg;
    4320            5 :       break;
    4321              : 
    4322            4 :     case OPT__help:
    4323            4 :       print_help_list = 1;
    4324              : 
    4325              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4326            4 :       if (is_cpp_driver)
    4327            0 :         add_preprocessor_option ("--help", 6);
    4328            4 :       add_assembler_option ("--help", 6);
    4329            4 :       add_linker_option ("--help", 6);
    4330            4 :       break;
    4331              : 
    4332          111 :     case OPT__help_:
    4333          111 :       print_subprocess_help = 2;
    4334          111 :       break;
    4335              : 
    4336            0 :     case OPT__target_help:
    4337            0 :       print_subprocess_help = 1;
    4338              : 
    4339              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4340            0 :       if (is_cpp_driver)
    4341            0 :         add_preprocessor_option ("--target-help", 13);
    4342            0 :       add_assembler_option ("--target-help", 13);
    4343            0 :       add_linker_option ("--target-help", 13);
    4344            0 :       break;
    4345              : 
    4346              :     case OPT__no_sysroot_suffix:
    4347              :     case OPT_pass_exit_codes:
    4348              :     case OPT_print_search_dirs:
    4349              :     case OPT_print_autofdo_gcov_version:
    4350              :     case OPT_print_file_name_:
    4351              :     case OPT_print_prog_name_:
    4352              :     case OPT_print_multi_lib:
    4353              :     case OPT_print_multi_directory:
    4354              :     case OPT_print_sysroot:
    4355              :     case OPT_print_multi_os_directory:
    4356              :     case OPT_print_multiarch:
    4357              :     case OPT_print_sysroot_headers_suffix:
    4358              :     case OPT_time:
    4359              :     case OPT_wrapper:
    4360              :       /* These options set the variables specified in common.opt
    4361              :          automatically, and do not need to be saved for spec
    4362              :          processing.  */
    4363              :       do_save = false;
    4364              :       break;
    4365              : 
    4366          392 :     case OPT_print_libgcc_file_name:
    4367          392 :       print_file_name = "libgcc.a";
    4368          392 :       do_save = false;
    4369          392 :       break;
    4370              : 
    4371            0 :     case OPT_fuse_ld_bfd:
    4372            0 :        use_ld = ".bfd";
    4373            0 :        break;
    4374              : 
    4375            0 :     case OPT_fuse_ld_gold:
    4376            0 :        use_ld = ".gold";
    4377            0 :        break;
    4378              : 
    4379            0 :     case OPT_fuse_ld_mold:
    4380            0 :        use_ld = ".mold";
    4381            0 :        break;
    4382              : 
    4383            0 :     case OPT_fuse_ld_wild:
    4384            0 :        use_ld = ".wild";
    4385            0 :        break;
    4386              : 
    4387            0 :     case OPT_fcompare_debug_second:
    4388            0 :       compare_debug_second = 1;
    4389            0 :       break;
    4390              : 
    4391          629 :     case OPT_fcompare_debug:
    4392          629 :       switch (value)
    4393              :         {
    4394            0 :         case 0:
    4395            0 :           compare_debug_replacement_opt = "-fcompare-debug=";
    4396            0 :           arg = "";
    4397            0 :           goto compare_debug_with_arg;
    4398              : 
    4399          629 :         case 1:
    4400          629 :           compare_debug_replacement_opt = "-fcompare-debug=-gtoggle";
    4401          629 :           arg = "-gtoggle";
    4402          629 :           goto compare_debug_with_arg;
    4403              : 
    4404            0 :         default:
    4405            0 :           gcc_unreachable ();
    4406              :         }
    4407            6 :       break;
    4408              : 
    4409            6 :     case OPT_fcompare_debug_:
    4410            6 :       compare_debug_replacement_opt = decoded->canonical_option[0];
    4411          635 :     compare_debug_with_arg:
    4412          635 :       gcc_assert (decoded->canonical_option_num_elements == 1);
    4413          635 :       gcc_assert (arg != NULL);
    4414          635 :       if (*arg)
    4415          635 :         compare_debug = 1;
    4416              :       else
    4417            0 :         compare_debug = -1;
    4418          635 :       if (compare_debug < 0)
    4419            0 :         compare_debug_opt = NULL;
    4420              :       else
    4421          635 :         compare_debug_opt = arg;
    4422          635 :       save_switch (compare_debug_replacement_opt, 0, NULL, validated, true);
    4423          635 :       set_source_date_epoch_envvar ();
    4424          635 :       return true;
    4425              : 
    4426       282995 :     case OPT_fdiagnostics_color_:
    4427       282995 :       diagnostic_color_init (dc, value);
    4428       282995 :       break;
    4429              : 
    4430       274709 :     case OPT_fdiagnostics_urls_:
    4431       274709 :       diagnostic_urls_init (dc, value);
    4432       274709 :       break;
    4433              : 
    4434            0 :     case OPT_fdiagnostics_show_highlight_colors:
    4435            0 :       dc->set_show_highlight_colors (value);
    4436            0 :       break;
    4437              : 
    4438            0 :     case OPT_fdiagnostics_format_:
    4439            0 :         {
    4440            0 :           const char *basename = get_diagnostic_file_output_basename (*opts);
    4441            0 :           gcc_assert (dc);
    4442            0 :           diagnostics::output_format_init (*dc,
    4443              :                                            opts->x_main_input_filename, basename,
    4444              :                                            (enum diagnostics_output_format)value,
    4445            0 :                                            opts->x_flag_diagnostics_json_formatting);
    4446            0 :           break;
    4447              :         }
    4448              : 
    4449            0 :     case OPT_fdiagnostics_add_output_:
    4450            0 :       handle_OPT_fdiagnostics_add_output_ (*opts, *dc, arg, loc);
    4451            0 :       break;
    4452              : 
    4453            0 :     case OPT_fdiagnostics_set_output_:
    4454            0 :       handle_OPT_fdiagnostics_set_output_ (*opts, *dc, arg, loc);
    4455            0 :       break;
    4456              : 
    4457       303963 :     case OPT_fdiagnostics_text_art_charset_:
    4458       303963 :       dc->set_text_art_charset ((enum diagnostic_text_art_charset)value);
    4459       303963 :       break;
    4460              : 
    4461              :     case OPT_Wa_:
    4462              :       {
    4463              :         int prev, j;
    4464              :         /* Pass the rest of this option to the assembler.  */
    4465              : 
    4466              :         /* Split the argument at commas.  */
    4467              :         prev = 0;
    4468          634 :         for (j = 0; arg[j]; j++)
    4469          586 :           if (arg[j] == ',')
    4470              :             {
    4471            0 :               add_assembler_option (arg + prev, j - prev);
    4472            0 :               prev = j + 1;
    4473              :             }
    4474              : 
    4475              :         /* Record the part after the last comma.  */
    4476           48 :         add_assembler_option (arg + prev, j - prev);
    4477              :       }
    4478           48 :       do_save = false;
    4479           48 :       break;
    4480              : 
    4481              :     case OPT_Wp_:
    4482              :       {
    4483              :         int prev, j;
    4484              :         /* Pass the rest of this option to the preprocessor.  */
    4485              : 
    4486              :         /* Split the argument at commas.  */
    4487              :         prev = 0;
    4488            0 :         for (j = 0; arg[j]; j++)
    4489            0 :           if (arg[j] == ',')
    4490              :             {
    4491            0 :               add_preprocessor_option (arg + prev, j - prev);
    4492            0 :               prev = j + 1;
    4493              :             }
    4494              : 
    4495              :         /* Record the part after the last comma.  */
    4496            0 :         add_preprocessor_option (arg + prev, j - prev);
    4497              :       }
    4498            0 :       do_save = false;
    4499            0 :       break;
    4500              : 
    4501              :     case OPT_Wl_:
    4502              :       {
    4503              :         int prev, j;
    4504              :         /* Split the argument at commas.  */
    4505              :         prev = 0;
    4506       124973 :         for (j = 0; arg[j]; j++)
    4507       117496 :           if (arg[j] == ',')
    4508              :             {
    4509           54 :               add_infile (save_string (arg + prev, j - prev), "*");
    4510           54 :               prev = j + 1;
    4511              :             }
    4512              :         /* Record the part after the last comma.  */
    4513         7477 :         add_infile (arg + prev, "*");
    4514         7477 :         if (strcmp (arg, "-z,lazy") == 0 || strcmp (arg, "-z,norelro") == 0)
    4515           12 :           avoid_linker_hardening_p = true;
    4516              :       }
    4517              :       do_save = false;
    4518              :       break;
    4519              : 
    4520           12 :     case OPT_z:
    4521           12 :       if (strcmp (arg, "lazy") == 0 || strcmp (arg, "norelro") == 0)
    4522           12 :         avoid_linker_hardening_p = true;
    4523              :       break;
    4524              : 
    4525            0 :     case OPT_Xlinker:
    4526            0 :       add_infile (arg, "*");
    4527            0 :       do_save = false;
    4528            0 :       break;
    4529              : 
    4530            0 :     case OPT_Xpreprocessor:
    4531            0 :       add_preprocessor_option (arg, strlen (arg));
    4532            0 :       do_save = false;
    4533            0 :       break;
    4534              : 
    4535           65 :     case OPT_Xassembler:
    4536           65 :       add_assembler_option (arg, strlen (arg));
    4537           65 :       do_save = false;
    4538           65 :       break;
    4539              : 
    4540       267867 :     case OPT_l:
    4541              :       /* POSIX allows separation of -l and the lib arg; canonicalize
    4542              :          by concatenating -l with its arg */
    4543       267867 :       add_infile (concat ("-l", arg, NULL), "*");
    4544              : 
    4545              :       /* Forward to offloading compilation '-l[...]' flags for standard,
    4546              :          well-known libraries.  */
    4547              :       /* Doing this processing here means that we don't get to see libraries
    4548              :          injected via specs, such as '-lquadmath' injected via
    4549              :          '[build]/[target]/libgfortran/libgfortran.spec'.  However, this issue
    4550              :          is not actually relevant for the current set of host/offloading
    4551              :          configurations.  */
    4552       267867 :       if (ENABLE_OFFLOADING)
    4553              :         forward_offload_option (opt_index, arg, validated);
    4554              : 
    4555       267867 :       do_save = false;
    4556       267867 :       break;
    4557              : 
    4558       268254 :     case OPT_L:
    4559              :       /* Similarly, canonicalize -L for linkers that may not accept
    4560              :          separate arguments.  */
    4561       268254 :       save_switch (concat ("-L", arg, NULL), 0, NULL, validated, true);
    4562       268254 :       return true;
    4563              : 
    4564            0 :     case OPT_F:
    4565              :       /* Likewise -F.  */
    4566            0 :       save_switch (concat ("-F", arg, NULL), 0, NULL, validated, true);
    4567            0 :       return true;
    4568              : 
    4569          416 :     case OPT_save_temps:
    4570          416 :       if (!save_temps_flag)
    4571          410 :         save_temps_flag = SAVE_TEMPS_DUMP;
    4572              :       validated = true;
    4573              :       break;
    4574              : 
    4575           58 :     case OPT_save_temps_:
    4576           58 :       if (strcmp (arg, "cwd") == 0)
    4577           29 :         save_temps_flag = SAVE_TEMPS_CWD;
    4578           29 :       else if (strcmp (arg, "obj") == 0
    4579            0 :                || strcmp (arg, "object") == 0)
    4580           29 :         save_temps_flag = SAVE_TEMPS_OBJ;
    4581              :       else
    4582            0 :         fatal_error (input_location, "%qs is an unknown %<-save-temps%> option",
    4583            0 :                      decoded->orig_option_with_args_text);
    4584           58 :       save_temps_overrides_dumpdir = true;
    4585           58 :       break;
    4586              : 
    4587        23442 :     case OPT_dumpdir:
    4588        23442 :       free (dumpdir);
    4589        23442 :       dumpdir = xstrdup (arg);
    4590        23442 :       save_temps_overrides_dumpdir = false;
    4591        23442 :       break;
    4592              : 
    4593        24899 :     case OPT_dumpbase:
    4594        24899 :       free (dumpbase);
    4595        24899 :       dumpbase = xstrdup (arg);
    4596        24899 :       break;
    4597              : 
    4598          256 :     case OPT_dumpbase_ext:
    4599          256 :       free (dumpbase_ext);
    4600          256 :       dumpbase_ext = xstrdup (arg);
    4601          256 :       break;
    4602              : 
    4603              :     case OPT_no_canonical_prefixes:
    4604              :       /* Already handled as a special case, so ignored here.  */
    4605              :       do_save = false;
    4606              :       break;
    4607              : 
    4608              :     case OPT_pipe:
    4609              :       validated = true;
    4610              :       /* These options set the variables specified in common.opt
    4611              :          automatically, but do need to be saved for spec
    4612              :          processing.  */
    4613              :       break;
    4614              : 
    4615            3 :     case OPT_specs_:
    4616            3 :       {
    4617            3 :         struct user_specs *user = XNEW (struct user_specs);
    4618              : 
    4619            3 :         user->next = (struct user_specs *) 0;
    4620            3 :         user->filename = arg;
    4621            3 :         if (user_specs_tail)
    4622            0 :           user_specs_tail->next = user;
    4623              :         else
    4624            3 :           user_specs_head = user;
    4625            3 :         user_specs_tail = user;
    4626              :       }
    4627            3 :       validated = true;
    4628            3 :       break;
    4629              : 
    4630            0 :     case OPT__sysroot_:
    4631            0 :       target_system_root = arg;
    4632            0 :       target_system_root_changed = 1;
    4633              :       /* Saving this option is useful to let self-specs decide to
    4634              :          provide a default one.  */
    4635            0 :       do_save = true;
    4636            0 :       validated = true;
    4637            0 :       break;
    4638              : 
    4639            0 :     case OPT_time_:
    4640            0 :       if (report_times_to_file)
    4641            0 :         fclose (report_times_to_file);
    4642            0 :       report_times_to_file = fopen (arg, "a");
    4643            0 :       do_save = false;
    4644            0 :       break;
    4645              : 
    4646         9532 :     case OPT_truncate:
    4647         9532 :       totruncate_file = arg;
    4648         9532 :       do_save = false;
    4649         9532 :       break;
    4650              : 
    4651          638 :     case OPT____:
    4652              :       /* "-###"
    4653              :          This is similar to -v except that there is no execution
    4654              :          of the commands and the echoed arguments are quoted.  It
    4655              :          is intended for use in shell scripts to capture the
    4656              :          driver-generated command line.  */
    4657          638 :       verbose_only_flag++;
    4658          638 :       verbose_flag = 1;
    4659          638 :       do_save = false;
    4660          638 :       break;
    4661              : 
    4662       506497 :     case OPT_B:
    4663       506497 :       {
    4664       506497 :         size_t len = strlen (arg);
    4665              : 
    4666              :         /* Catch the case where the user has forgotten to append a
    4667              :            directory separator to the path.  Note, they may be using
    4668              :            -B to add an executable name prefix, eg "i386-elf-", in
    4669              :            order to distinguish between multiple installations of
    4670              :            GCC in the same directory.  Hence we must check to see
    4671              :            if appending a directory separator actually makes a
    4672              :            valid directory name.  */
    4673       506497 :         if (!IS_DIR_SEPARATOR (arg[len - 1])
    4674       506497 :             && is_directory (arg))
    4675              :           {
    4676       100129 :             char *tmp = XNEWVEC (char, len + 2);
    4677       100129 :             strcpy (tmp, arg);
    4678       100129 :             tmp[len] = DIR_SEPARATOR;
    4679       100129 :             tmp[++len] = 0;
    4680       100129 :             arg = tmp;
    4681              :           }
    4682              : 
    4683       506497 :         add_prefix (&exec_prefixes, arg, NULL,
    4684              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4685       506497 :         add_prefix (&startfile_prefixes, arg, NULL,
    4686              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4687       506497 :         add_prefix (&include_prefixes, arg, NULL,
    4688              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4689              :       }
    4690       506497 :       validated = true;
    4691       506497 :       break;
    4692              : 
    4693         2889 :     case OPT_E:
    4694         2889 :       have_E = true;
    4695         2889 :       break;
    4696              : 
    4697        52845 :     case OPT_x:
    4698        52845 :       spec_lang = arg;
    4699        52845 :       if (!strcmp (spec_lang, "none"))
    4700              :         /* Suppress the warning if -xnone comes after the last input
    4701              :            file, because alternate command interfaces like g++ might
    4702              :            find it useful to place -xnone after each input file.  */
    4703        13937 :         spec_lang = 0;
    4704              :       else
    4705        38908 :         last_language_n_infiles = n_infiles;
    4706              :       do_save = false;
    4707              :       break;
    4708              : 
    4709       281758 :     case OPT_o:
    4710       281758 :       have_o = 1;
    4711              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
    4712              :       arg = convert_filename (arg, ! have_c, 0);
    4713              : #endif
    4714       281758 :       output_file = arg;
    4715              :       /* On some systems, ld cannot handle "-o" without a space.  So
    4716              :          split the option from its argument.  */
    4717       281758 :       save_switch ("-o", 1, &arg, validated, true);
    4718       281758 :       return true;
    4719              : 
    4720         2167 :     case OPT_pie:
    4721              : #ifdef ENABLE_DEFAULT_PIE
    4722              :       /* -pie is turned on by default.  */
    4723              :       validated = true;
    4724              : #endif
    4725              :       /* FALLTHROUGH */
    4726         2167 :     case OPT_r:
    4727         2167 :     case OPT_shared:
    4728         2167 :     case OPT_no_pie:
    4729         2167 :       avoid_linker_hardening_p = true;
    4730         2167 :       break;
    4731              : 
    4732          101 :     case OPT_static:
    4733          101 :       static_p = true;
    4734          101 :       break;
    4735              : 
    4736              :     case OPT_static_libgcc:
    4737              :     case OPT_shared_libgcc:
    4738              :     case OPT_static_libgfortran:
    4739              :     case OPT_static_libquadmath:
    4740              :     case OPT_static_libphobos:
    4741              :     case OPT_static_libga68:
    4742              :     case OPT_static_libgm2:
    4743              :     case OPT_static_libstdc__:
    4744              :       /* These are always valid; gcc.cc itself understands the first two
    4745              :          gfortranspec.cc understands -static-libgfortran,
    4746              :          libgfortran.spec handles -static-libquadmath,
    4747              :          a68spec.cc understands -static-libga68,
    4748              :          d-spec.cc understands -static-libphobos,
    4749              :          gm2spec.cc understands -static-libgm2,
    4750              :          and g++spec.cc understands -static-libstdc++.  */
    4751              :       validated = true;
    4752              :       break;
    4753              : 
    4754           78 :     case OPT_fwpa:
    4755           78 :       flag_wpa = "";
    4756           78 :       break;
    4757              : 
    4758           27 :     case OPT_foffload_options_:
    4759           27 :       check_foffload_target_names (arg);
    4760           27 :       break;
    4761              : 
    4762         2886 :     case OPT_foffload_:
    4763         2886 :       handle_foffload_option (arg);
    4764         2886 :       if (arg[0] == '-' || NULL != strchr (arg, '='))
    4765          839 :         save_switch (concat ("-foffload-options=", arg, NULL),
    4766              :                      0, NULL, validated, true);
    4767              :       do_save = false;
    4768              :       break;
    4769              : 
    4770            0 :     case OPT_gcodeview:
    4771            0 :       add_infile ("--pdb=", "*");
    4772            0 :       break;
    4773              : 
    4774              :     default:
    4775              :       /* Various driver options need no special processing at this
    4776              :          point, having been handled in a prescan above or being
    4777              :          handled by specs.  */
    4778              :       break;
    4779              :     }
    4780              : 
    4781      1700836 :   if (do_save)
    4782      1919094 :     save_switch (decoded->canonical_option[0],
    4783      1919094 :                  decoded->canonical_option_num_elements - 1,
    4784              :                  &decoded->canonical_option[1], validated, true);
    4785              :   return true;
    4786              : }
    4787              : 
    4788              : /* Return true if F2 is F1 followed by a single suffix, i.e., by a
    4789              :    period and additional characters other than a period.  */
    4790              : 
    4791              : static inline bool
    4792        88396 : adds_single_suffix_p (const char *f2, const char *f1)
    4793              : {
    4794        88396 :   size_t len = strlen (f1);
    4795              : 
    4796        88396 :   return (strncmp (f1, f2, len) == 0
    4797        79969 :           && f2[len] == '.'
    4798       167892 :           && strchr (f2 + len + 1, '.') == NULL);
    4799              : }
    4800              : 
    4801              : /* Put the driver's standard set of option handlers in *HANDLERS.  */
    4802              : 
    4803              : static void
    4804       900496 : set_option_handlers (struct cl_option_handlers *handlers)
    4805              : {
    4806       900496 :   handlers->unknown_option_callback = driver_unknown_option_callback;
    4807       900496 :   handlers->wrong_lang_callback = driver_wrong_lang_callback;
    4808       900496 :   handlers->num_handlers = 3;
    4809       900496 :   handlers->handlers[0].handler = driver_handle_option;
    4810       900496 :   handlers->handlers[0].mask = CL_DRIVER;
    4811       900496 :   handlers->handlers[1].handler = common_handle_option;
    4812       900496 :   handlers->handlers[1].mask = CL_COMMON;
    4813       900496 :   handlers->handlers[2].handler = target_handle_option;
    4814       900496 :   handlers->handlers[2].mask = CL_TARGET;
    4815            0 : }
    4816              : 
    4817              : 
    4818              : /* Return the index into infiles for the single non-library
    4819              :    non-lto-wpa input file, -1 if there isn't any, or -2 if there is
    4820              :    more than one.  */
    4821              : static inline int
    4822       160419 : single_input_file_index ()
    4823              : {
    4824       160419 :   int ret = -1;
    4825              : 
    4826       519729 :   for (int i = 0; i < n_infiles; i++)
    4827              :     {
    4828       371555 :       if (infiles[i].language
    4829       262570 :           && (infiles[i].language[0] == '*'
    4830        51633 :               || (flag_wpa
    4831        19934 :                   && strcmp (infiles[i].language, "lto") == 0)))
    4832       230871 :         continue;
    4833              : 
    4834       140684 :       if (ret != -1)
    4835              :         return -2;
    4836              : 
    4837              :       ret = i;
    4838              :     }
    4839              : 
    4840              :   return ret;
    4841              : }
    4842              : 
    4843              : /* Create the vector `switches' and its contents.
    4844              :    Store its length in `n_switches'.  */
    4845              : 
    4846              : static void
    4847       312002 : process_command (unsigned int decoded_options_count,
    4848              :                  struct cl_decoded_option *decoded_options)
    4849              : {
    4850       312002 :   const char *temp;
    4851       312002 :   char *temp1;
    4852       312002 :   char *tooldir_prefix, *tooldir_prefix2;
    4853       312002 :   char *(*get_relative_prefix) (const char *, const char *,
    4854              :                                 const char *) = NULL;
    4855       312002 :   struct cl_option_handlers handlers;
    4856       312002 :   unsigned int j;
    4857              : 
    4858       312002 :   gcc_exec_prefix = env.get ("GCC_EXEC_PREFIX");
    4859              : 
    4860       312002 :   n_switches = 0;
    4861       312002 :   n_infiles = 0;
    4862       312002 :   added_libraries = 0;
    4863              : 
    4864              :   /* Figure compiler version from version string.  */
    4865              : 
    4866       312002 :   compiler_version = temp1 = xstrdup (version_string);
    4867              : 
    4868      2184014 :   for (; *temp1; ++temp1)
    4869              :     {
    4870      2184014 :       if (*temp1 == ' ')
    4871              :         {
    4872       312002 :           *temp1 = '\0';
    4873       312002 :           break;
    4874              :         }
    4875              :     }
    4876              : 
    4877              :   /* Handle any -no-canonical-prefixes flag early, to assign the function
    4878              :      that builds relative prefixes.  This function creates default search
    4879              :      paths that are needed later in normal option handling.  */
    4880              : 
    4881      6998077 :   for (j = 1; j < decoded_options_count; j++)
    4882              :     {
    4883      6686075 :       if (decoded_options[j].opt_index == OPT_no_canonical_prefixes)
    4884              :         {
    4885              :           get_relative_prefix = make_relative_prefix_ignore_links;
    4886              :           break;
    4887              :         }
    4888              :     }
    4889       312002 :   if (! get_relative_prefix)
    4890       312002 :     get_relative_prefix = make_relative_prefix;
    4891              : 
    4892              :   /* Set up the default search paths.  If there is no GCC_EXEC_PREFIX,
    4893              :      see if we can create it from the pathname specified in
    4894              :      decoded_options[0].arg.  */
    4895              : 
    4896       312002 :   gcc_libexec_prefix = standard_libexec_prefix;
    4897              : #ifndef VMS
    4898              :   /* FIXME: make_relative_prefix doesn't yet work for VMS.  */
    4899       312002 :   if (!gcc_exec_prefix)
    4900              :     {
    4901        29566 :       gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg,
    4902              :                                              standard_bindir_prefix,
    4903              :                                              standard_exec_prefix);
    4904        29566 :       gcc_libexec_prefix = get_relative_prefix (decoded_options[0].arg,
    4905              :                                              standard_bindir_prefix,
    4906              :                                              standard_libexec_prefix);
    4907        29566 :       if (gcc_exec_prefix)
    4908        29566 :         xputenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
    4909              :     }
    4910              :   else
    4911              :     {
    4912              :       /* make_relative_prefix requires a program name, but
    4913              :          GCC_EXEC_PREFIX is typically a directory name with a trailing
    4914              :          / (which is ignored by make_relative_prefix), so append a
    4915              :          program name.  */
    4916       282436 :       char *tmp_prefix = concat (gcc_exec_prefix, "gcc", NULL);
    4917       282436 :       gcc_libexec_prefix = get_relative_prefix (tmp_prefix,
    4918              :                                                 standard_exec_prefix,
    4919              :                                                 standard_libexec_prefix);
    4920              : 
    4921              :       /* The path is unrelocated, so fallback to the original setting.  */
    4922       282436 :       if (!gcc_libexec_prefix)
    4923       282091 :         gcc_libexec_prefix = standard_libexec_prefix;
    4924              : 
    4925       282436 :       free (tmp_prefix);
    4926              :     }
    4927              : #else
    4928              : #endif
    4929              :   /* From this point onward, gcc_exec_prefix is non-null if the toolchain
    4930              :      is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX
    4931              :      or an automatically created GCC_EXEC_PREFIX from
    4932              :      decoded_options[0].arg.  */
    4933              : 
    4934              :   /* Do language-specific adjustment/addition of flags.  */
    4935       312002 :   lang_specific_driver (&decoded_options, &decoded_options_count,
    4936              :                         &added_libraries);
    4937              : 
    4938       311998 :   if (gcc_exec_prefix)
    4939              :     {
    4940       311998 :       int len = strlen (gcc_exec_prefix);
    4941              : 
    4942       311998 :       if (len > (int) sizeof ("/lib/gcc/") - 1
    4943       311998 :           && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
    4944              :         {
    4945       311998 :           temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
    4946       311998 :           if (IS_DIR_SEPARATOR (*temp)
    4947       311998 :               && filename_ncmp (temp + 1, "lib", 3) == 0
    4948       311998 :               && IS_DIR_SEPARATOR (temp[4])
    4949       623996 :               && filename_ncmp (temp + 5, "gcc", 3) == 0)
    4950       311998 :             len -= sizeof ("/lib/gcc/") - 1;
    4951              :         }
    4952              : 
    4953       311998 :       set_std_prefix (gcc_exec_prefix, len);
    4954       311998 :       add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
    4955              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4956       311998 :       add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
    4957              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4958              :     }
    4959              : 
    4960              :   /* COMPILER_PATH and LIBRARY_PATH have values
    4961              :      that are lists of directory names with colons.  */
    4962              : 
    4963       311998 :   temp = env.get ("COMPILER_PATH");
    4964       311998 :   if (temp)
    4965              :     {
    4966        23278 :       const char *startp, *endp;
    4967        23278 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4968              : 
    4969        23278 :       startp = endp = temp;
    4970      2118326 :       while (1)
    4971              :         {
    4972      2118326 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4973              :             {
    4974        37735 :               strncpy (nstore, startp, endp - startp);
    4975        37735 :               if (endp == startp)
    4976            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4977        37735 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4978              :                 {
    4979            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4980            0 :                   nstore[endp - startp + 1] = 0;
    4981              :                 }
    4982              :               else
    4983        37735 :                 nstore[endp - startp] = 0;
    4984        37735 :               add_prefix (&exec_prefixes, nstore, 0,
    4985              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4986        37735 :               add_prefix (&include_prefixes, nstore, 0,
    4987              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4988        37735 :               if (*endp == 0)
    4989              :                 break;
    4990        14457 :               endp = startp = endp + 1;
    4991              :             }
    4992              :           else
    4993      2080591 :             endp++;
    4994              :         }
    4995              :     }
    4996              : 
    4997       311998 :   temp = env.get (LIBRARY_PATH_ENV);
    4998       311998 :   if (temp && *cross_compile == '0')
    4999              :     {
    5000        24641 :       const char *startp, *endp;
    5001        24641 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    5002              : 
    5003        24641 :       startp = endp = temp;
    5004      4281768 :       while (1)
    5005              :         {
    5006      4281768 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    5007              :             {
    5008       178076 :               strncpy (nstore, startp, endp - startp);
    5009       178076 :               if (endp == startp)
    5010            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    5011       178076 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    5012              :                 {
    5013         1363 :                   nstore[endp - startp] = DIR_SEPARATOR;
    5014         1363 :                   nstore[endp - startp + 1] = 0;
    5015              :                 }
    5016              :               else
    5017       176713 :                 nstore[endp - startp] = 0;
    5018       178076 :               add_prefix (&startfile_prefixes, nstore, NULL,
    5019              :                           PREFIX_PRIORITY_LAST, 0, 1);
    5020       178076 :               if (*endp == 0)
    5021              :                 break;
    5022       153435 :               endp = startp = endp + 1;
    5023              :             }
    5024              :           else
    5025      4103692 :             endp++;
    5026              :         }
    5027              :     }
    5028              : 
    5029              :   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
    5030       311998 :   temp = env.get ("LPATH");
    5031       311998 :   if (temp && *cross_compile == '0')
    5032              :     {
    5033            0 :       const char *startp, *endp;
    5034            0 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    5035              : 
    5036            0 :       startp = endp = temp;
    5037            0 :       while (1)
    5038              :         {
    5039            0 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    5040              :             {
    5041            0 :               strncpy (nstore, startp, endp - startp);
    5042            0 :               if (endp == startp)
    5043            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    5044            0 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    5045              :                 {
    5046            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    5047            0 :                   nstore[endp - startp + 1] = 0;
    5048              :                 }
    5049              :               else
    5050            0 :                 nstore[endp - startp] = 0;
    5051            0 :               add_prefix (&startfile_prefixes, nstore, NULL,
    5052              :                           PREFIX_PRIORITY_LAST, 0, 1);
    5053            0 :               if (*endp == 0)
    5054              :                 break;
    5055            0 :               endp = startp = endp + 1;
    5056              :             }
    5057              :           else
    5058            0 :             endp++;
    5059              :         }
    5060              :     }
    5061              : 
    5062              :   /* Process the options and store input files and switches in their
    5063              :      vectors.  */
    5064              : 
    5065       311998 :   last_language_n_infiles = -1;
    5066              : 
    5067       311998 :   set_option_handlers (&handlers);
    5068              : 
    5069      5998696 :   for (j = 1; j < decoded_options_count; j++)
    5070              :     {
    5071      5882979 :       switch (decoded_options[j].opt_index)
    5072              :         {
    5073       196281 :         case OPT_S:
    5074       196281 :         case OPT_c:
    5075       196281 :         case OPT_E:
    5076       196281 :           have_c = 1;
    5077       196281 :           break;
    5078              :         }
    5079      5882979 :       if (have_c)
    5080              :         break;
    5081              :     }
    5082              : 
    5083      7396547 :   for (j = 1; j < decoded_options_count; j++)
    5084              :     {
    5085      7084830 :       if (decoded_options[j].opt_index == OPT_SPECIAL_input_file)
    5086              :         {
    5087       333166 :           const char *arg = decoded_options[j].arg;
    5088              : 
    5089              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    5090              :           arg = convert_filename (arg, 0, access (arg, F_OK));
    5091              : #endif
    5092       333166 :           add_infile (arg, spec_lang,
    5093       333166 :                       decoded_options[j].mask == CL_DRIVER);
    5094              : 
    5095       333166 :           continue;
    5096       333166 :         }
    5097              : 
    5098      6751664 :       read_cmdline_option (&global_options, &global_options_set,
    5099              :                            decoded_options + j, UNKNOWN_LOCATION,
    5100              :                            CL_DRIVER, &handlers, global_dc);
    5101              :     }
    5102              : 
    5103              :   /* If the user didn't specify any, default to all configured offload
    5104              :      targets.  */
    5105       311717 :   if (ENABLE_OFFLOADING && offload_targets == NULL)
    5106              :     {
    5107              :       handle_foffload_option (OFFLOAD_TARGETS);
    5108              : #if OFFLOAD_DEFAULTED
    5109              :       offload_targets_default = true;
    5110              : #endif
    5111              :     }
    5112              : 
    5113              :   /* TODO: check if -static -pie works and maybe use it.  */
    5114       311717 :   if (flag_hardened)
    5115              :     {
    5116           92 :       if (!avoid_linker_hardening_p && !static_p)
    5117              :         {
    5118              : #if defined HAVE_LD_PIE && defined LD_PIE_SPEC
    5119           68 :           save_switch (LD_PIE_SPEC, 0, NULL, /*validated=*/true, /*known=*/false);
    5120              : #endif
    5121              :           /* These are passed straight down to collect2 so we have to break
    5122              :              it up like this.  */
    5123           68 :           if (HAVE_LD_NOW_SUPPORT)
    5124              :             {
    5125           68 :               add_infile ("-z", "*");
    5126           68 :               add_infile ("now", "*");
    5127              :             }
    5128           68 :           if (HAVE_LD_RELRO_SUPPORT)
    5129              :             {
    5130           68 :               add_infile ("-z", "*");
    5131           68 :               add_infile ("relro", "*");
    5132              :             }
    5133              :         }
    5134              :       /* We can't use OPT_Whardened yet.  Sigh.  */
    5135              :       else
    5136           24 :         warning_at (UNKNOWN_LOCATION, 0,
    5137              :                     "linker hardening options not enabled by %<-fhardened%> "
    5138              :                     "because other link options were specified on the command "
    5139              :                     "line");
    5140              :     }
    5141              : 
    5142              :   /* Handle -gtoggle as it would later in toplev.cc:process_options to
    5143              :      make the debug-level-gt spec function work as expected.  */
    5144       311717 :   if (flag_gtoggle)
    5145              :     {
    5146            4 :       if (debug_info_level == DINFO_LEVEL_NONE)
    5147            0 :         debug_info_level = DINFO_LEVEL_NORMAL;
    5148              :       else
    5149            4 :         debug_info_level = DINFO_LEVEL_NONE;
    5150              :     }
    5151              : 
    5152       311717 :   if (output_file
    5153       281757 :       && strcmp (output_file, "-") != 0
    5154       281594 :       && strcmp (output_file, HOST_BIT_BUCKET) != 0)
    5155              :     {
    5156              :       int i;
    5157       833297 :       for (i = 0; i < n_infiles; i++)
    5158       267580 :         if ((!infiles[i].language || infiles[i].language[0] != '*')
    5159       581783 :             && canonical_filename_eq (infiles[i].name, output_file))
    5160            1 :           fatal_error (input_location,
    5161              :                        "input file %qs is the same as output file",
    5162              :                        output_file);
    5163              :     }
    5164              : 
    5165       311716 :   if (output_file != NULL && output_file[0] == '\0')
    5166            0 :     fatal_error (input_location, "output filename may not be empty");
    5167              : 
    5168              :   /* -dumpdir and -save-temps=* both specify the location of aux/dump
    5169              :      outputs; the one that appears last prevails.  When compiling
    5170              :      multiple sources, an explicit dumpbase (minus -ext) may be
    5171              :      combined with an explicit or implicit dumpdir, whereas when
    5172              :      linking, a specified or implied link output name (minus
    5173              :      extension) may be combined with a prevailing -save-temps=* or an
    5174              :      otherwise implied dumpdir, but not override a prevailing
    5175              :      -dumpdir.  Primary outputs (e.g., linker output when linking
    5176              :      without -o, or .i, .s or .o outputs when processing multiple
    5177              :      inputs with -E, -S or -c, respectively) are NOT affected by these
    5178              :      -save-temps=/-dump* options, always landing in the current
    5179              :      directory and with the same basename as the input when an output
    5180              :      name is not given, but when they're intermediate outputs, they
    5181              :      are named like other aux outputs, so the options affect their
    5182              :      location and name.
    5183              : 
    5184              :      Here are some examples.  There are several more in the
    5185              :      documentation of -o and -dump*, and some quite exhaustive tests
    5186              :      in gcc.misc-tests/outputs.exp.
    5187              : 
    5188              :      When compiling any number of sources, no -dump* nor
    5189              :      -save-temps=*, all outputs in cwd without prefix:
    5190              : 
    5191              :      # gcc -c b.c -gsplit-dwarf
    5192              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5193              : 
    5194              :      # gcc -c b.c d.c -gsplit-dwarf
    5195              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5196              :      && cc1 [-dumpdir ./] -dumpbase d.c -dumpbase-ext .c # d.o d.dwo
    5197              : 
    5198              :      When compiling and linking, no -dump* nor -save-temps=*, .o
    5199              :      outputs are temporary, aux outputs land in the dir of the output,
    5200              :      prefixed with the basename of the linker output:
    5201              : 
    5202              :      # gcc b.c d.c -o ab -gsplit-dwarf
    5203              :      -> cc1 -dumpdir ab- -dumpbase b.c -dumpbase-ext .c # ab-b.dwo
    5204              :      && cc1 -dumpdir ab- -dumpbase d.c -dumpbase-ext .c # ab-d.dwo
    5205              :      && link ... -o ab
    5206              : 
    5207              :      # gcc b.c d.c [-o a.out] -gsplit-dwarf
    5208              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.dwo
    5209              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.dwo
    5210              :      && link ... [-o a.out]
    5211              : 
    5212              :      When compiling and linking, a prevailing -dumpdir fully overrides
    5213              :      the prefix of aux outputs given by the output name:
    5214              : 
    5215              :      # gcc -dumpdir f b.c d.c -gsplit-dwarf [-o [dir/]whatever]
    5216              :      -> cc1 -dumpdir f -dumpbase b.c -dumpbase-ext .c # fb.dwo
    5217              :      && cc1 -dumpdir f -dumpbase d.c -dumpbase-ext .c # fd.dwo
    5218              :      && link ... [-o whatever]
    5219              : 
    5220              :      When compiling multiple inputs, an explicit -dumpbase is combined
    5221              :      with -dumpdir, affecting aux outputs, but not the .o outputs:
    5222              : 
    5223              :      # gcc -dumpdir f -dumpbase g- b.c d.c -gsplit-dwarf -c
    5224              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # b.o fg-b.dwo
    5225              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # d.o fg-d.dwo
    5226              : 
    5227              :      When compiling and linking with -save-temps, the .o outputs that
    5228              :      would have been temporary become aux outputs, so they get
    5229              :      affected by -dump* flags:
    5230              : 
    5231              :      # gcc -dumpdir f -dumpbase g- -save-temps b.c d.c
    5232              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # fg-b.o
    5233              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # fg-d.o
    5234              :      && link
    5235              : 
    5236              :      If -save-temps=* prevails over -dumpdir, however, the explicit
    5237              :      -dumpdir is discarded, as if it wasn't there.  The basename of
    5238              :      the implicit linker output, a.out or a.exe, becomes a- as the aux
    5239              :      output prefix for all compilations:
    5240              : 
    5241              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c
    5242              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.o
    5243              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.o
    5244              :      && link
    5245              : 
    5246              :      A single -dumpbase, applying to multiple inputs, overrides the
    5247              :      linker output name, implied or explicit, as the aux output prefix:
    5248              : 
    5249              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c
    5250              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5251              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5252              :      && link
    5253              : 
    5254              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c -o dir/h.out
    5255              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5256              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5257              :      && link -o dir/h.out
    5258              : 
    5259              :      Now, if the linker output is NOT overridden as a prefix, but
    5260              :      -save-temps=* overrides implicit or explicit -dumpdir, the
    5261              :      effective dump dir combines the dir selected by the -save-temps=*
    5262              :      option with the basename of the specified or implied link output:
    5263              : 
    5264              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c -o dir/h.out
    5265              :      -> cc1 -dumpdir h- -dumpbase b.c -dumpbase-ext .c # h-b.o
    5266              :      && cc1 -dumpdir h- -dumpbase d.c -dumpbase-ext .c # h-d.o
    5267              :      && link -o dir/h.out
    5268              : 
    5269              :      # gcc [-dumpdir f] -save-temps=obj b.c d.c -o dir/h.out
    5270              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5271              :      && cc1 -dumpdir dir/h- -dumpbase d.c -dumpbase-ext .c # dir/h-d.o
    5272              :      && link -o dir/h.out
    5273              : 
    5274              :      But then again, a single -dumpbase applying to multiple inputs
    5275              :      gets used instead of the linker output basename in the combined
    5276              :      dumpdir:
    5277              : 
    5278              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=obj b.c d.c -o dir/h.out
    5279              :      -> cc1 -dumpdir dir/g- -dumpbase b.c -dumpbase-ext .c # dir/g-b.o
    5280              :      && cc1 -dumpdir dir/g- -dumpbase d.c -dumpbase-ext .c # dir/g-d.o
    5281              :      && link -o dir/h.out
    5282              : 
    5283              :      With a single input being compiled, the output basename does NOT
    5284              :      affect the dumpdir prefix.
    5285              : 
    5286              :      # gcc -save-temps=obj b.c -gsplit-dwarf -c -o dir/b.o
    5287              :      -> cc1 -dumpdir dir/ -dumpbase b.c -dumpbase-ext .c # dir/b.o dir/b.dwo
    5288              : 
    5289              :      but when compiling and linking even a single file, it does:
    5290              : 
    5291              :      # gcc -save-temps=obj b.c -o dir/h.out
    5292              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5293              : 
    5294              :      unless an explicit -dumpdir prevails:
    5295              : 
    5296              :      # gcc -save-temps[=obj] -dumpdir g- b.c -o dir/h.out
    5297              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5298              : 
    5299              :   */
    5300              : 
    5301       311716 :   bool explicit_dumpdir = dumpdir;
    5302              : 
    5303       311664 :   if ((!save_temps_overrides_dumpdir && explicit_dumpdir)
    5304       599946 :       || (output_file && not_actual_file_p (output_file)))
    5305              :     {
    5306              :       /* Do nothing.  */
    5307              :     }
    5308              : 
    5309              :   /* If -save-temps=obj and -o name, create the prefix to use for %b.
    5310              :      Otherwise just make -save-temps=obj the same as -save-temps=cwd.  */
    5311       287205 :   else if (save_temps_flag != SAVE_TEMPS_CWD && output_file != NULL)
    5312              :     {
    5313       266233 :       free (dumpdir);
    5314       266233 :       dumpdir = NULL;
    5315       266233 :       temp = lbasename (output_file);
    5316       266233 :       if (temp != output_file)
    5317       104897 :         dumpdir = xstrndup (output_file,
    5318       104897 :                             strlen (output_file) - strlen (temp));
    5319              :     }
    5320        20972 :   else if (dumpdir)
    5321              :     {
    5322            5 :       free (dumpdir);
    5323            5 :       dumpdir = NULL;
    5324              :     }
    5325              : 
    5326       311716 :   if (save_temps_flag)
    5327          468 :     save_temps_flag = SAVE_TEMPS_DUMP;
    5328              : 
    5329              :   /* If there is any pathname component in an explicit -dumpbase, it
    5330              :      overrides dumpdir entirely, so discard it right away.  Although
    5331              :      the presence of an explicit -dumpdir matters for the driver, it
    5332              :      shouldn't matter for other processes, that get all that's needed
    5333              :      from the -dumpdir and -dumpbase always passed to them.  */
    5334       311716 :   if (dumpdir && dumpbase && lbasename (dumpbase) != dumpbase)
    5335              :     {
    5336        23347 :       free (dumpdir);
    5337        23347 :       dumpdir = NULL;
    5338              :     }
    5339              : 
    5340              :   /* Check that dumpbase_ext matches the end of dumpbase, drop it
    5341              :      otherwise.  */
    5342       311716 :   if (dumpbase_ext && dumpbase && *dumpbase)
    5343              :     {
    5344           20 :       int lendb = strlen (dumpbase);
    5345           20 :       int lendbx = strlen (dumpbase_ext);
    5346              : 
    5347              :       /* -dumpbase-ext must be a suffix proper; discard it if it
    5348              :           matches all of -dumpbase, as that would make for an empty
    5349              :           basename.  */
    5350           20 :       if (lendbx >= lendb
    5351           19 :           || strcmp (dumpbase + lendb - lendbx, dumpbase_ext) != 0)
    5352              :         {
    5353            1 :           free (dumpbase_ext);
    5354            1 :           dumpbase_ext = NULL;
    5355              :         }
    5356              :     }
    5357              : 
    5358              :   /* -dumpbase with multiple sources goes into dumpdir.  With a single
    5359              :      source, it does only if linking and if dumpdir was not explicitly
    5360              :      specified.  */
    5361        24899 :   if (dumpbase && *dumpbase
    5362       335141 :       && (single_input_file_index () == -2
    5363        23141 :           || (!have_c && !explicit_dumpdir)))
    5364              :     {
    5365          296 :       char *prefix;
    5366              : 
    5367          296 :       if (dumpbase_ext)
    5368              :         /* We checked that they match above.  */
    5369            6 :         dumpbase[strlen (dumpbase) - strlen (dumpbase_ext)] = '\0';
    5370              : 
    5371          296 :       if (dumpdir)
    5372           13 :         prefix = concat (dumpdir, dumpbase, "-", NULL);
    5373              :       else
    5374          283 :         prefix = concat (dumpbase, "-", NULL);
    5375              : 
    5376          296 :       free (dumpdir);
    5377          296 :       free (dumpbase);
    5378          296 :       free (dumpbase_ext);
    5379          296 :       dumpbase = dumpbase_ext = NULL;
    5380          296 :       dumpdir = prefix;
    5381          296 :       dumpdir_trailing_dash_added = true;
    5382              :     }
    5383              : 
    5384              :   /* If dumpbase was not brought into dumpdir but we're linking, bring
    5385              :      output_file into dumpdir unless dumpdir was explicitly specified.
    5386              :      The test for !explicit_dumpdir is further below, because we want
    5387              :      to use the obase computation for a ghost outbase, passed to
    5388              :      GCC_COLLECT_OPTIONS.  */
    5389       311420 :   else if (!have_c && (!explicit_dumpdir || (dumpbase && !*dumpbase)))
    5390              :     {
    5391              :       /* If we get here, we know dumpbase was not specified, or it was
    5392              :          specified as an empty string.  If it was anything else, it
    5393              :          would have combined with dumpdir above, because the condition
    5394              :          for dumpbase to be used when present is broader than the
    5395              :          condition that gets us here.  */
    5396       115334 :       gcc_assert (!dumpbase || !*dumpbase);
    5397              : 
    5398       115334 :       const char *obase;
    5399       115334 :       char *tofree = NULL;
    5400       115334 :       if (!output_file || not_actual_file_p (output_file))
    5401              :         obase = "a";
    5402              :       else
    5403              :         {
    5404        97759 :           obase = lbasename (output_file);
    5405        97759 :           size_t blen = strlen (obase), xlen;
    5406              :           /* Drop the suffix if it's dumpbase_ext, if given,
    5407              :              otherwise .exe or the target executable suffix, or if the
    5408              :              output was explicitly named a.out, but not otherwise.  */
    5409        97759 :           if (dumpbase_ext
    5410        97759 :               ? (blen > (xlen = strlen (dumpbase_ext))
    5411          227 :                  && strcmp ((temp = (obase + blen - xlen)),
    5412              :                             dumpbase_ext) == 0)
    5413        97532 :               : ((temp = strrchr (obase + 1, '.'))
    5414        95679 :                  && (xlen = strlen (temp))
    5415       193211 :                  && (strcmp (temp, ".exe") == 0
    5416              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    5417              :                      || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
    5418              : #endif
    5419         8529 :                      || strcmp (obase, "a.out") == 0)))
    5420              :             {
    5421        87403 :               tofree = xstrndup (obase, blen - xlen);
    5422        87403 :               obase = tofree;
    5423              :             }
    5424              :         }
    5425              : 
    5426              :       /* We wish to save this basename to the -dumpdir passed through
    5427              :          GCC_COLLECT_OPTIONS within maybe_run_linker, for e.g. LTO,
    5428              :          but we do NOT wish to add it to e.g. %b, so we keep
    5429              :          outbase_length as zero.  */
    5430       115334 :       gcc_assert (!outbase);
    5431       115334 :       outbase_length = 0;
    5432              : 
    5433              :       /* If we're building [dir1/]foo[.exe] out of a single input
    5434              :          [dir2/]foo.c that shares the same basename, dump to
    5435              :          [dir2/]foo.c.* rather than duplicating the basename into
    5436              :          [dir2/]foo-foo.c.*.  */
    5437       115334 :       int idxin;
    5438       115334 :       if (dumpbase
    5439       115334 :           || ((idxin = single_input_file_index ()) >= 0
    5440        88396 :               && adds_single_suffix_p (lbasename (infiles[idxin].name),
    5441              :                                        obase)))
    5442              :         {
    5443        80965 :           if (obase == tofree)
    5444        79205 :             outbase = tofree;
    5445              :           else
    5446              :             {
    5447         1760 :               outbase = xstrdup (obase);
    5448         1760 :               free (tofree);
    5449              :             }
    5450       115334 :           obase = tofree = NULL;
    5451              :         }
    5452              :       else
    5453              :         {
    5454        34369 :           if (dumpdir)
    5455              :             {
    5456        14383 :               char *p = concat (dumpdir, obase, "-", NULL);
    5457        14383 :               free (dumpdir);
    5458        14383 :               dumpdir = p;
    5459              :             }
    5460              :           else
    5461        19986 :             dumpdir = concat (obase, "-", NULL);
    5462              : 
    5463        34369 :           dumpdir_trailing_dash_added = true;
    5464              : 
    5465        34369 :           free (tofree);
    5466        34369 :           obase = tofree = NULL;
    5467              :         }
    5468              : 
    5469       115334 :       if (!explicit_dumpdir || dumpbase)
    5470              :         {
    5471              :           /* Absent -dumpbase and present -dumpbase-ext have been applied
    5472              :              to the linker output name, so compute fresh defaults for each
    5473              :              compilation.  */
    5474       115334 :           free (dumpbase_ext);
    5475       115334 :           dumpbase_ext = NULL;
    5476              :         }
    5477              :     }
    5478              : 
    5479              :   /* Now, if we're compiling, or if we haven't used the dumpbase
    5480              :      above, then outbase (%B) is derived from dumpbase, if given, or
    5481              :      from the output name, given or implied.  We can't precompute
    5482              :      implied output names, but that's ok, since they're derived from
    5483              :      input names.  Just make sure we skip this if dumpbase is the
    5484              :      empty string: we want to use input names then, so don't set
    5485              :      outbase.  */
    5486       311716 :   if ((dumpbase || have_c)
    5487       197772 :       && !(dumpbase && !*dumpbase))
    5488              :     {
    5489       196298 :       gcc_assert (!outbase);
    5490              : 
    5491       196298 :       if (dumpbase)
    5492              :         {
    5493        23129 :           gcc_assert (single_input_file_index () != -2);
    5494              :           /* We do not want lbasename here; dumpbase with dirnames
    5495              :              overrides dumpdir entirely, even if dumpdir is
    5496              :              specified.  */
    5497        23129 :           if (dumpbase_ext)
    5498              :             /* We've already checked above that the suffix matches.  */
    5499           13 :             outbase = xstrndup (dumpbase,
    5500           13 :                                 strlen (dumpbase) - strlen (dumpbase_ext));
    5501              :           else
    5502        23116 :             outbase = xstrdup (dumpbase);
    5503              :         }
    5504       173169 :       else if (output_file && !not_actual_file_p (output_file))
    5505              :         {
    5506       168711 :           outbase = xstrdup (lbasename (output_file));
    5507       168711 :           char *p = strrchr (outbase + 1, '.');
    5508       168711 :           if (p)
    5509       168711 :             *p = '\0';
    5510              :         }
    5511              : 
    5512       196298 :       if (outbase)
    5513       191840 :         outbase_length = strlen (outbase);
    5514              :     }
    5515              : 
    5516              :   /* If there is any pathname component in an explicit -dumpbase, do
    5517              :      not use dumpdir, but retain it to pass it on to the compiler.  */
    5518       311716 :   if (dumpdir)
    5519       125253 :     dumpdir_length = strlen (dumpdir);
    5520              :   else
    5521       186463 :     dumpdir_length = 0;
    5522              : 
    5523              :   /* Check that dumpbase_ext, if still present, still matches the end
    5524              :      of dumpbase, if present, and drop it otherwise.  We only retained
    5525              :      it above when dumpbase was absent to maybe use it to drop the
    5526              :      extension from output_name before combining it with dumpdir.  We
    5527              :      won't deal with -dumpbase-ext when -dumpbase is not explicitly
    5528              :      given, even if just to activate backward-compatible dumpbase:
    5529              :      dropping it on the floor is correct, expected and documented
    5530              :      behavior.  Attempting to deal with a -dumpbase-ext that might
    5531              :      match the end of some input filename, or of the combination of
    5532              :      the output basename with the suffix of the input filename,
    5533              :      possible with an intermediate .gk extension for -fcompare-debug,
    5534              :      is just calling for trouble.  */
    5535       311716 :   if (dumpbase_ext)
    5536              :     {
    5537           22 :       if (!dumpbase || !*dumpbase)
    5538              :         {
    5539            9 :           free (dumpbase_ext);
    5540            9 :           dumpbase_ext = NULL;
    5541              :         }
    5542              :       else
    5543           13 :         gcc_assert (strcmp (dumpbase + strlen (dumpbase)
    5544              :                             - strlen (dumpbase_ext), dumpbase_ext) == 0);
    5545              :     }
    5546              : 
    5547       311716 :   if (save_temps_flag && use_pipes)
    5548              :     {
    5549              :       /* -save-temps overrides -pipe, so that temp files are produced */
    5550            0 :       if (save_temps_flag)
    5551            0 :         warning (0, "%<-pipe%> ignored because %<-save-temps%> specified");
    5552            0 :       use_pipes = 0;
    5553              :     }
    5554              : 
    5555       311716 :   if (!compare_debug)
    5556              :     {
    5557       311081 :       const char *gcd = env.get ("GCC_COMPARE_DEBUG");
    5558              : 
    5559       311081 :       if (gcd && gcd[0] == '-')
    5560              :         {
    5561            0 :           compare_debug = 2;
    5562            0 :           compare_debug_opt = gcd;
    5563              :         }
    5564            0 :       else if (gcd && *gcd && strcmp (gcd, "0"))
    5565              :         {
    5566            0 :           compare_debug = 3;
    5567            0 :           compare_debug_opt = "-gtoggle";
    5568              :         }
    5569              :     }
    5570          635 :   else if (compare_debug < 0)
    5571              :     {
    5572            0 :       compare_debug = 0;
    5573            0 :       gcc_assert (!compare_debug_opt);
    5574              :     }
    5575              : 
    5576              :   /* Set up the search paths.  We add directories that we expect to
    5577              :      contain GNU Toolchain components before directories specified by
    5578              :      the machine description so that we will find GNU components (like
    5579              :      the GNU assembler) before those of the host system.  */
    5580              : 
    5581              :   /* If we don't know where the toolchain has been installed, use the
    5582              :      configured-in locations.  */
    5583       311716 :   if (!gcc_exec_prefix)
    5584              :     {
    5585              : #ifndef OS2
    5586            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
    5587              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5588            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
    5589              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5590            0 :       add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
    5591              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5592              : #endif
    5593            0 :       add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
    5594              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5595              :     }
    5596              : 
    5597       311716 :   gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
    5598       311716 :   tooldir_prefix2 = concat (tooldir_base_prefix, spec_machine,
    5599              :                             dir_separator_str, NULL);
    5600              : 
    5601              :   /* Look for tools relative to the location from which the driver is
    5602              :      running, or, if that is not available, the configured prefix.  */
    5603       311716 :   tooldir_prefix
    5604       623432 :     = concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    5605              :               spec_host_machine, dir_separator_str, spec_version,
    5606              :               accel_dir_suffix, dir_separator_str, tooldir_prefix2, NULL);
    5607       311716 :   free (tooldir_prefix2);
    5608              : 
    5609       311716 :   add_prefix (&exec_prefixes,
    5610       311716 :               concat (tooldir_prefix, "bin", dir_separator_str, NULL),
    5611              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 0);
    5612       311716 :   add_prefix (&startfile_prefixes,
    5613       311716 :               concat (tooldir_prefix, "lib", dir_separator_str, NULL),
    5614              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
    5615       311716 :   free (tooldir_prefix);
    5616              : 
    5617              : #if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
    5618              :   /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
    5619              :      then consider it to relocate with the rest of the GCC installation
    5620              :      if GCC_EXEC_PREFIX is set.
    5621              :      ``make_relative_prefix'' is not compiled for VMS, so don't call it.  */
    5622              :   if (target_system_root && !target_system_root_changed && gcc_exec_prefix)
    5623              :     {
    5624              :       char *tmp_prefix = get_relative_prefix (decoded_options[0].arg,
    5625              :                                               standard_bindir_prefix,
    5626              :                                               target_system_root);
    5627              :       if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
    5628              :         {
    5629              :           target_system_root = tmp_prefix;
    5630              :           target_system_root_changed = 1;
    5631              :         }
    5632              :     }
    5633              : #endif
    5634              : 
    5635              :   /* More prefixes are enabled in main, after we read the specs file
    5636              :      and determine whether this is cross-compilation or not.  */
    5637              : 
    5638       311716 :   if (n_infiles != 0 && n_infiles == last_language_n_infiles && spec_lang != 0)
    5639            0 :     warning (0, "%<-x %s%> after last input file has no effect", spec_lang);
    5640              : 
    5641              :   /* Synthesize -fcompare-debug flag from the GCC_COMPARE_DEBUG
    5642              :      environment variable.  */
    5643       311716 :   if (compare_debug == 2 || compare_debug == 3)
    5644              :     {
    5645            0 :       const char *opt = concat ("-fcompare-debug=", compare_debug_opt, NULL);
    5646            0 :       save_switch (opt, 0, NULL, false, true);
    5647            0 :       compare_debug = 1;
    5648              :     }
    5649              : 
    5650              :   /* Ensure we only invoke each subprocess once.  */
    5651       311716 :   if (n_infiles == 0
    5652         9996 :       && (print_subprocess_help || print_help_list || print_version))
    5653              :     {
    5654              :       /* Create a dummy input file, so that we can pass
    5655              :          the help option on to the various sub-processes.  */
    5656           78 :       add_infile ("help-dummy", "c");
    5657              :     }
    5658              : 
    5659              :   /* Decide if undefined variable references are allowed in specs.  */
    5660              : 
    5661              :   /* -v alone is safe. --version and --help alone or together are safe.  Note
    5662              :      that -v would make them unsafe, as they'd then be run for subprocesses as
    5663              :      well, the location of which might depend on variables possibly coming
    5664              :      from self-specs.  Note also that the command name is counted in
    5665              :      decoded_options_count.  */
    5666              : 
    5667       311716 :   unsigned help_version_count = 0;
    5668              : 
    5669       311716 :   if (print_version)
    5670           78 :     help_version_count++;
    5671              : 
    5672       311716 :   if (print_help_list)
    5673            4 :     help_version_count++;
    5674              : 
    5675       623432 :   spec_undefvar_allowed =
    5676         1658 :     ((verbose_flag && decoded_options_count == 2)
    5677       313296 :      || help_version_count == decoded_options_count - 1);
    5678              : 
    5679       311716 :   alloc_switch ();
    5680       311716 :   switches[n_switches].part1 = 0;
    5681       311716 :   alloc_infile ();
    5682       311716 :   infiles[n_infiles].name = 0;
    5683       311716 : }
    5684              : 
    5685              : /* Set COLLECT_GCC_OPTIONS in the environment.  If the value would
    5686              :    exceed COLLECT2_OPTIONS_MAX_LENGTH, spill it to a temporary
    5687              :    response file and set the variable to @<path> instead.  */
    5688              : 
    5689              : static void
    5690       851406 : xsetenv_collect_gcc_options (char *string)
    5691              : {
    5692       851406 :   if (strlen (string) <= COLLECT2_OPTIONS_MAX_LENGTH)
    5693              :     {
    5694       650527 :       xputenv (string);
    5695       650527 :       return;
    5696              :     }
    5697              : 
    5698       200879 :   static const char prefix[] = "COLLECT_GCC_OPTIONS=";
    5699       200879 :   gcc_assert (startswith (string, prefix));
    5700              : 
    5701              :   /* parse_options_from_collect_gcc_options expects argc to start
    5702              :      at 1, so push a placeholder argv[0].  */
    5703       200879 :   struct obstack argv_obstack;
    5704       200879 :   obstack_init (&argv_obstack);
    5705       200879 :   obstack_ptr_grow (&argv_obstack, const_cast<char *> (progname));
    5706       200879 :   int argc;
    5707       200879 :   parse_options_from_collect_gcc_options (string + sizeof (prefix) - 1,
    5708              :                                           &argv_obstack, &argc);
    5709       200879 :   char **argv = XOBFINISH (&argv_obstack, char **);
    5710              : 
    5711       200879 :   char *temp_file = make_temp_file ("");
    5712       200879 :   FILE *f = fopen (temp_file, "wb");
    5713       200879 :   if (f == nullptr)
    5714            0 :     fatal_error (input_location,
    5715              :                  "cannot open response file %qs: %m", temp_file);
    5716              :   /* writeargv walks until NULL; skip our placeholder argv[0].  */
    5717       200879 :   if (writeargv (argv + 1, f) != 0)
    5718            0 :     fatal_error (input_location,
    5719              :                  "cannot write response file %qs: %m", temp_file);
    5720       200879 :   if (fclose (f) != 0)
    5721            0 :     fatal_error (input_location,
    5722              :                  "cannot close response file %qs: %m", temp_file);
    5723              : 
    5724       200879 :   char *env_val = concat (prefix, "@", temp_file, nullptr);
    5725              :   /* Delete on both success and failure unless -save-temps.  */
    5726       200879 :   record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
    5727       200879 :   obstack_free (&argv_obstack, nullptr);
    5728       200879 :   xputenv (env_val);
    5729              : }
    5730              : 
    5731              : /* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
    5732              :    and place that in the environment.  */
    5733              : 
    5734              : static void
    5735       851406 : set_collect_gcc_options (void)
    5736              : {
    5737       851406 :   int i;
    5738       851406 :   int first_time;
    5739              : 
    5740              :   /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
    5741              :      the compiler.  */
    5742       851406 :   obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
    5743              :                 sizeof ("COLLECT_GCC_OPTIONS=") - 1);
    5744              : 
    5745       851406 :   first_time = true;
    5746     20503742 :   for (i = 0; (int) i < n_switches; i++)
    5747              :     {
    5748     19652336 :       const char *const *args;
    5749     19652336 :       const char *p, *q;
    5750     19652336 :       if (!first_time)
    5751     18800930 :         obstack_grow (&collect_obstack, " ", 1);
    5752              : 
    5753     19652336 :       first_time = false;
    5754              : 
    5755              :       /* Ignore elided switches.  */
    5756     19787449 :       if ((switches[i].live_cond
    5757     19652336 :            & (SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC))
    5758              :           == SWITCH_IGNORE)
    5759       135113 :         continue;
    5760              : 
    5761     19517223 :       obstack_grow (&collect_obstack, "'-", 2);
    5762     19517223 :       q = switches[i].part1;
    5763     19517223 :       while ((p = strchr (q, '\'')))
    5764              :         {
    5765            0 :           obstack_grow (&collect_obstack, q, p - q);
    5766            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5767            0 :           q = ++p;
    5768              :         }
    5769     19517223 :       obstack_grow (&collect_obstack, q, strlen (q));
    5770     19517223 :       obstack_grow (&collect_obstack, "'", 1);
    5771              : 
    5772     23785700 :       for (args = switches[i].args; args && *args; args++)
    5773              :         {
    5774      4268477 :           obstack_grow (&collect_obstack, " '", 2);
    5775      4268477 :           q = *args;
    5776      4268477 :           while ((p = strchr (q, '\'')))
    5777              :             {
    5778            0 :               obstack_grow (&collect_obstack, q, p - q);
    5779            0 :               obstack_grow (&collect_obstack, "'\\''", 4);
    5780            0 :               q = ++p;
    5781              :             }
    5782      4268477 :           obstack_grow (&collect_obstack, q, strlen (q));
    5783      4268477 :           obstack_grow (&collect_obstack, "'", 1);
    5784              :         }
    5785              :     }
    5786              : 
    5787       851406 :   if (dumpdir)
    5788              :     {
    5789       598441 :       if (!first_time)
    5790       598441 :         obstack_grow (&collect_obstack, " ", 1);
    5791       598441 :       first_time = false;
    5792              : 
    5793       598441 :       obstack_grow (&collect_obstack, "'-dumpdir' '", 12);
    5794       598441 :       const char *p, *q;
    5795              : 
    5796       598441 :       q = dumpdir;
    5797       598441 :       while ((p = strchr (q, '\'')))
    5798              :         {
    5799            0 :           obstack_grow (&collect_obstack, q, p - q);
    5800            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5801            0 :           q = ++p;
    5802              :         }
    5803       598441 :       obstack_grow (&collect_obstack, q, strlen (q));
    5804              : 
    5805       598441 :       obstack_grow (&collect_obstack, "'", 1);
    5806              :     }
    5807              : 
    5808       851406 :   obstack_grow (&collect_obstack, "\0", 1);
    5809       851406 :   xsetenv_collect_gcc_options (XOBFINISH (&collect_obstack, char *));
    5810       851406 : }
    5811              : 
    5812              : /* Process a spec string, accumulating and running commands.  */
    5813              : 
    5814              : /* These variables describe the input file name.
    5815              :    input_file_number is the index on outfiles of this file,
    5816              :    so that the output file name can be stored for later use by %o.
    5817              :    input_basename is the start of the part of the input file
    5818              :    sans all directory names, and basename_length is the number
    5819              :    of characters starting there excluding the suffix .c or whatever.  */
    5820              : 
    5821              : static const char *gcc_input_filename;
    5822              : static int input_file_number;
    5823              : size_t input_filename_length;
    5824              : static int basename_length;
    5825              : static int suffixed_basename_length;
    5826              : static const char *input_basename;
    5827              : static const char *input_suffix;
    5828              : #ifndef HOST_LACKS_INODE_NUMBERS
    5829              : static struct stat input_stat;
    5830              : #endif
    5831              : static int input_stat_set;
    5832              : 
    5833              : /* The compiler used to process the current input file.  */
    5834              : static struct compiler *input_file_compiler;
    5835              : 
    5836              : /* These are variables used within do_spec and do_spec_1.  */
    5837              : 
    5838              : /* Nonzero if an arg has been started and not yet terminated
    5839              :    (with space, tab or newline).  */
    5840              : static int arg_going;
    5841              : 
    5842              : /* Nonzero means %d or %g has been seen; the next arg to be terminated
    5843              :    is a temporary file name.  */
    5844              : static int delete_this_arg;
    5845              : 
    5846              : /* Nonzero means %w has been seen; the next arg to be terminated
    5847              :    is the output file name of this compilation.  */
    5848              : static int this_is_output_file;
    5849              : 
    5850              : /* Nonzero means %s has been seen; the next arg to be terminated
    5851              :    is the name of a library file and we should try the standard
    5852              :    search dirs for it.  */
    5853              : static int this_is_library_file;
    5854              : 
    5855              : /* Nonzero means %T has been seen; the next arg to be terminated
    5856              :    is the name of a linker script and we should try all of the
    5857              :    standard search dirs for it.  If it is found insert a --script
    5858              :    command line switch and then substitute the full path in place,
    5859              :    otherwise generate an error message.  */
    5860              : static int this_is_linker_script;
    5861              : 
    5862              : /* Nonzero means that the input of this command is coming from a pipe.  */
    5863              : static int input_from_pipe;
    5864              : 
    5865              : /* Nonnull means substitute this for any suffix when outputting a switches
    5866              :    arguments.  */
    5867              : static const char *suffix_subst;
    5868              : 
    5869              : /* If there is an argument being accumulated, terminate it and store it.  */
    5870              : 
    5871              : static void
    5872     82984280 : end_going_arg (void)
    5873              : {
    5874     82984280 :   if (arg_going)
    5875              :     {
    5876     19519707 :       const char *string;
    5877              : 
    5878     19519707 :       obstack_1grow (&obstack, 0);
    5879     19519707 :       string = XOBFINISH (&obstack, const char *);
    5880     19519707 :       if (this_is_library_file)
    5881       554225 :         string = find_file (string);
    5882     19519707 :       if (this_is_linker_script)
    5883              :         {
    5884            0 :           char * full_script_path = find_a_file (&startfile_prefixes, string, true);
    5885              : 
    5886            0 :           if (full_script_path == NULL)
    5887              :             {
    5888            0 :               error ("unable to locate default linker script %qs in the library search paths", string);
    5889              :               /* Script was not found on search path.  */
    5890            0 :               return;
    5891              :             }
    5892            0 :           store_arg ("--script", false, false);
    5893            0 :           string = full_script_path;
    5894              :         }
    5895     19519707 :       store_arg (string, delete_this_arg, this_is_output_file);
    5896     19519707 :       if (this_is_output_file)
    5897       102660 :         outfiles[input_file_number] = string;
    5898     19519707 :       arg_going = 0;
    5899              :     }
    5900              : }
    5901              : 
    5902              : 
    5903              : /* Parse the WRAPPER string which is a comma separated list of the command line
    5904              :    and insert them into the beginning of argbuf.  */
    5905              : 
    5906              : static void
    5907            0 : insert_wrapper (const char *wrapper)
    5908              : {
    5909            0 :   int n = 0;
    5910            0 :   int i;
    5911            0 :   char *buf = xstrdup (wrapper);
    5912            0 :   char *p = buf;
    5913            0 :   unsigned int old_length = argbuf.length ();
    5914              : 
    5915            0 :   do
    5916              :     {
    5917            0 :       n++;
    5918            0 :       while (*p == ',')
    5919            0 :         p++;
    5920              :     }
    5921            0 :   while ((p = strchr (p, ',')) != NULL);
    5922              : 
    5923            0 :   argbuf.safe_grow (old_length + n, true);
    5924            0 :   memmove (argbuf.address () + n,
    5925            0 :            argbuf.address (),
    5926            0 :            old_length * sizeof (const_char_p));
    5927              : 
    5928            0 :   i = 0;
    5929            0 :   p = buf;
    5930              :   do
    5931              :     {
    5932            0 :       while (*p == ',')
    5933              :         {
    5934            0 :           *p = 0;
    5935            0 :           p++;
    5936              :         }
    5937            0 :       argbuf[i] = p;
    5938            0 :       i++;
    5939              :     }
    5940            0 :   while ((p = strchr (p, ',')) != NULL);
    5941            0 :   gcc_assert (i == n);
    5942            0 : }
    5943              : 
    5944              : /* Process the spec SPEC and run the commands specified therein.
    5945              :    Returns 0 if the spec is successfully processed; -1 if failed.  */
    5946              : 
    5947              : int
    5948       585102 : do_spec (const char *spec)
    5949              : {
    5950       585102 :   int value;
    5951              : 
    5952       585102 :   value = do_spec_2 (spec, NULL);
    5953              : 
    5954              :   /* Force out any unfinished command.
    5955              :      If -pipe, this forces out the last command if it ended in `|'.  */
    5956       585102 :   if (value == 0)
    5957              :     {
    5958       579178 :       if (argbuf.length () > 0
    5959       870006 :           && !strcmp (argbuf.last (), "|"))
    5960            0 :         argbuf.pop ();
    5961              : 
    5962       579178 :       set_collect_gcc_options ();
    5963              : 
    5964       579178 :       if (argbuf.length () > 0)
    5965       290828 :         value = execute ();
    5966              :     }
    5967              : 
    5968       585102 :   return value;
    5969              : }
    5970              : 
    5971              : /* Process the spec SPEC, with SOFT_MATCHED_PART designating the current value
    5972              :    of a matched * pattern which may be re-injected by way of %*.  */
    5973              : 
    5974              : static int
    5975      5527240 : do_spec_2 (const char *spec, const char *soft_matched_part)
    5976              : {
    5977      5527240 :   int result;
    5978              : 
    5979      5527240 :   clear_args ();
    5980      5527240 :   arg_going = 0;
    5981      5527240 :   delete_this_arg = 0;
    5982      5527240 :   this_is_output_file = 0;
    5983      5527240 :   this_is_library_file = 0;
    5984      5527240 :   this_is_linker_script = 0;
    5985      5527240 :   input_from_pipe = 0;
    5986      5527240 :   suffix_subst = NULL;
    5987              : 
    5988      5527240 :   result = do_spec_1 (spec, 0, soft_matched_part);
    5989              : 
    5990      5527240 :   end_going_arg ();
    5991              : 
    5992      5527240 :   return result;
    5993              : }
    5994              : 
    5995              : /* Process the given spec string and add any new options to the end
    5996              :    of the switches/n_switches array.  */
    5997              : 
    5998              : static void
    5999      3118480 : do_option_spec (const char *name, const char *spec)
    6000              : {
    6001      3118480 :   unsigned int i, value_count, value_len;
    6002      3118480 :   const char *p, *q, *value;
    6003      3118480 :   char *tmp_spec, *tmp_spec_p;
    6004              : 
    6005      3118480 :   if (configure_default_options[0].name == NULL)
    6006              :     return;
    6007              : 
    6008      8419896 :   for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
    6009      5925112 :     if (strcmp (configure_default_options[i].name, name) == 0)
    6010              :       break;
    6011      3118480 :   if (i == ARRAY_SIZE (configure_default_options))
    6012              :     return;
    6013              : 
    6014       623696 :   value = configure_default_options[i].value;
    6015       623696 :   value_len = strlen (value);
    6016              : 
    6017              :   /* Compute the size of the final spec.  */
    6018       623696 :   value_count = 0;
    6019       623696 :   p = spec;
    6020      1247392 :   while ((p = strstr (p, "%(VALUE)")) != NULL)
    6021              :     {
    6022       623696 :       p ++;
    6023       623696 :       value_count ++;
    6024              :     }
    6025              : 
    6026              :   /* Replace each %(VALUE) by the specified value.  */
    6027       623696 :   tmp_spec = (char *) alloca (strlen (spec) + 1
    6028              :                      + value_count * (value_len - strlen ("%(VALUE)")));
    6029       623696 :   tmp_spec_p = tmp_spec;
    6030       623696 :   q = spec;
    6031      1247392 :   while ((p = strstr (q, "%(VALUE)")) != NULL)
    6032              :     {
    6033       623696 :       memcpy (tmp_spec_p, q, p - q);
    6034       623696 :       tmp_spec_p = tmp_spec_p + (p - q);
    6035       623696 :       memcpy (tmp_spec_p, value, value_len);
    6036       623696 :       tmp_spec_p += value_len;
    6037       623696 :       q = p + strlen ("%(VALUE)");
    6038              :     }
    6039       623696 :   strcpy (tmp_spec_p, q);
    6040              : 
    6041       623696 :   do_self_spec (tmp_spec);
    6042              : }
    6043              : 
    6044              : /* Process the given spec string and add any new options to the end
    6045              :    of the switches/n_switches array.  */
    6046              : 
    6047              : static void
    6048      2806977 : do_self_spec (const char *spec)
    6049              : {
    6050      2806977 :   int i;
    6051              : 
    6052      2806977 :   do_spec_2 (spec, NULL);
    6053      2806977 :   do_spec_1 (" ", 0, NULL);
    6054              : 
    6055              :   /* Mark %<S switches processed by do_self_spec to be ignored permanently.
    6056              :      do_self_specs adds the replacements to switches array, so it shouldn't
    6057              :      be processed afterwards.  */
    6058     67519646 :   for (i = 0; i < n_switches; i++)
    6059     61905692 :     if ((switches[i].live_cond & SWITCH_IGNORE))
    6060          683 :       switches[i].live_cond |= SWITCH_IGNORE_PERMANENTLY;
    6061              : 
    6062      2806977 :   if (argbuf.length () > 0)
    6063              :     {
    6064       588498 :       const char **argbuf_copy;
    6065       588498 :       struct cl_decoded_option *decoded_options;
    6066       588498 :       struct cl_option_handlers handlers;
    6067       588498 :       unsigned int decoded_options_count;
    6068       588498 :       unsigned int j;
    6069              : 
    6070              :       /* Create a copy of argbuf with a dummy argv[0] entry for
    6071              :          decode_cmdline_options_to_array.  */
    6072       588498 :       argbuf_copy = XNEWVEC (const char *,
    6073              :                              argbuf.length () + 1);
    6074       588498 :       argbuf_copy[0] = "";
    6075       588498 :       memcpy (argbuf_copy + 1, argbuf.address (),
    6076       588498 :               argbuf.length () * sizeof (const char *));
    6077              : 
    6078      1176996 :       decode_cmdline_options_to_array (argbuf.length () + 1,
    6079              :                                        argbuf_copy,
    6080              :                                        CL_DRIVER, &decoded_options,
    6081              :                                        &decoded_options_count);
    6082       588498 :       free (argbuf_copy);
    6083              : 
    6084       588498 :       set_option_handlers (&handlers);
    6085              : 
    6086      1179536 :       for (j = 1; j < decoded_options_count; j++)
    6087              :         {
    6088       591038 :           switch (decoded_options[j].opt_index)
    6089              :             {
    6090            0 :             case OPT_SPECIAL_input_file:
    6091              :               /* Specs should only generate options, not input
    6092              :                  files.  */
    6093            0 :               if (strcmp (decoded_options[j].arg, "-") != 0)
    6094            0 :                 fatal_error (input_location,
    6095              :                              "switch %qs does not start with %<-%>",
    6096              :                              decoded_options[j].arg);
    6097              :               else
    6098            0 :                 fatal_error (input_location,
    6099              :                              "spec-generated switch is just %<-%>");
    6100         1270 :               break;
    6101              : 
    6102         1270 :             case OPT_fcompare_debug_second:
    6103         1270 :             case OPT_fcompare_debug:
    6104         1270 :             case OPT_fcompare_debug_:
    6105         1270 :             case OPT_o:
    6106              :               /* Avoid duplicate processing of some options from
    6107              :                  compare-debug specs; just save them here.  */
    6108         1270 :               save_switch (decoded_options[j].canonical_option[0],
    6109         1270 :                            (decoded_options[j].canonical_option_num_elements
    6110              :                             - 1),
    6111         1270 :                            &decoded_options[j].canonical_option[1], false, true);
    6112         1270 :               break;
    6113              : 
    6114       589768 :             default:
    6115       589768 :               read_cmdline_option (&global_options, &global_options_set,
    6116              :                                    decoded_options + j, UNKNOWN_LOCATION,
    6117              :                                    CL_DRIVER, &handlers, global_dc);
    6118       589768 :               break;
    6119              :             }
    6120              :         }
    6121              : 
    6122       588498 :       free (decoded_options);
    6123              : 
    6124       588498 :       alloc_switch ();
    6125       588498 :       switches[n_switches].part1 = 0;
    6126              :     }
    6127      2806977 : }
    6128              : 
    6129              : /* Callback for processing %D and %I specs.  */
    6130              : 
    6131              : struct spec_path {
    6132              :   const char *option;
    6133              :   const char *append;
    6134              :   size_t append_len;
    6135              :   bool omit_relative;
    6136              :   bool separate_options;
    6137              :   bool realpaths;
    6138              : 
    6139              :   void *operator() (char *path, bool);
    6140              : };
    6141              : 
    6142              : void *
    6143      3426388 : spec_path::operator() (char *path, bool)
    6144              : {
    6145      3426388 :   size_t len = 0;
    6146      3426388 :   char save = 0;
    6147              : 
    6148              :   /* The path must exist; we want to resolve it to the realpath so that this
    6149              :      can be embedded as a runpath.  */
    6150      3426388 :   if (realpaths)
    6151            0 :      path = lrealpath (path);
    6152              : 
    6153              :   /* However, if we failed to resolve it - perhaps because there was a bogus
    6154              :      -B option on the command line, then punt on this entry.  */
    6155      3426388 :   if (!path)
    6156              :     return NULL;
    6157              : 
    6158      3426388 :   if (omit_relative && !IS_ABSOLUTE_PATH (path))
    6159              :     return NULL;
    6160              : 
    6161      3426388 :   if (append_len != 0)
    6162              :     {
    6163      1424876 :       len = strlen (path);
    6164      1424876 :       memcpy (path + len, append, append_len + 1);
    6165              :     }
    6166              : 
    6167      3426388 :   if (!is_directory (path))
    6168              :     return NULL;
    6169              : 
    6170      1291802 :   do_spec_1 (option, 1, NULL);
    6171      1291802 :   if (separate_options)
    6172       463857 :     do_spec_1 (" ", 0, NULL);
    6173              : 
    6174      1291802 :   if (append_len == 0)
    6175              :     {
    6176       827945 :       len = strlen (path);
    6177       827945 :       save = path[len - 1];
    6178       827945 :       if (IS_DIR_SEPARATOR (path[len - 1]))
    6179       827945 :         path[len - 1] = '\0';
    6180              :     }
    6181              : 
    6182      1291802 :   do_spec_1 (path, 1, NULL);
    6183      1291802 :   do_spec_1 (" ", 0, NULL);
    6184              : 
    6185              :   /* Must not damage the original path.  */
    6186      1291802 :   if (append_len == 0)
    6187       827945 :     path[len - 1] = save;
    6188              : 
    6189              :   return NULL;
    6190              : }
    6191              : 
    6192              : /* True if we should compile INFILE. */
    6193              : 
    6194              : static bool
    6195        46681 : compile_input_file_p (struct infile *infile)
    6196              : {
    6197        29083 :   if ((!infile->language) || (infile->language[0] != '*'))
    6198        41932 :     if (infile->incompiler == input_file_compiler)
    6199            0 :       return true;
    6200              :   return false;
    6201              : }
    6202              : 
    6203              : /* Process each member of VEC as a spec.  */
    6204              : 
    6205              : static void
    6206       482505 : do_specs_vec (vec<char_p> vec)
    6207              : {
    6208       482623 :   for (char *opt : vec)
    6209              :     {
    6210           70 :       do_spec_1 (opt, 1, NULL);
    6211              :       /* Make each accumulated option a separate argument.  */
    6212           70 :       do_spec_1 (" ", 0, NULL);
    6213              :     }
    6214       482505 : }
    6215              : 
    6216              : /* Add options passed via -Xassembler or -Wa to COLLECT_AS_OPTIONS.  */
    6217              : 
    6218              : static void
    6219       311715 : putenv_COLLECT_AS_OPTIONS (vec<char_p> vec)
    6220              : {
    6221       311715 :   if (vec.is_empty ())
    6222       311715 :      return;
    6223              : 
    6224          103 :   obstack_init (&collect_obstack);
    6225          103 :   obstack_grow (&collect_obstack, "COLLECT_AS_OPTIONS=",
    6226              :                 strlen ("COLLECT_AS_OPTIONS="));
    6227              : 
    6228          103 :   char *opt;
    6229          103 :   unsigned ix;
    6230              : 
    6231          298 :   FOR_EACH_VEC_ELT (vec, ix, opt)
    6232              :     {
    6233          195 :       obstack_1grow (&collect_obstack, '\'');
    6234          195 :       obstack_grow (&collect_obstack, opt, strlen (opt));
    6235          195 :       obstack_1grow (&collect_obstack, '\'');
    6236          195 :       if (ix < vec.length () - 1)
    6237           92 :         obstack_1grow(&collect_obstack, ' ');
    6238              :     }
    6239              : 
    6240          103 :   obstack_1grow (&collect_obstack, '\0');
    6241          103 :   xputenv (XOBFINISH (&collect_obstack, char *));
    6242              : }
    6243              : 
    6244              : /* Process the sub-spec SPEC as a portion of a larger spec.
    6245              :    This is like processing a whole spec except that we do
    6246              :    not initialize at the beginning and we do not supply a
    6247              :    newline by default at the end.
    6248              :    INSWITCH nonzero means don't process %-sequences in SPEC;
    6249              :    in this case, % is treated as an ordinary character.
    6250              :    This is used while substituting switches.
    6251              :    INSWITCH nonzero also causes SPC not to terminate an argument.
    6252              : 
    6253              :    Value is zero unless a line was finished
    6254              :    and the command on that line reported an error.  */
    6255              : 
    6256              : static int
    6257     54360702 : do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
    6258              : {
    6259     54360702 :   const char *p = spec;
    6260     54360702 :   int c;
    6261     54360702 :   int i;
    6262     54360702 :   int value;
    6263              : 
    6264              :   /* If it's an empty string argument to a switch, keep it as is.  */
    6265     54360702 :   if (inswitch && !*p)
    6266            1 :     arg_going = 1;
    6267              : 
    6268    548533588 :   while ((c = *p++))
    6269              :     /* If substituting a switch, treat all chars like letters.
    6270              :        Otherwise, NL, SPC, TAB and % are special.  */
    6271    494222702 :     switch (inswitch ? 'a' : c)
    6272              :       {
    6273       272228 :       case '\n':
    6274       272228 :         end_going_arg ();
    6275              : 
    6276       272228 :         if (argbuf.length () > 0
    6277       544456 :             && !strcmp (argbuf.last (), "|"))
    6278              :           {
    6279              :             /* A `|' before the newline means use a pipe here,
    6280              :                but only if -pipe was specified.
    6281              :                Otherwise, execute now and don't pass the `|' as an arg.  */
    6282       173230 :             if (use_pipes)
    6283              :               {
    6284            0 :                 input_from_pipe = 1;
    6285            0 :                 break;
    6286              :               }
    6287              :             else
    6288       173230 :               argbuf.pop ();
    6289              :           }
    6290              : 
    6291       272228 :         set_collect_gcc_options ();
    6292              : 
    6293       272228 :         if (argbuf.length () > 0)
    6294              :           {
    6295       272228 :             value = execute ();
    6296       272228 :             if (value)
    6297              :               return value;
    6298              :           }
    6299              :         /* Reinitialize for a new command, and for a new argument.  */
    6300       266304 :         clear_args ();
    6301       266304 :         arg_going = 0;
    6302       266304 :         delete_this_arg = 0;
    6303       266304 :         this_is_output_file = 0;
    6304       266304 :         this_is_library_file = 0;
    6305       266304 :         this_is_linker_script = 0;
    6306       266304 :         input_from_pipe = 0;
    6307       266304 :         break;
    6308              : 
    6309       173230 :       case '|':
    6310       173230 :         end_going_arg ();
    6311              : 
    6312              :         /* Use pipe */
    6313       173230 :         obstack_1grow (&obstack, c);
    6314       173230 :         arg_going = 1;
    6315       173230 :         break;
    6316              : 
    6317     72201357 :       case '\t':
    6318     72201357 :       case ' ':
    6319     72201357 :         end_going_arg ();
    6320              : 
    6321              :         /* Reinitialize for a new argument.  */
    6322     72201357 :         delete_this_arg = 0;
    6323     72201357 :         this_is_output_file = 0;
    6324     72201357 :         this_is_library_file = 0;
    6325     72201357 :         this_is_linker_script = 0;
    6326     72201357 :         break;
    6327              : 
    6328     50878165 :       case '%':
    6329     50878165 :         switch (c = *p++)
    6330              :           {
    6331            0 :           case 0:
    6332            0 :             fatal_error (input_location, "spec %qs invalid", spec);
    6333              : 
    6334         3618 :           case 'b':
    6335              :             /* Don't use %b in the linker command.  */
    6336         3618 :             gcc_assert (suffixed_basename_length);
    6337         3618 :             if (!this_is_output_file && dumpdir_length)
    6338          709 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6339         3618 :             if (this_is_output_file || !outbase_length)
    6340         3276 :               obstack_grow (&obstack, input_basename, basename_length);
    6341              :             else
    6342          342 :               obstack_grow (&obstack, outbase, outbase_length);
    6343         3618 :             if (compare_debug < 0)
    6344            6 :               obstack_grow (&obstack, ".gk", 3);
    6345         3618 :             arg_going = 1;
    6346         3618 :             break;
    6347              : 
    6348           10 :           case 'B':
    6349              :             /* Don't use %B in the linker command.  */
    6350           10 :             gcc_assert (suffixed_basename_length);
    6351           10 :             if (!this_is_output_file && dumpdir_length)
    6352            0 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6353           10 :             if (this_is_output_file || !outbase_length)
    6354            5 :               obstack_grow (&obstack, input_basename, basename_length);
    6355              :             else
    6356            5 :               obstack_grow (&obstack, outbase, outbase_length);
    6357           10 :             if (compare_debug < 0)
    6358            3 :               obstack_grow (&obstack, ".gk", 3);
    6359           10 :             obstack_grow (&obstack, input_basename + basename_length,
    6360              :                           suffixed_basename_length - basename_length);
    6361              : 
    6362           10 :             arg_going = 1;
    6363           10 :             break;
    6364              : 
    6365       100147 :           case 'd':
    6366       100147 :             delete_this_arg = 2;
    6367       100147 :             break;
    6368              : 
    6369              :           /* Dump out the directories specified with LIBRARY_PATH,
    6370              :              followed by the absolute directories
    6371              :              that we search for startfiles.  */
    6372       108224 :           case 'D':
    6373       108224 :             {
    6374       108224 :               struct spec_path info;
    6375              : 
    6376       108224 :               info.option = "-L";
    6377       108224 :               info.append_len = 0;
    6378              : #ifdef RELATIVE_PREFIX_NOT_LINKDIR
    6379              :               /* Used on systems which record the specified -L dirs
    6380              :                  and use them to search for dynamic linking.
    6381              :                  Relative directories always come from -B,
    6382              :                  and it is better not to use them for searching
    6383              :                  at run time.  In particular, stage1 loses.  */
    6384              :               info.omit_relative = true;
    6385              : #else
    6386       108224 :               info.omit_relative = false;
    6387              : #endif
    6388       108224 :               info.separate_options = false;
    6389       108224 :               info.realpaths = false;
    6390              : 
    6391       108224 :               for_each_path (&startfile_prefixes, true, 0, info);
    6392              :             }
    6393       108224 :             break;
    6394              : 
    6395            0 :           case 'P':
    6396            0 :             {
    6397            0 :               struct spec_path info;
    6398              : 
    6399            0 :               info.option = RUNPATH_OPTION;
    6400            0 :               info.append_len = 0;
    6401            0 :               info.omit_relative = false;
    6402            0 :               info.separate_options = true;
    6403              :               /* We want to embed the actual paths that have the libraries.  */
    6404            0 :               info.realpaths = true;
    6405              : 
    6406            0 :               for_each_path (&startfile_prefixes, true, 0, info);
    6407              :             }
    6408            0 :             break;
    6409              : 
    6410              :           case 'e':
    6411              :             /* %efoo means report an error with `foo' as error message
    6412              :                and don't execute any more commands for this file.  */
    6413              :             {
    6414              :               const char *q = p;
    6415              :               char *buf;
    6416            0 :               while (*p != 0 && *p != '\n')
    6417            0 :                 p++;
    6418            0 :               buf = (char *) alloca (p - q + 1);
    6419            0 :               strncpy (buf, q, p - q);
    6420            0 :               buf[p - q] = 0;
    6421            0 :               error ("%s", _(buf));
    6422            0 :               return -1;
    6423              :             }
    6424              :             break;
    6425              :           case 'n':
    6426              :             /* %nfoo means report a notice with `foo' on stderr.  */
    6427              :             {
    6428              :               const char *q = p;
    6429              :               char *buf;
    6430            0 :               while (*p != 0 && *p != '\n')
    6431            0 :                 p++;
    6432            0 :               buf = (char *) alloca (p - q + 1);
    6433            0 :               strncpy (buf, q, p - q);
    6434            0 :               buf[p - q] = 0;
    6435            0 :               inform (UNKNOWN_LOCATION, "%s", _(buf));
    6436            0 :               if (*p)
    6437            0 :                 p++;
    6438              :             }
    6439              :             break;
    6440              : 
    6441          900 :           case 'j':
    6442          900 :             {
    6443          900 :               struct stat st;
    6444              : 
    6445              :               /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
    6446              :                  defined, and it is not a directory, and it is
    6447              :                  writable, use it.  Otherwise, treat this like any
    6448              :                  other temporary file.  */
    6449              : 
    6450          900 :               if ((!save_temps_flag)
    6451          900 :                   && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
    6452         1800 :                   && (access (HOST_BIT_BUCKET, W_OK) == 0))
    6453              :                 {
    6454          900 :                   obstack_grow (&obstack, HOST_BIT_BUCKET,
    6455              :                                 strlen (HOST_BIT_BUCKET));
    6456          900 :                   delete_this_arg = 0;
    6457          900 :                   arg_going = 1;
    6458          900 :                   break;
    6459              :                 }
    6460              :             }
    6461            0 :             goto create_temp_file;
    6462       173230 :           case '|':
    6463       173230 :             if (use_pipes)
    6464              :               {
    6465            0 :                 obstack_1grow (&obstack, '-');
    6466            0 :                 delete_this_arg = 0;
    6467            0 :                 arg_going = 1;
    6468              : 
    6469              :                 /* consume suffix */
    6470            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6471            0 :                   p++;
    6472            0 :                 if (p[0] == '%' && p[1] == 'O')
    6473            0 :                   p += 2;
    6474              : 
    6475              :                 break;
    6476              :               }
    6477       173230 :             goto create_temp_file;
    6478       167446 :           case 'm':
    6479       167446 :             if (use_pipes)
    6480              :               {
    6481              :                 /* consume suffix */
    6482            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6483            0 :                   p++;
    6484            0 :                 if (p[0] == '%' && p[1] == 'O')
    6485            0 :                   p += 2;
    6486              : 
    6487              :                 break;
    6488              :               }
    6489       167446 :             goto create_temp_file;
    6490       536549 :           case 'g':
    6491       536549 :           case 'u':
    6492       536549 :           case 'U':
    6493       536549 :           create_temp_file:
    6494       536549 :               {
    6495       536549 :                 struct temp_name *t;
    6496       536549 :                 int suffix_length;
    6497       536549 :                 const char *suffix = p;
    6498       536549 :                 char *saved_suffix = NULL;
    6499              : 
    6500      1598847 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6501      1062298 :                   p++;
    6502       536549 :                 suffix_length = p - suffix;
    6503       536549 :                 if (p[0] == '%' && p[1] == 'O')
    6504              :                   {
    6505       100369 :                     p += 2;
    6506              :                     /* We don't support extra suffix characters after %O.  */
    6507       100369 :                     if (*p == '.' || ISALNUM ((unsigned char) *p))
    6508            0 :                       fatal_error (input_location,
    6509              :                                    "spec %qs has invalid %<%%0%c%>", spec, *p);
    6510       100369 :                     if (suffix_length == 0)
    6511              :                       suffix = TARGET_OBJECT_SUFFIX;
    6512              :                     else
    6513              :                       {
    6514            0 :                         saved_suffix
    6515            0 :                           = XNEWVEC (char, suffix_length
    6516              :                                      + strlen (TARGET_OBJECT_SUFFIX) + 1);
    6517            0 :                         strncpy (saved_suffix, suffix, suffix_length);
    6518            0 :                         strcpy (saved_suffix + suffix_length,
    6519              :                                 TARGET_OBJECT_SUFFIX);
    6520              :                       }
    6521       100369 :                     suffix_length += strlen (TARGET_OBJECT_SUFFIX);
    6522              :                   }
    6523              : 
    6524       536549 :                 if (compare_debug < 0)
    6525              :                   {
    6526          626 :                     suffix = concat (".gk", suffix, NULL);
    6527          626 :                     suffix_length += 3;
    6528              :                   }
    6529              : 
    6530              :                 /* If -save-temps was specified, use that for the
    6531              :                    temp file.  */
    6532       536549 :                 if (save_temps_flag)
    6533              :                   {
    6534         1233 :                     char *tmp;
    6535         1233 :                     bool adjusted_suffix = false;
    6536         1233 :                     if (suffix_length
    6537         1233 :                         && !outbase_length && !basename_length
    6538          233 :                         && !dumpdir_trailing_dash_added)
    6539              :                       {
    6540           20 :                         adjusted_suffix = true;
    6541           20 :                         suffix++;
    6542           20 :                         suffix_length--;
    6543              :                       }
    6544         1233 :                     temp_filename_length
    6545         1233 :                       = dumpdir_length + suffix_length + 1;
    6546         1233 :                     if (outbase_length)
    6547           72 :                       temp_filename_length += outbase_length;
    6548              :                     else
    6549         1161 :                       temp_filename_length += basename_length;
    6550         1233 :                     tmp = (char *) alloca (temp_filename_length);
    6551         1233 :                     if (dumpdir_length)
    6552         1075 :                       memcpy (tmp, dumpdir, dumpdir_length);
    6553         1233 :                     if (outbase_length)
    6554           72 :                       memcpy (tmp + dumpdir_length, outbase,
    6555              :                               outbase_length);
    6556         1161 :                     else if (basename_length)
    6557          928 :                       memcpy (tmp + dumpdir_length, input_basename,
    6558              :                               basename_length);
    6559         1233 :                     memcpy (tmp + temp_filename_length - suffix_length - 1,
    6560              :                             suffix, suffix_length);
    6561         1233 :                     if (adjusted_suffix)
    6562              :                       {
    6563           20 :                         adjusted_suffix = false;
    6564           20 :                         suffix--;
    6565           20 :                         suffix_length++;
    6566              :                       }
    6567         1233 :                     tmp[temp_filename_length - 1] = '\0';
    6568         1233 :                     temp_filename = tmp;
    6569              : 
    6570         1233 :                     if (filename_cmp (temp_filename, gcc_input_filename) != 0)
    6571              :                       {
    6572              : #ifndef HOST_LACKS_INODE_NUMBERS
    6573         1233 :                         struct stat st_temp;
    6574              : 
    6575              :                         /* Note, set_input() resets input_stat_set to 0.  */
    6576         1233 :                         if (input_stat_set == 0)
    6577              :                           {
    6578          576 :                             input_stat_set = stat (gcc_input_filename,
    6579              :                                                    &input_stat);
    6580          576 :                             if (input_stat_set >= 0)
    6581          576 :                               input_stat_set = 1;
    6582              :                           }
    6583              : 
    6584              :                         /* If we have the stat for the gcc_input_filename
    6585              :                            and we can do the stat for the temp_filename
    6586              :                            then the they could still refer to the same
    6587              :                            file if st_dev/st_ino's are the same.  */
    6588         1233 :                         if (input_stat_set != 1
    6589         1233 :                             || stat (temp_filename, &st_temp) < 0
    6590          375 :                             || input_stat.st_dev != st_temp.st_dev
    6591         1247 :                             || input_stat.st_ino != st_temp.st_ino)
    6592              : #else
    6593              :                         /* Just compare canonical pathnames.  */
    6594              :                         char* input_realname = lrealpath (gcc_input_filename);
    6595              :                         char* temp_realname = lrealpath (temp_filename);
    6596              :                         bool files_differ = filename_cmp (input_realname, temp_realname);
    6597              :                         free (input_realname);
    6598              :                         free (temp_realname);
    6599              :                         if (files_differ)
    6600              : #endif
    6601              :                           {
    6602         1233 :                             temp_filename
    6603         1233 :                               = save_string (temp_filename,
    6604              :                                              temp_filename_length - 1);
    6605         1233 :                             obstack_grow (&obstack, temp_filename,
    6606              :                                                     temp_filename_length);
    6607         1233 :                             arg_going = 1;
    6608         1233 :                             delete_this_arg = 0;
    6609         1233 :                             break;
    6610              :                           }
    6611              :                       }
    6612              :                   }
    6613              : 
    6614              :                 /* See if we already have an association of %g/%u/%U and
    6615              :                    suffix.  */
    6616       915057 :                 for (t = temp_names; t; t = t->next)
    6617       554240 :                   if (t->length == suffix_length
    6618       370917 :                       && strncmp (t->suffix, suffix, suffix_length) == 0
    6619       178472 :                       && t->unique == (c == 'u' || c == 'U' || c == 'j'))
    6620              :                     break;
    6621              : 
    6622              :                 /* Make a new association if needed.  %u and %j
    6623              :                    require one.  */
    6624       535316 :                 if (t == 0 || c == 'u' || c == 'j')
    6625              :                   {
    6626       364590 :                     if (t == 0)
    6627              :                       {
    6628       360817 :                         t = XNEW (struct temp_name);
    6629       360817 :                         t->next = temp_names;
    6630       360817 :                         temp_names = t;
    6631              :                       }
    6632       364590 :                     t->length = suffix_length;
    6633       364590 :                     if (saved_suffix)
    6634              :                       {
    6635            0 :                         t->suffix = saved_suffix;
    6636            0 :                         saved_suffix = NULL;
    6637              :                       }
    6638              :                     else
    6639       364590 :                       t->suffix = save_string (suffix, suffix_length);
    6640       364590 :                     t->unique = (c == 'u' || c == 'U' || c == 'j');
    6641       364590 :                     temp_filename = make_temp_file (t->suffix);
    6642       364590 :                     temp_filename_length = strlen (temp_filename);
    6643       364590 :                     t->filename = temp_filename;
    6644       364590 :                     t->filename_length = temp_filename_length;
    6645              :                   }
    6646              : 
    6647       535316 :                 free (saved_suffix);
    6648              : 
    6649       535316 :                 obstack_grow (&obstack, t->filename, t->filename_length);
    6650       535316 :                 delete_this_arg = 1;
    6651              :               }
    6652       535316 :             arg_going = 1;
    6653       535316 :             break;
    6654              : 
    6655       298327 :           case 'i':
    6656       298327 :             if (combine_inputs)
    6657              :               {
    6658              :                 /* We are going to expand `%i' into `@FILE', where FILE
    6659              :                    is a newly-created temporary filename.  The filenames
    6660              :                    that would usually be expanded in place of %o will be
    6661              :                    written to the temporary file.  */
    6662        32754 :                 if (at_file_supplied)
    6663        13745 :                   open_at_file ();
    6664              : 
    6665        79435 :                 for (i = 0; (int) i < n_infiles; i++)
    6666        93362 :                   if (compile_input_file_p (&infiles[i]))
    6667              :                     {
    6668        41870 :                       store_arg (infiles[i].name, 0, 0);
    6669        41870 :                       infiles[i].compiled = true;
    6670              :                     }
    6671              : 
    6672        32754 :                 if (at_file_supplied)
    6673        13745 :                   close_at_file ();
    6674              :               }
    6675              :             else
    6676              :               {
    6677       265573 :                 obstack_grow (&obstack, gcc_input_filename,
    6678              :                               input_filename_length);
    6679       265573 :                 arg_going = 1;
    6680              :               }
    6681              :             break;
    6682              : 
    6683       230786 :           case 'I':
    6684       230786 :             {
    6685       230786 :               struct spec_path info;
    6686              : 
    6687       230786 :               if (multilib_dir)
    6688              :                 {
    6689         6025 :                   do_spec_1 ("-imultilib", 1, NULL);
    6690              :                   /* Make this a separate argument.  */
    6691         6025 :                   do_spec_1 (" ", 0, NULL);
    6692         6025 :                   do_spec_1 (multilib_dir, 1, NULL);
    6693         6025 :                   do_spec_1 (" ", 0, NULL);
    6694              :                 }
    6695              : 
    6696       230786 :               if (multiarch_dir)
    6697              :                 {
    6698            0 :                   do_spec_1 ("-imultiarch", 1, NULL);
    6699              :                   /* Make this a separate argument.  */
    6700            0 :                   do_spec_1 (" ", 0, NULL);
    6701            0 :                   do_spec_1 (multiarch_dir, 1, NULL);
    6702            0 :                   do_spec_1 (" ", 0, NULL);
    6703              :                 }
    6704              : 
    6705       230786 :               if (gcc_exec_prefix)
    6706              :                 {
    6707       230786 :                   do_spec_1 ("-iprefix", 1, NULL);
    6708              :                   /* Make this a separate argument.  */
    6709       230786 :                   do_spec_1 (" ", 0, NULL);
    6710       230786 :                   do_spec_1 (gcc_exec_prefix, 1, NULL);
    6711       230786 :                   do_spec_1 (" ", 0, NULL);
    6712              :                 }
    6713              : 
    6714       230786 :               if (target_system_root_changed ||
    6715       230786 :                   (target_system_root && target_sysroot_hdrs_suffix))
    6716              :                 {
    6717            0 :                   do_spec_1 ("-isysroot", 1, NULL);
    6718              :                   /* Make this a separate argument.  */
    6719            0 :                   do_spec_1 (" ", 0, NULL);
    6720            0 :                   do_spec_1 (target_system_root, 1, NULL);
    6721            0 :                   if (target_sysroot_hdrs_suffix)
    6722            0 :                     do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
    6723            0 :                   do_spec_1 (" ", 0, NULL);
    6724              :                 }
    6725              : 
    6726       230786 :               info.option = "-isystem";
    6727       230786 :               info.append = "include";
    6728       230786 :               info.append_len = strlen (info.append);
    6729       230786 :               info.omit_relative = false;
    6730       230786 :               info.separate_options = true;
    6731       230786 :               info.realpaths = false;
    6732              : 
    6733       230786 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6734              : 
    6735       230786 :               info.append = "include-fixed";
    6736       230786 :               if (*sysroot_hdrs_suffix_spec)
    6737            0 :                 info.append = concat (info.append, dir_separator_str,
    6738              :                                       multilib_dir, NULL);
    6739       230786 :               else if (multiarch_dir)
    6740              :                 {
    6741              :                   /* For multiarch, search include-fixed/<multiarch-dir>
    6742              :                      before include-fixed.  */
    6743            0 :                   info.append = concat (info.append, dir_separator_str,
    6744              :                                         multiarch_dir, NULL);
    6745            0 :                   info.append_len = strlen (info.append);
    6746            0 :                   for_each_path (&include_prefixes, false,
    6747              :                                  info.append_len, info);
    6748              : 
    6749            0 :                   info.append = "include-fixed";
    6750              :                 }
    6751       230786 :               info.append_len = strlen (info.append);
    6752       230786 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6753              :             }
    6754       230786 :             break;
    6755              : 
    6756        98145 :           case 'o':
    6757              :             /* We are going to expand `%o' into `@FILE', where FILE
    6758              :                is a newly-created temporary filename.  The filenames
    6759              :                that would usually be expanded in place of %o will be
    6760              :                written to the temporary file.  */
    6761        98145 :             if (at_file_supplied)
    6762            6 :               open_at_file ();
    6763              : 
    6764       434267 :             for (i = 0; i < n_infiles + lang_specific_extra_outfiles; i++)
    6765       336122 :               if (outfiles[i])
    6766       336082 :                 store_arg (outfiles[i], 0, 0);
    6767              : 
    6768        98145 :             if (at_file_supplied)
    6769            6 :               close_at_file ();
    6770              :             break;
    6771              : 
    6772         4035 :           case 'O':
    6773         4035 :             obstack_grow (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    6774         4035 :             arg_going = 1;
    6775         4035 :             break;
    6776              : 
    6777       554229 :           case 's':
    6778       554229 :             this_is_library_file = 1;
    6779       554229 :             break;
    6780              : 
    6781            0 :           case 'T':
    6782            0 :             this_is_linker_script = 1;
    6783            0 :             break;
    6784              : 
    6785          467 :           case 'V':
    6786          467 :             outfiles[input_file_number] = NULL;
    6787          467 :             break;
    6788              : 
    6789       103134 :           case 'w':
    6790       103134 :             this_is_output_file = 1;
    6791       103134 :             break;
    6792              : 
    6793       181187 :           case 'W':
    6794       181187 :             {
    6795       181187 :               unsigned int cur_index = argbuf.length ();
    6796              :               /* Handle the {...} following the %W.  */
    6797       181187 :               if (*p != '{')
    6798            0 :                 fatal_error (input_location,
    6799              :                              "spec %qs has invalid %<%%W%c%>", spec, *p);
    6800       181187 :               p = handle_braces (p + 1);
    6801       181187 :               if (p == 0)
    6802              :                 return -1;
    6803       181187 :               end_going_arg ();
    6804              :               /* If any args were output, mark the last one for deletion
    6805              :                  on failure.  */
    6806       362374 :               if (argbuf.length () != cur_index)
    6807       178011 :                 record_temp_file (argbuf.last (), 0, 1);
    6808              :               break;
    6809              :             }
    6810              : 
    6811       313191 :           case '@':
    6812              :             /* Handle the {...} following the %@.  */
    6813       313191 :             if (*p != '{')
    6814            0 :               fatal_error (input_location,
    6815              :                            "spec %qs has invalid %<%%@%c%>", spec, *p);
    6816       313191 :             if (at_file_supplied)
    6817          141 :               open_at_file ();
    6818       313191 :             p = handle_braces (p + 1);
    6819       313191 :             if (at_file_supplied)
    6820          141 :               close_at_file ();
    6821       313191 :             if (p == 0)
    6822              :               return -1;
    6823              :             break;
    6824              : 
    6825              :           /* %x{OPTION} records OPTION for %X to output.  */
    6826            0 :           case 'x':
    6827            0 :             {
    6828            0 :               const char *p1 = p;
    6829            0 :               char *string;
    6830              : 
    6831              :               /* Skip past the option value and make a copy.  */
    6832            0 :               if (*p != '{')
    6833            0 :                 fatal_error (input_location,
    6834              :                              "spec %qs has invalid %<%%x%c%>", spec, *p);
    6835            0 :               while (*p++ != '}')
    6836              :                 ;
    6837            0 :               string = save_string (p1 + 1, p - p1 - 2);
    6838              : 
    6839              :               /* See if we already recorded this option.  */
    6840            0 :               for (const char *opt : linker_options)
    6841            0 :                 if (! strcmp (string, opt))
    6842              :                   {
    6843            0 :                     free (string);
    6844            0 :                     return 0;
    6845              :                   }
    6846              : 
    6847              :               /* This option is new; add it.  */
    6848            0 :               add_linker_option (string, strlen (string));
    6849            0 :               free (string);
    6850              :             }
    6851            0 :             break;
    6852              : 
    6853              :           /* Dump out the options accumulated previously using %x.  */
    6854        98145 :           case 'X':
    6855        98145 :             do_specs_vec (linker_options);
    6856        98145 :             break;
    6857              : 
    6858              :           /* Dump out the options accumulated previously using -Wa,.  */
    6859       169314 :           case 'Y':
    6860       169314 :             do_specs_vec (assembler_options);
    6861       169314 :             break;
    6862              : 
    6863              :           /* Dump out the options accumulated previously using -Wp,.  */
    6864       215046 :           case 'Z':
    6865       215046 :             do_specs_vec (preprocessor_options);
    6866       215046 :             break;
    6867              : 
    6868              :             /* Here are digits and numbers that just process
    6869              :                a certain constant string as a spec.  */
    6870              : 
    6871       295225 :           case '1':
    6872       295225 :             value = do_spec_1 (cc1_spec, 0, NULL);
    6873       295225 :             if (value != 0)
    6874              :               return value;
    6875              :             break;
    6876              : 
    6877        99766 :           case '2':
    6878        99766 :             value = do_spec_1 (cc1plus_spec, 0, NULL);
    6879        99766 :             if (value != 0)
    6880              :               return value;
    6881              :             break;
    6882              : 
    6883       169314 :           case 'a':
    6884       169314 :             value = do_spec_1 (asm_spec, 0, NULL);
    6885       169314 :             if (value != 0)
    6886              :               return value;
    6887              :             break;
    6888              : 
    6889       169314 :           case 'A':
    6890       169314 :             value = do_spec_1 (asm_final_spec, 0, NULL);
    6891       169314 :             if (value != 0)
    6892              :               return value;
    6893              :             break;
    6894              : 
    6895       215046 :           case 'C':
    6896       215046 :             {
    6897       115412 :               const char *const spec
    6898       215046 :                 = (input_file_compiler->cpp_spec
    6899       215046 :                    ? input_file_compiler->cpp_spec
    6900              :                    : cpp_spec);
    6901       215046 :               value = do_spec_1 (spec, 0, NULL);
    6902       215046 :               if (value != 0)
    6903              :                 return value;
    6904              :             }
    6905              :             break;
    6906              : 
    6907        97940 :           case 'E':
    6908        97940 :             value = do_spec_1 (endfile_spec, 0, NULL);
    6909        97940 :             if (value != 0)
    6910              :               return value;
    6911              :             break;
    6912              : 
    6913        98145 :           case 'l':
    6914        98145 :             value = do_spec_1 (link_spec, 0, NULL);
    6915        98145 :             if (value != 0)
    6916              :               return value;
    6917              :             break;
    6918              : 
    6919       190338 :           case 'L':
    6920       190338 :             value = do_spec_1 (lib_spec, 0, NULL);
    6921       190338 :             if (value != 0)
    6922              :               return value;
    6923              :             break;
    6924              : 
    6925            0 :           case 'M':
    6926            0 :             if (multilib_os_dir == NULL)
    6927            0 :               obstack_1grow (&obstack, '.');
    6928              :             else
    6929            0 :               obstack_grow (&obstack, multilib_os_dir,
    6930              :                             strlen (multilib_os_dir));
    6931              :             break;
    6932              : 
    6933       380482 :           case 'G':
    6934       380482 :             value = do_spec_1 (libgcc_spec, 0, NULL);
    6935       380482 :             if (value != 0)
    6936              :               return value;
    6937              :             break;
    6938              : 
    6939            0 :           case 'R':
    6940              :             /* We assume there is a directory
    6941              :                separator at the end of this string.  */
    6942            0 :             if (target_system_root)
    6943              :               {
    6944            0 :                 obstack_grow (&obstack, target_system_root,
    6945              :                               strlen (target_system_root));
    6946            0 :                 if (target_sysroot_suffix)
    6947            0 :                   obstack_grow (&obstack, target_sysroot_suffix,
    6948              :                                 strlen (target_sysroot_suffix));
    6949              :               }
    6950              :             break;
    6951              : 
    6952        97940 :           case 'S':
    6953        97940 :             value = do_spec_1 (startfile_spec, 0, NULL);
    6954        97940 :             if (value != 0)
    6955              :               return value;
    6956              :             break;
    6957              : 
    6958              :             /* Here we define characters other than letters and digits.  */
    6959              : 
    6960     41410084 :           case '{':
    6961     41410084 :             p = handle_braces (p);
    6962     41410084 :             if (p == 0)
    6963              :               return -1;
    6964              :             break;
    6965              : 
    6966       452525 :           case ':':
    6967       452525 :             p = handle_spec_function (p, NULL, soft_matched_part);
    6968       452525 :             if (p == 0)
    6969              :               return -1;
    6970              :             break;
    6971              : 
    6972            0 :           case '%':
    6973            0 :             obstack_1grow (&obstack, '%');
    6974            0 :             break;
    6975              : 
    6976              :           case '.':
    6977              :             {
    6978              :               unsigned len = 0;
    6979              : 
    6980        11898 :               while (p[len] && p[len] != ' ' && p[len] != '%')
    6981         5967 :                 len++;
    6982         5931 :               suffix_subst = save_string (p - 1, len + 1);
    6983         5931 :               p += len;
    6984              :             }
    6985         5931 :            break;
    6986              : 
    6987              :            /* Henceforth ignore the option(s) matching the pattern
    6988              :               after the %<.  */
    6989      1524129 :           case '<':
    6990      1524129 :           case '>':
    6991      1524129 :             {
    6992      1524129 :               unsigned len = 0;
    6993      1524129 :               int have_wildcard = 0;
    6994      1524129 :               int i;
    6995      1524129 :               int switch_option;
    6996              : 
    6997      1524129 :               if (c == '>')
    6998      1524129 :                 switch_option = SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC;
    6999              :               else
    7000      1524107 :                 switch_option = SWITCH_IGNORE;
    7001              : 
    7002     18413165 :               while (p[len] && p[len] != ' ' && p[len] != '\t')
    7003     16889036 :                 len++;
    7004              : 
    7005      1524129 :               if (p[len-1] == '*')
    7006        16199 :                 have_wildcard = 1;
    7007              : 
    7008     36236310 :               for (i = 0; i < n_switches; i++)
    7009     34712181 :                 if (!strncmp (switches[i].part1, p, len - have_wildcard)
    7010        51482 :                     && (have_wildcard || switches[i].part1[len] == '\0'))
    7011              :                   {
    7012        51209 :                     switches[i].live_cond |= switch_option;
    7013              :                     /* User switch be validated from validate_all_switches.
    7014              :                        when the definition is seen from the spec file.
    7015              :                        If not defined anywhere, will be rejected.  */
    7016        51209 :                     if (switches[i].known)
    7017        51209 :                       switches[i].validated = true;
    7018              :                   }
    7019              : 
    7020              :               p += len;
    7021              :             }
    7022              :             break;
    7023              : 
    7024         6882 :           case '*':
    7025         6882 :             if (soft_matched_part)
    7026              :               {
    7027         6882 :                 if (soft_matched_part[0])
    7028          371 :                   do_spec_1 (soft_matched_part, 1, NULL);
    7029              :                 /* Only insert a space after the substitution if it is at the
    7030              :                    end of the current sequence.  So if:
    7031              : 
    7032              :                      "%{foo=*:bar%*}%{foo=*:one%*two}"
    7033              : 
    7034              :                    matches -foo=hello then it will produce:
    7035              : 
    7036              :                      barhello onehellotwo
    7037              :                 */
    7038         6882 :                 if (*p == 0 || *p == '}')
    7039         6882 :                   do_spec_1 (" ", 0, NULL);
    7040              :               }
    7041              :             else
    7042              :               /* Catch the case where a spec string contains something like
    7043              :                  '%{foo:%*}'.  i.e. there is no * in the pattern on the left
    7044              :                  hand side of the :.  */
    7045            0 :               error ("spec failure: %<%%*%> has not been initialized by pattern match");
    7046              :             break;
    7047              : 
    7048              :             /* Process a string found as the value of a spec given by name.
    7049              :                This feature allows individual machine descriptions
    7050              :                to add and use their own specs.  */
    7051              :           case '(':
    7052              :             {
    7053     34367921 :               const char *name = p;
    7054              :               struct spec_list *sl;
    7055              :               int len;
    7056              : 
    7057              :               /* The string after the S/P is the name of a spec that is to be
    7058              :                  processed.  */
    7059     34367921 :               while (*p && *p != ')')
    7060     31718280 :                 p++;
    7061              : 
    7062              :               /* See if it's in the list.  */
    7063     36306290 :               for (len = p - name, sl = specs; sl; sl = sl->next)
    7064     36306290 :                 if (sl->name_len == len && !strncmp (sl->name, name, len))
    7065              :                   {
    7066      2649641 :                     name = *(sl->ptr_spec);
    7067              : #ifdef DEBUG_SPECS
    7068              :                     fnotice (stderr, "Processing spec (%s), which is '%s'\n",
    7069              :                              sl->name, name);
    7070              : #endif
    7071      2649641 :                     break;
    7072              :                   }
    7073              : 
    7074      2649641 :               if (sl)
    7075              :                 {
    7076      2649641 :                   value = do_spec_1 (name, 0, NULL);
    7077      2649641 :                   if (value != 0)
    7078              :                     return value;
    7079              :                 }
    7080              : 
    7081              :               /* Discard the closing paren.  */
    7082      2643857 :               if (*p)
    7083      2643857 :                 p++;
    7084              :             }
    7085              :             break;
    7086              : 
    7087            9 :           case '"':
    7088              :             /* End a previous argument, if there is one, then issue an
    7089              :                empty argument.  */
    7090            9 :             end_going_arg ();
    7091            9 :             arg_going = 1;
    7092            9 :             end_going_arg ();
    7093            9 :             break;
    7094              : 
    7095            0 :           default:
    7096            0 :             error ("spec failure: unrecognized spec option %qc", c);
    7097            0 :             break;
    7098              :           }
    7099              :         break;
    7100              : 
    7101            0 :       case '\\':
    7102              :         /* Backslash: treat next character as ordinary.  */
    7103            0 :         c = *p++;
    7104              : 
    7105              :         /* When adding more cases that previously matched default, make
    7106              :            sure to adjust quote_spec_char_p as well.  */
    7107              : 
    7108              :         /* Fall through.  */
    7109    370697722 :       default:
    7110              :         /* Ordinary character: put it into the current argument.  */
    7111    370697722 :         obstack_1grow (&obstack, c);
    7112    370697722 :         arg_going = 1;
    7113              :       }
    7114              : 
    7115              :   /* End of string.  If we are processing a spec function, we need to
    7116              :      end any pending argument.  */
    7117     54310886 :   if (processing_spec_function)
    7118      4629020 :     end_going_arg ();
    7119              : 
    7120              :   return 0;
    7121              : }
    7122              : 
    7123              : /* Look up a spec function.  */
    7124              : 
    7125              : static const struct spec_function *
    7126      2132631 : lookup_spec_function (const char *name)
    7127              : {
    7128      2132631 :   const struct spec_function *sf;
    7129              : 
    7130     25547998 :   for (sf = static_spec_functions; sf->name != NULL; sf++)
    7131     25547998 :     if (strcmp (sf->name, name) == 0)
    7132              :       return sf;
    7133              : 
    7134              :   return NULL;
    7135              : }
    7136              : 
    7137              : /* Evaluate a spec function.  */
    7138              : 
    7139              : static const char *
    7140      2132631 : eval_spec_function (const char *func, const char *args,
    7141              :                     const char *soft_matched_part)
    7142              : {
    7143      2132631 :   const struct spec_function *sf;
    7144      2132631 :   const char *funcval;
    7145              : 
    7146              :   /* Saved spec processing context.  */
    7147      2132631 :   vec<const_char_p> save_argbuf;
    7148              : 
    7149      2132631 :   int save_arg_going;
    7150      2132631 :   int save_delete_this_arg;
    7151      2132631 :   int save_this_is_output_file;
    7152      2132631 :   int save_this_is_library_file;
    7153      2132631 :   int save_input_from_pipe;
    7154      2132631 :   int save_this_is_linker_script;
    7155      2132631 :   const char *save_suffix_subst;
    7156              : 
    7157      2132631 :   int save_growing_size;
    7158      2132631 :   void *save_growing_value = NULL;
    7159              : 
    7160      2132631 :   sf = lookup_spec_function (func);
    7161      2132631 :   if (sf == NULL)
    7162            0 :     fatal_error (input_location, "unknown spec function %qs", func);
    7163              : 
    7164              :   /* Push the spec processing context.  */
    7165      2132631 :   save_argbuf = argbuf;
    7166              : 
    7167      2132631 :   save_arg_going = arg_going;
    7168      2132631 :   save_delete_this_arg = delete_this_arg;
    7169      2132631 :   save_this_is_output_file = this_is_output_file;
    7170      2132631 :   save_this_is_library_file = this_is_library_file;
    7171      2132631 :   save_this_is_linker_script = this_is_linker_script;
    7172      2132631 :   save_input_from_pipe = input_from_pipe;
    7173      2132631 :   save_suffix_subst = suffix_subst;
    7174              : 
    7175              :   /* If we have some object growing now, finalize it so the args and function
    7176              :      eval proceed from a cleared context.  This is needed to prevent the first
    7177              :      constructed arg from mistakenly including the growing value.  We'll push
    7178              :      this value back on the obstack once the function evaluation is done, to
    7179              :      restore a consistent processing context for our caller.  This is fine as
    7180              :      the address of growing objects isn't guaranteed to remain stable until
    7181              :      they are finalized, and we expect this situation to be rare enough for
    7182              :      the extra copy not to be an issue.  */
    7183      2132631 :   save_growing_size = obstack_object_size (&obstack);
    7184      2132631 :   if (save_growing_size > 0)
    7185        42675 :     save_growing_value = obstack_finish (&obstack);
    7186              : 
    7187              :   /* Create a new spec processing context, and build the function
    7188              :      arguments.  */
    7189              : 
    7190      2132631 :   alloc_args ();
    7191      2132631 :   if (do_spec_2 (args, soft_matched_part) < 0)
    7192            0 :     fatal_error (input_location, "error in arguments to spec function %qs",
    7193              :                  func);
    7194              : 
    7195              :   /* argbuf_index is an index for the next argument to be inserted, and
    7196              :      so contains the count of the args already inserted.  */
    7197              : 
    7198      6397893 :   funcval = (*sf->func) (argbuf.length (),
    7199              :                          argbuf.address ());
    7200              : 
    7201              :   /* Pop the spec processing context.  */
    7202      2132631 :   argbuf.release ();
    7203      2132631 :   argbuf = save_argbuf;
    7204              : 
    7205      2132631 :   arg_going = save_arg_going;
    7206      2132631 :   delete_this_arg = save_delete_this_arg;
    7207      2132631 :   this_is_output_file = save_this_is_output_file;
    7208      2132631 :   this_is_library_file = save_this_is_library_file;
    7209      2132631 :   this_is_linker_script = save_this_is_linker_script;
    7210      2132631 :   input_from_pipe = save_input_from_pipe;
    7211      2132631 :   suffix_subst = save_suffix_subst;
    7212              : 
    7213      2132631 :   if (save_growing_size > 0)
    7214        42675 :     obstack_grow (&obstack, save_growing_value, save_growing_size);
    7215              : 
    7216      2132631 :   return funcval;
    7217              : }
    7218              : 
    7219              : /* Handle a spec function call of the form:
    7220              : 
    7221              :    %:function(args)
    7222              : 
    7223              :    ARGS is processed as a spec in a separate context and split into an
    7224              :    argument vector in the normal fashion.  The function returns a string
    7225              :    containing a spec which we then process in the caller's context, or
    7226              :    NULL if no processing is required.
    7227              : 
    7228              :    If RETVAL_NONNULL is not NULL, then store a bool whether function
    7229              :    returned non-NULL.
    7230              : 
    7231              :    SOFT_MATCHED_PART holds the current value of a matched * pattern, which
    7232              :    may be re-expanded with a %* as part of the function arguments.  */
    7233              : 
    7234              : static const char *
    7235      2132631 : handle_spec_function (const char *p, bool *retval_nonnull,
    7236              :                       const char *soft_matched_part)
    7237              : {
    7238      2132631 :   char *func, *args;
    7239      2132631 :   const char *endp, *funcval;
    7240      2132631 :   int count;
    7241              : 
    7242      2132631 :   processing_spec_function++;
    7243              : 
    7244              :   /* Get the function name.  */
    7245     19758162 :   for (endp = p; *endp != '\0'; endp++)
    7246              :     {
    7247     19758162 :       if (*endp == '(')         /* ) */
    7248              :         break;
    7249              :       /* Only allow [A-Za-z0-9], -, and _ in function names.  */
    7250     17625531 :       if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
    7251            0 :         fatal_error (input_location, "malformed spec function name");
    7252              :     }
    7253      2132631 :   if (*endp != '(')             /* ) */
    7254            0 :     fatal_error (input_location, "no arguments for spec function");
    7255      2132631 :   func = save_string (p, endp - p);
    7256      2132631 :   p = ++endp;
    7257              : 
    7258              :   /* Get the arguments.  */
    7259     26060265 :   for (count = 0; *endp != '\0'; endp++)
    7260              :     {
    7261              :       /* ( */
    7262     26060265 :       if (*endp == ')')
    7263              :         {
    7264      2225031 :           if (count == 0)
    7265              :             break;
    7266        92400 :           count--;
    7267              :         }
    7268     23835234 :       else if (*endp == '(')    /* ) */
    7269        92400 :         count++;
    7270              :     }
    7271              :   /* ( */
    7272      2132631 :   if (*endp != ')')
    7273            0 :     fatal_error (input_location, "malformed spec function arguments");
    7274      2132631 :   args = save_string (p, endp - p);
    7275      2132631 :   p = ++endp;
    7276              : 
    7277              :   /* p now points to just past the end of the spec function expression.  */
    7278              : 
    7279      2132631 :   funcval = eval_spec_function (func, args, soft_matched_part);
    7280      2132631 :   if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
    7281              :     p = NULL;
    7282      2132631 :   if (retval_nonnull)
    7283      1680106 :     *retval_nonnull = funcval != NULL;
    7284              : 
    7285      2132631 :   free (func);
    7286      2132631 :   free (args);
    7287              : 
    7288      2132631 :   processing_spec_function--;
    7289              : 
    7290      2132631 :   return p;
    7291              : }
    7292              : 
    7293              : /* Inline subroutine of handle_braces.  Returns true if the current
    7294              :    input suffix matches the atom bracketed by ATOM and END_ATOM.  */
    7295              : static inline bool
    7296            0 : input_suffix_matches (const char *atom, const char *end_atom)
    7297              : {
    7298            0 :   return (input_suffix
    7299            0 :           && !strncmp (input_suffix, atom, end_atom - atom)
    7300            0 :           && input_suffix[end_atom - atom] == '\0');
    7301              : }
    7302              : 
    7303              : /* Subroutine of handle_braces.  Returns true if the current
    7304              :    input file's spec name matches the atom bracketed by ATOM and END_ATOM.  */
    7305              : static bool
    7306            0 : input_spec_matches (const char *atom, const char *end_atom)
    7307              : {
    7308            0 :   return (input_file_compiler
    7309            0 :           && input_file_compiler->suffix
    7310            0 :           && input_file_compiler->suffix[0] != '\0'
    7311            0 :           && !strncmp (input_file_compiler->suffix + 1, atom,
    7312            0 :                        end_atom - atom)
    7313            0 :           && input_file_compiler->suffix[end_atom - atom + 1] == '\0');
    7314              : }
    7315              : 
    7316              : /* Subroutine of handle_braces.  Returns true if a switch
    7317              :    matching the atom bracketed by ATOM and END_ATOM appeared on the
    7318              :    command line.  */
    7319              : static bool
    7320     39773677 : switch_matches (const char *atom, const char *end_atom, int starred)
    7321              : {
    7322     39773677 :   int i;
    7323     39773677 :   int len = end_atom - atom;
    7324     39773677 :   int plen = starred ? len : -1;
    7325              : 
    7326    930726397 :   for (i = 0; i < n_switches; i++)
    7327    892366688 :     if (!strncmp (switches[i].part1, atom, len)
    7328      2371002 :         && (starred || switches[i].part1[len] == '\0')
    7329    893781289 :         && check_live_switch (i, plen))
    7330              :       return true;
    7331              : 
    7332              :     /* Check if a switch with separated form matching the atom.
    7333              :        We check -D and -U switches. */
    7334    890952721 :     else if (switches[i].args != 0)
    7335              :       {
    7336    205164694 :         if ((*switches[i].part1 == 'D' || *switches[i].part1 == 'U')
    7337      8849611 :             && *switches[i].part1 == atom[0])
    7338              :           {
    7339            1 :             if (!strncmp (switches[i].args[0], &atom[1], len - 1)
    7340            1 :                 && (starred || (switches[i].part1[1] == '\0'
    7341            1 :                                 && switches[i].args[0][len - 1] == '\0'))
    7342            2 :                 && check_live_switch (i, (starred ? 1 : -1)))
    7343              :               return true;
    7344              :           }
    7345              :       }
    7346              : 
    7347              :   return false;
    7348              : }
    7349              : 
    7350              : /* Inline subroutine of handle_braces.  Mark all of the switches which
    7351              :    match ATOM (extends to END_ATOM; STARRED indicates whether there
    7352              :    was a star after the atom) for later processing.  */
    7353              : static inline void
    7354     11575141 : mark_matching_switches (const char *atom, const char *end_atom, int starred)
    7355              : {
    7356     11575141 :   int i;
    7357     11575141 :   int len = end_atom - atom;
    7358     11575141 :   int plen = starred ? len : -1;
    7359              : 
    7360    274662263 :   for (i = 0; i < n_switches; i++)
    7361    263087122 :     if (!strncmp (switches[i].part1, atom, len)
    7362      6551634 :         && (starred || switches[i].part1[len] == '\0')
    7363    269416521 :         && check_live_switch (i, plen))
    7364      6278200 :       switches[i].ordering = 1;
    7365     11575141 : }
    7366              : 
    7367              : /* Inline subroutine of handle_braces.  Process all the currently
    7368              :    marked switches through give_switch, and clear the marks.  */
    7369              : static inline void
    7370     10044328 : process_marked_switches (void)
    7371              : {
    7372     10044328 :   int i;
    7373              : 
    7374    238288037 :   for (i = 0; i < n_switches; i++)
    7375    228243709 :     if (switches[i].ordering == 1)
    7376              :       {
    7377      6278200 :         switches[i].ordering = 0;
    7378      6278200 :         give_switch (i, 0);
    7379              :       }
    7380     10044328 : }
    7381              : 
    7382              : /* Handle a %{ ... } construct.  P points just inside the leading {.
    7383              :    Returns a pointer one past the end of the brace block, or 0
    7384              :    if we call do_spec_1 and that returns -1.  */
    7385              : 
    7386              : static const char *
    7387     41904462 : handle_braces (const char *p)
    7388              : {
    7389     41904462 :   const char *atom, *end_atom;
    7390     41904462 :   const char *d_atom = NULL, *d_end_atom = NULL;
    7391     41904462 :   char *esc_buf = NULL, *d_esc_buf = NULL;
    7392     41904462 :   int esc;
    7393     41904462 :   const char *orig = p;
    7394              : 
    7395     41904462 :   bool a_is_suffix;
    7396     41904462 :   bool a_is_spectype;
    7397     41904462 :   bool a_is_starred;
    7398     41904462 :   bool a_is_negated;
    7399     41904462 :   bool a_matched;
    7400              : 
    7401     41904462 :   bool a_must_be_last = false;
    7402     41904462 :   bool ordered_set    = false;
    7403     41904462 :   bool disjunct_set   = false;
    7404     41904462 :   bool disj_matched   = false;
    7405     41904462 :   bool disj_starred   = true;
    7406     41904462 :   bool n_way_choice   = false;
    7407     41904462 :   bool n_way_matched  = false;
    7408              : 
    7409              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    7410              : 
    7411     55691319 :   do
    7412              :     {
    7413     55691319 :       if (a_must_be_last)
    7414            0 :         goto invalid;
    7415              : 
    7416              :       /* Scan one "atom" (S in the description above of %{}, possibly
    7417              :          with '!', '.', '@', ',', or '*' modifiers).  */
    7418     55691319 :       a_matched = false;
    7419     55691319 :       a_is_suffix = false;
    7420     55691319 :       a_is_starred = false;
    7421     55691319 :       a_is_negated = false;
    7422     55691319 :       a_is_spectype = false;
    7423              : 
    7424     63427083 :       SKIP_WHITE ();
    7425     55691319 :       if (*p == '!')
    7426     13453469 :         p++, a_is_negated = true;
    7427              : 
    7428     55691319 :       SKIP_WHITE ();
    7429     55691319 :       if (*p == '%' && p[1] == ':')
    7430              :         {
    7431      1680106 :           atom = NULL;
    7432      1680106 :           end_atom = NULL;
    7433      1680106 :           p = handle_spec_function (p + 2, &a_matched, NULL);
    7434              :         }
    7435              :       else
    7436              :         {
    7437     54011213 :           if (*p == '.')
    7438            0 :             p++, a_is_suffix = true;
    7439     54011213 :           else if (*p == ',')
    7440            0 :             p++, a_is_spectype = true;
    7441              : 
    7442     54011213 :           atom = p;
    7443     54011213 :           esc = 0;
    7444     54011213 :           while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    7445    407067848 :                  || *p == ',' || *p == '.' || *p == '@' || *p == '\\')
    7446              :             {
    7447    353056635 :               if (*p == '\\')
    7448              :                 {
    7449            0 :                   p++;
    7450            0 :                   if (!*p)
    7451            0 :                     fatal_error (input_location,
    7452              :                                  "braced spec %qs ends in escape", orig);
    7453            0 :                   esc++;
    7454              :                 }
    7455    353056635 :               p++;
    7456              :             }
    7457     54011213 :           end_atom = p;
    7458              : 
    7459     54011213 :           if (esc)
    7460              :             {
    7461            0 :               const char *ap;
    7462            0 :               char *ep;
    7463              : 
    7464            0 :               if (esc_buf && esc_buf != d_esc_buf)
    7465            0 :                 free (esc_buf);
    7466            0 :               esc_buf = NULL;
    7467            0 :               ep = esc_buf = (char *) xmalloc (end_atom - atom - esc + 1);
    7468            0 :               for (ap = atom; ap != end_atom; ap++, ep++)
    7469              :                 {
    7470            0 :                   if (*ap == '\\')
    7471            0 :                     ap++;
    7472            0 :                   *ep = *ap;
    7473              :                 }
    7474            0 :               *ep = '\0';
    7475            0 :               atom = esc_buf;
    7476            0 :               end_atom = ep;
    7477              :             }
    7478              : 
    7479     54011213 :           if (*p == '*')
    7480     12203600 :             p++, a_is_starred = 1;
    7481              :         }
    7482              : 
    7483     55691319 :       SKIP_WHITE ();
    7484     55691319 :       switch (*p)
    7485              :         {
    7486     11575141 :         case '&': case '}':
    7487              :           /* Substitute the switch(es) indicated by the current atom.  */
    7488     11575141 :           ordered_set = true;
    7489     11575141 :           if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
    7490     11575141 :               || a_is_spectype || atom == end_atom)
    7491            0 :             goto invalid;
    7492              : 
    7493     11575141 :           mark_matching_switches (atom, end_atom, a_is_starred);
    7494              : 
    7495     11575141 :           if (*p == '}')
    7496     10044328 :             process_marked_switches ();
    7497              :           break;
    7498              : 
    7499     44116178 :         case '|': case ':':
    7500              :           /* Substitute some text if the current atom appears as a switch
    7501              :              or suffix.  */
    7502     44116178 :           disjunct_set = true;
    7503     44116178 :           if (ordered_set)
    7504            0 :             goto invalid;
    7505              : 
    7506     44116178 :           if (atom && atom == end_atom)
    7507              :             {
    7508      1819213 :               if (!n_way_choice || disj_matched || *p == '|'
    7509      1819213 :                   || a_is_negated || a_is_suffix || a_is_spectype
    7510      1819213 :                   || a_is_starred)
    7511            0 :                 goto invalid;
    7512              : 
    7513              :               /* An empty term may appear as the last choice of an
    7514              :                  N-way choice set; it means "otherwise".  */
    7515      1819213 :               a_must_be_last = true;
    7516      1819213 :               disj_matched = !n_way_matched;
    7517      1819213 :               disj_starred = false;
    7518              :             }
    7519              :           else
    7520              :             {
    7521     42296965 :               if ((a_is_suffix || a_is_spectype) && a_is_starred)
    7522            0 :                 goto invalid;
    7523              : 
    7524     42296965 :               if (!a_is_starred)
    7525     36529321 :                 disj_starred = false;
    7526              : 
    7527              :               /* Don't bother testing this atom if we already have a
    7528              :                  match.  */
    7529     42296965 :               if (!disj_matched && !n_way_matched)
    7530              :                 {
    7531     41250999 :                   if (atom == NULL)
    7532              :                     /* a_matched is already set by handle_spec_function.  */;
    7533     39675528 :                   else if (a_is_suffix)
    7534            0 :                     a_matched = input_suffix_matches (atom, end_atom);
    7535     39675528 :                   else if (a_is_spectype)
    7536            0 :                     a_matched = input_spec_matches (atom, end_atom);
    7537              :                   else
    7538     39675528 :                     a_matched = switch_matches (atom, end_atom, a_is_starred);
    7539              : 
    7540     41250999 :                   if (a_matched != a_is_negated)
    7541              :                     {
    7542     13313223 :                       disj_matched = true;
    7543     13313223 :                       d_atom = atom;
    7544     13313223 :                       d_end_atom = end_atom;
    7545     13313223 :                       d_esc_buf = esc_buf;
    7546              :                     }
    7547              :                 }
    7548              :             }
    7549              : 
    7550     44116178 :           if (*p == ':')
    7551              :             {
    7552              :               /* Found the body, that is, the text to substitute if the
    7553              :                  current disjunction matches.  */
    7554     69880996 :               p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
    7555     34940498 :                                       disj_matched && !n_way_matched);
    7556     34940498 :               if (p == 0)
    7557        38108 :                 goto done;
    7558              : 
    7559              :               /* If we have an N-way choice, reset state for the next
    7560              :                  disjunction.  */
    7561     34902390 :               if (*p == ';')
    7562              :                 {
    7563      3080364 :                   n_way_choice = true;
    7564      3080364 :                   n_way_matched |= disj_matched;
    7565      3080364 :                   disj_matched = false;
    7566      3080364 :                   disj_starred = true;
    7567      3080364 :                   d_atom = d_end_atom = NULL;
    7568              :                 }
    7569              :             }
    7570              :           break;
    7571              : 
    7572            0 :         default:
    7573            0 :           goto invalid;
    7574              :         }
    7575              :     }
    7576     55653211 :   while (*p++ != '}');
    7577              : 
    7578     41866354 :  done:
    7579     41904462 :   if (d_esc_buf && d_esc_buf != esc_buf)
    7580            0 :     free (d_esc_buf);
    7581     41904462 :   if (esc_buf)
    7582            0 :     free (esc_buf);
    7583              : 
    7584     41904462 :   return p;
    7585              : 
    7586            0 :  invalid:
    7587            0 :   fatal_error (input_location, "braced spec %qs is invalid at %qc", orig, *p);
    7588              : 
    7589              : #undef SKIP_WHITE
    7590              : }
    7591              : 
    7592              : /* Subroutine of handle_braces.  Scan and process a brace substitution body
    7593              :    (X in the description of %{} syntax).  P points one past the colon;
    7594              :    ATOM and END_ATOM bracket the first atom which was found to be true
    7595              :    (present) in the current disjunction; STARRED indicates whether all
    7596              :    the atoms in the current disjunction were starred (for syntax validation);
    7597              :    MATCHED indicates whether the disjunction matched or not, and therefore
    7598              :    whether or not the body is to be processed through do_spec_1 or just
    7599              :    skipped.  Returns a pointer to the closing } or ;, or 0 if do_spec_1
    7600              :    returns -1.  */
    7601              : 
    7602              : static const char *
    7603     34940498 : process_brace_body (const char *p, const char *atom, const char *end_atom,
    7604              :                     int starred, int matched)
    7605              : {
    7606     34940498 :   const char *body, *end_body;
    7607     34940498 :   unsigned int nesting_level;
    7608     34940498 :   bool have_subst     = false;
    7609              : 
    7610              :   /* Locate the closing } or ;, honoring nested braces.
    7611              :      Trim trailing whitespace.  */
    7612     34940498 :   body = p;
    7613     34940498 :   nesting_level = 1;
    7614  11793128582 :   for (;;)
    7615              :     {
    7616   5914034540 :       if (*p == '{')
    7617    176258432 :         nesting_level++;
    7618   5737776108 :       else if (*p == '}')
    7619              :         {
    7620    208118566 :           if (!--nesting_level)
    7621              :             break;
    7622              :         }
    7623   5529657542 :       else if (*p == ';' && nesting_level == 1)
    7624              :         break;
    7625   5526577178 :       else if (*p == '%' && p[1] == '*' && nesting_level == 1)
    7626              :         have_subst = true;
    7627   5525764753 :       else if (*p == '\0')
    7628            0 :         goto invalid;
    7629   5879094042 :       p++;
    7630              :     }
    7631              : 
    7632              :   end_body = p;
    7633     37791452 :   while (end_body[-1] == ' ' || end_body[-1] == '\t')
    7634      2850954 :     end_body--;
    7635              : 
    7636     34940498 :   if (have_subst && !starred)
    7637            0 :     goto invalid;
    7638              : 
    7639     34940498 :   if (matched)
    7640              :     {
    7641              :       /* Copy the substitution body to permanent storage and execute it.
    7642              :          If have_subst is false, this is a simple matter of running the
    7643              :          body through do_spec_1...  */
    7644     14294538 :       char *string = save_string (body, end_body - body);
    7645     14294538 :       if (!have_subst)
    7646              :         {
    7647     14287660 :           if (do_spec_1 (string, 0, NULL) < 0)
    7648              :             {
    7649        38108 :               free (string);
    7650        38108 :               return 0;
    7651              :             }
    7652              :         }
    7653              :       else
    7654              :         {
    7655              :           /* ... but if have_subst is true, we have to process the
    7656              :              body once for each matching switch, with %* set to the
    7657              :              variant part of the switch.  */
    7658         6878 :           unsigned int hard_match_len = end_atom - atom;
    7659         6878 :           int i;
    7660              : 
    7661       275230 :           for (i = 0; i < n_switches; i++)
    7662       268352 :             if (!strncmp (switches[i].part1, atom, hard_match_len)
    7663       268352 :                 && check_live_switch (i, hard_match_len))
    7664              :               {
    7665         6882 :                 if (do_spec_1 (string, 0,
    7666              :                                &switches[i].part1[hard_match_len]) < 0)
    7667              :                   {
    7668            0 :                     free (string);
    7669            0 :                     return 0;
    7670              :                   }
    7671              :                 /* Pass any arguments this switch has.  */
    7672         6882 :                 give_switch (i, 1);
    7673         6882 :                 suffix_subst = NULL;
    7674              :               }
    7675              :         }
    7676     14256430 :       free (string);
    7677              :     }
    7678              : 
    7679              :   return p;
    7680              : 
    7681            0 :  invalid:
    7682            0 :   fatal_error (input_location, "braced spec body %qs is invalid", body);
    7683              : }
    7684              : 
    7685              : /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
    7686              :    on the command line.  PREFIX_LENGTH is the length of XXX in an {XXX*}
    7687              :    spec, or -1 if either exact match or %* is used.
    7688              : 
    7689              :    A -O switch is obsoleted by a later -O switch.  A -f, -g, -m, or -W switch
    7690              :    whose value does not begin with "no-" is obsoleted by the same value
    7691              :    with the "no-", similarly for a switch with the "no-" prefix.  */
    7692              : 
    7693              : static int
    7694      7750883 : check_live_switch (int switchnum, int prefix_length)
    7695              : {
    7696      7750883 :   const char *name = switches[switchnum].part1;
    7697      7750883 :   int i;
    7698              : 
    7699              :   /* If we already processed this switch and determined if it was
    7700              :      live or not, return our past determination.  */
    7701      7750883 :   if (switches[switchnum].live_cond != 0)
    7702       977429 :     return ((switches[switchnum].live_cond & SWITCH_LIVE) != 0
    7703       925614 :             && (switches[switchnum].live_cond & SWITCH_FALSE) == 0
    7704      1903043 :             && (switches[switchnum].live_cond & SWITCH_IGNORE_PERMANENTLY)
    7705       977429 :                == 0);
    7706              : 
    7707              :   /* In the common case of {<at-most-one-letter>*}, a negating
    7708              :      switch would always match, so ignore that case.  We will just
    7709              :      send the conflicting switches to the compiler phase.  */
    7710      6773454 :   if (prefix_length >= 0 && prefix_length <= 1)
    7711              :     return 1;
    7712              : 
    7713              :   /* Now search for duplicate in a manner that depends on the name.  */
    7714       913769 :   switch (*name)
    7715              :     {
    7716           62 :     case 'O':
    7717          344 :       for (i = switchnum + 1; i < n_switches; i++)
    7718          287 :         if (switches[i].part1[0] == 'O')
    7719              :           {
    7720            5 :             switches[switchnum].validated = true;
    7721            5 :             switches[switchnum].live_cond = SWITCH_FALSE;
    7722            5 :             return 0;
    7723              :           }
    7724              :       break;
    7725              : 
    7726       298827 :     case 'W':  case 'f':  case 'm': case 'g':
    7727       298827 :       if (startswith (name + 1, "no-"))
    7728              :         {
    7729              :           /* We have Xno-YYY, search for XYYY.  */
    7730        35569 :           for (i = switchnum + 1; i < n_switches; i++)
    7731        29907 :             if (switches[i].part1[0] == name[0]
    7732         5697 :                 && ! strcmp (&switches[i].part1[1], &name[4]))
    7733              :               {
    7734              :                 /* --specs are validated with the validate_switches mechanism.  */
    7735            0 :                 if (switches[switchnum].known)
    7736            0 :                   switches[switchnum].validated = true;
    7737            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7738            0 :                 return 0;
    7739              :               }
    7740              :         }
    7741              :       else
    7742              :         {
    7743              :           /* We have XYYY, search for Xno-YYY.  */
    7744      3067631 :           for (i = switchnum + 1; i < n_switches; i++)
    7745      2774466 :             if (switches[i].part1[0] == name[0]
    7746      1680190 :                 && switches[i].part1[1] == 'n'
    7747       211660 :                 && switches[i].part1[2] == 'o'
    7748       211659 :                 && switches[i].part1[3] == '-'
    7749       211629 :                 && !strcmp (&switches[i].part1[4], &name[1]))
    7750              :               {
    7751              :                 /* --specs are validated with the validate_switches mechanism.  */
    7752            0 :                 if (switches[switchnum].known)
    7753            0 :                   switches[switchnum].validated = true;
    7754            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7755            0 :                 return 0;
    7756              :               }
    7757              :         }
    7758              :       break;
    7759              :     }
    7760              : 
    7761              :   /* Otherwise the switch is live.  */
    7762       913764 :   switches[switchnum].live_cond |= SWITCH_LIVE;
    7763       913764 :   return 1;
    7764              : }
    7765              : 
    7766              : /* Pass a switch to the current accumulating command
    7767              :    in the same form that we received it.
    7768              :    SWITCHNUM identifies the switch; it is an index into
    7769              :    the vector of switches gcc received, which is `switches'.
    7770              :    This cannot fail since it never finishes a command line.
    7771              : 
    7772              :    If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.  */
    7773              : 
    7774              : static void
    7775      6285082 : give_switch (int switchnum, int omit_first_word)
    7776              : {
    7777      6285082 :   if ((switches[switchnum].live_cond & SWITCH_IGNORE) != 0)
    7778              :     return;
    7779              : 
    7780      6285071 :   if (!omit_first_word)
    7781              :     {
    7782      6278189 :       do_spec_1 ("-", 0, NULL);
    7783      6278189 :       do_spec_1 (switches[switchnum].part1, 1, NULL);
    7784              :     }
    7785              : 
    7786      6285071 :   if (switches[switchnum].args != 0)
    7787              :     {
    7788              :       const char **p;
    7789      2525346 :       for (p = switches[switchnum].args; *p; p++)
    7790              :         {
    7791      1262673 :           const char *arg = *p;
    7792              : 
    7793      1262673 :           do_spec_1 (" ", 0, NULL);
    7794      1262673 :           if (suffix_subst)
    7795              :             {
    7796         5931 :               unsigned length = strlen (arg);
    7797         5931 :               int dot = 0;
    7798              : 
    7799        11862 :               while (length-- && !IS_DIR_SEPARATOR (arg[length]))
    7800        11862 :                 if (arg[length] == '.')
    7801              :                   {
    7802         5931 :                     (const_cast<char *> (arg))[length] = 0;
    7803         5931 :                     dot = 1;
    7804         5931 :                     break;
    7805              :                   }
    7806         5931 :               do_spec_1 (arg, 1, NULL);
    7807         5931 :               if (dot)
    7808         5931 :                 (const_cast<char *> (arg))[length] = '.';
    7809         5931 :               do_spec_1 (suffix_subst, 1, NULL);
    7810              :             }
    7811              :           else
    7812      1256742 :             do_spec_1 (arg, 1, NULL);
    7813              :         }
    7814              :     }
    7815              : 
    7816      6285071 :   do_spec_1 (" ", 0, NULL);
    7817      6285071 :   switches[switchnum].validated = true;
    7818              : }
    7819              : 
    7820              : /* Print GCC configuration (e.g. version, thread model, target,
    7821              :    configuration_arguments) to a given FILE.  */
    7822              : 
    7823              : static void
    7824         1658 : print_configuration (FILE *file)
    7825              : {
    7826         1658 :   int n;
    7827         1658 :   const char *thrmod;
    7828              : 
    7829         1658 :   fnotice (file, "Target: %s\n", spec_machine);
    7830         1658 :   fnotice (file, "Configured with: %s\n", configuration_arguments);
    7831              : 
    7832              : #ifdef THREAD_MODEL_SPEC
    7833              :   /* We could have defined THREAD_MODEL_SPEC to "%*" by default,
    7834              :   but there's no point in doing all this processing just to get
    7835              :   thread_model back.  */
    7836              :   obstack_init (&obstack);
    7837              :   do_spec_1 (THREAD_MODEL_SPEC, 0, thread_model);
    7838              :   obstack_1grow (&obstack, '\0');
    7839              :   thrmod = XOBFINISH (&obstack, const char *);
    7840              : #else
    7841         1658 :   thrmod = thread_model;
    7842              : #endif
    7843              : 
    7844         1658 :   fnotice (file, "Thread model: %s\n", thrmod);
    7845         1658 :   fnotice (file, "Supported LTO compression algorithms: zlib");
    7846              : #ifdef HAVE_ZSTD_H
    7847         1658 :   fnotice (file, " zstd");
    7848              : #endif
    7849         1658 :   fnotice (file, "\n");
    7850              : 
    7851              :   /* compiler_version is truncated at the first space when initialized
    7852              :   from version string, so truncate version_string at the first space
    7853              :   before comparing.  */
    7854        13264 :   for (n = 0; version_string[n]; n++)
    7855        11606 :     if (version_string[n] == ' ')
    7856              :       break;
    7857              : 
    7858         1658 :   if (! strncmp (version_string, compiler_version, n)
    7859         1658 :       && compiler_version[n] == 0)
    7860         1658 :     fnotice (file, "gcc version %s %s\n", version_string,
    7861              :              pkgversion_string);
    7862              :   else
    7863            0 :     fnotice (file, "gcc driver version %s %sexecuting gcc version %s\n",
    7864              :              version_string, pkgversion_string, compiler_version);
    7865              : 
    7866         1658 : }
    7867              : 
    7868              : #define RETRY_ICE_ATTEMPTS 3
    7869              : 
    7870              : /* Returns true if FILE1 and FILE2 contain equivalent data, 0 otherwise.
    7871              :    If lines start with 0x followed by 1-16 lowercase hexadecimal digits
    7872              :    followed by a space, ignore anything before that space.  These are
    7873              :    typically function addresses from libbacktrace and those can differ
    7874              :    due to ASLR.  */
    7875              : 
    7876              : static bool
    7877            0 : files_equal_p (char *file1, char *file2)
    7878              : {
    7879            0 :   FILE *f1 = fopen (file1, "rb");
    7880            0 :   FILE *f2 = fopen (file2, "rb");
    7881            0 :   char line1[256], line2[256];
    7882              : 
    7883            0 :   bool line_start = true;
    7884            0 :   while (fgets (line1, sizeof (line1), f1))
    7885              :     {
    7886            0 :       if (!fgets (line2, sizeof (line2), f2))
    7887            0 :         goto error;
    7888            0 :       char *p1 = line1, *p2 = line2;
    7889            0 :       if (line_start
    7890            0 :           && line1[0] == '0'
    7891            0 :           && line1[1] == 'x'
    7892            0 :           && line2[0] == '0'
    7893            0 :           && line2[1] == 'x')
    7894              :         {
    7895              :           int i, j;
    7896            0 :           for (i = 0; i < 16; ++i)
    7897            0 :             if (!ISXDIGIT (line1[2 + i]) || ISUPPER (line1[2 + i]))
    7898              :               break;
    7899            0 :           for (j = 0; j < 16; ++j)
    7900            0 :             if (!ISXDIGIT (line2[2 + j]) || ISUPPER (line2[2 + j]))
    7901              :               break;
    7902            0 :           if (i && line1[2 + i] == ' ' && j && line2[2 + j] == ' ')
    7903              :             {
    7904            0 :               p1 = line1 + i + 3;
    7905            0 :               p2 = line2 + j + 3;
    7906              :             }
    7907              :         }
    7908            0 :       if (strcmp (p1, p2) != 0)
    7909            0 :         goto error;
    7910            0 :       line_start = strchr (line1, '\n') != NULL;
    7911              :     }
    7912            0 :   if (fgets (line2, sizeof (line2), f2))
    7913            0 :     goto error;
    7914              : 
    7915            0 :   fclose (f1);
    7916            0 :   fclose (f2);
    7917            0 :   return 1;
    7918              : 
    7919            0 : error:
    7920            0 :   fclose (f1);
    7921            0 :   fclose (f2);
    7922            0 :   return 0;
    7923              : }
    7924              : 
    7925              : /* Check that compiler's output doesn't differ across runs.
    7926              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are arrays of files, containing
    7927              :    stdout and stderr for each compiler run.  Return true if all of
    7928              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are equivalent.  */
    7929              : 
    7930              : static bool
    7931            0 : check_repro (char **temp_stdout_files, char **temp_stderr_files)
    7932              : {
    7933            0 :   int i;
    7934            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS - 2; ++i)
    7935              :     {
    7936            0 :      if (!files_equal_p (temp_stdout_files[i], temp_stdout_files[i + 1])
    7937            0 :          || !files_equal_p (temp_stderr_files[i], temp_stderr_files[i + 1]))
    7938              :        {
    7939            0 :          fnotice (stderr, "The bug is not reproducible, so it is"
    7940              :                   " likely a hardware or OS problem.\n");
    7941            0 :          break;
    7942              :        }
    7943              :     }
    7944            0 :   return i == RETRY_ICE_ATTEMPTS - 2;
    7945              : }
    7946              : 
    7947              : enum attempt_status {
    7948              :   ATTEMPT_STATUS_FAIL_TO_RUN,
    7949              :   ATTEMPT_STATUS_SUCCESS,
    7950              :   ATTEMPT_STATUS_ICE
    7951              : };
    7952              : 
    7953              : 
    7954              : /* Run compiler with arguments NEW_ARGV to reproduce the ICE, storing stdout
    7955              :    to OUT_TEMP and stderr to ERR_TEMP.  If APPEND is TRUE, append to OUT_TEMP
    7956              :    and ERR_TEMP instead of truncating.  If EMIT_SYSTEM_INFO is TRUE, also write
    7957              :    GCC configuration into to ERR_TEMP.  Return ATTEMPT_STATUS_FAIL_TO_RUN if
    7958              :    compiler failed to run, ATTEMPT_STATUS_ICE if compiled ICE-ed and
    7959              :    ATTEMPT_STATUS_SUCCESS otherwise.  */
    7960              : 
    7961              : static enum attempt_status
    7962            0 : run_attempt (const char **new_argv, const char *out_temp,
    7963              :              const char *err_temp, int emit_system_info, int append)
    7964              : {
    7965              : 
    7966            0 :   if (emit_system_info)
    7967              :     {
    7968            0 :       FILE *file_out = fopen (err_temp, "a");
    7969            0 :       print_configuration (file_out);
    7970            0 :       fputs ("\n", file_out);
    7971            0 :       fclose (file_out);
    7972              :     }
    7973              : 
    7974            0 :   int exit_status;
    7975            0 :   const char *errmsg;
    7976            0 :   struct pex_obj *pex;
    7977            0 :   int err;
    7978            0 :   int pex_flags = PEX_USE_PIPES | PEX_LAST;
    7979            0 :   enum attempt_status status = ATTEMPT_STATUS_FAIL_TO_RUN;
    7980              : 
    7981            0 :   if (append)
    7982            0 :     pex_flags |= PEX_STDOUT_APPEND | PEX_STDERR_APPEND;
    7983              : 
    7984            0 :   pex = pex_init (PEX_USE_PIPES, new_argv[0], NULL);
    7985            0 :   if (!pex)
    7986              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    7987              : 
    7988            0 :   errmsg = pex_run (pex, pex_flags, new_argv[0],
    7989            0 :                     const_cast<char *const *> (&new_argv[1]),
    7990              :                     out_temp, err_temp, &err);
    7991            0 :   if (errmsg != NULL)
    7992              :     {
    7993            0 :       errno = err;
    7994            0 :       fatal_error (input_location,
    7995              :                    err ? G_ ("cannot execute %qs: %s: %m")
    7996              :                    : G_ ("cannot execute %qs: %s"),
    7997              :                    new_argv[0], errmsg);
    7998              :     }
    7999              : 
    8000            0 :   if (!pex_get_status (pex, 1, &exit_status))
    8001            0 :     goto out;
    8002              : 
    8003            0 :   switch (WEXITSTATUS (exit_status))
    8004              :     {
    8005              :       case ICE_EXIT_CODE:
    8006            0 :         status = ATTEMPT_STATUS_ICE;
    8007              :         break;
    8008              : 
    8009            0 :       case SUCCESS_EXIT_CODE:
    8010            0 :         status = ATTEMPT_STATUS_SUCCESS;
    8011            0 :         break;
    8012              : 
    8013            0 :       default:
    8014            0 :         ;
    8015              :     }
    8016              : 
    8017            0 : out:
    8018            0 :   pex_free (pex);
    8019            0 :   return status;
    8020              : }
    8021              : 
    8022              : /* This routine reads lines from IN file, adds C++ style comments
    8023              :    at the beginning of each line and writes result into OUT.  */
    8024              : 
    8025              : static void
    8026            0 : insert_comments (const char *file_in, const char *file_out)
    8027              : {
    8028            0 :   FILE *in = fopen (file_in, "rb");
    8029            0 :   FILE *out = fopen (file_out, "wb");
    8030            0 :   char line[256];
    8031              : 
    8032            0 :   bool add_comment = true;
    8033            0 :   while (fgets (line, sizeof (line), in))
    8034              :     {
    8035            0 :       if (add_comment)
    8036            0 :         fputs ("// ", out);
    8037            0 :       fputs (line, out);
    8038            0 :       add_comment = strchr (line, '\n') != NULL;
    8039              :     }
    8040              : 
    8041            0 :   fclose (in);
    8042            0 :   fclose (out);
    8043            0 : }
    8044              : 
    8045              : /* This routine adds preprocessed source code into the given ERR_FILE.
    8046              :    To do this, it adds "-E" to NEW_ARGV and execute RUN_ATTEMPT routine to
    8047              :    add information in report file.  RUN_ATTEMPT should return
    8048              :    ATTEMPT_STATUS_SUCCESS, in other case we cannot generate the report.  */
    8049              : 
    8050              : static void
    8051            0 : do_report_bug (const char **new_argv, const int nargs,
    8052              :                char **out_file, char **err_file)
    8053              : {
    8054            0 :   int i, status;
    8055            0 :   int fd = open (*out_file, O_RDWR | O_APPEND);
    8056            0 :   if (fd < 0)
    8057              :     return;
    8058            0 :   write (fd, "\n//", 3);
    8059            0 :   for (i = 0; i < nargs; i++)
    8060              :     {
    8061            0 :       write (fd, " ", 1);
    8062            0 :       write (fd, new_argv[i], strlen (new_argv[i]));
    8063              :     }
    8064            0 :   write (fd, "\n\n", 2);
    8065            0 :   close (fd);
    8066            0 :   new_argv[nargs] = "-E";
    8067            0 :   new_argv[nargs + 1] = NULL;
    8068              : 
    8069            0 :   status = run_attempt (new_argv, *out_file, *err_file, 0, 1);
    8070              : 
    8071            0 :   if (status == ATTEMPT_STATUS_SUCCESS)
    8072              :     {
    8073            0 :       fnotice (stderr, "Preprocessed source stored into %s file,"
    8074              :                " please attach this to your bugreport.\n", *out_file);
    8075              :       /* Make sure it is not deleted.  */
    8076            0 :       free (*out_file);
    8077            0 :       *out_file = NULL;
    8078              :     }
    8079              : }
    8080              : 
    8081              : /* Try to reproduce ICE.  If bug is reproducible, generate report .err file
    8082              :    containing GCC configuration, backtrace, compiler's command line options
    8083              :    and preprocessed source code.  */
    8084              : 
    8085              : static void
    8086            0 : try_generate_repro (const char **argv)
    8087              : {
    8088            0 :   int i, nargs, out_arg = -1, quiet = 0, attempt;
    8089            0 :   const char **new_argv;
    8090            0 :   char *temp_files[RETRY_ICE_ATTEMPTS * 2];
    8091            0 :   char **temp_stdout_files = &temp_files[0];
    8092            0 :   char **temp_stderr_files = &temp_files[RETRY_ICE_ATTEMPTS];
    8093              : 
    8094            0 :   if (gcc_input_filename == NULL || ! strcmp (gcc_input_filename, "-"))
    8095            0 :     return;
    8096              : 
    8097            0 :   for (nargs = 0; argv[nargs] != NULL; ++nargs)
    8098              :     /* Only retry compiler ICEs, not preprocessor ones.  */
    8099            0 :     if (! strcmp (argv[nargs], "-E"))
    8100              :       return;
    8101            0 :     else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o')
    8102              :       {
    8103            0 :         if (out_arg == -1)
    8104              :           out_arg = nargs;
    8105              :         else
    8106              :           return;
    8107              :       }
    8108              :     /* If the compiler is going to output any time information,
    8109              :        it might varry between invocations.  */
    8110            0 :     else if (! strcmp (argv[nargs], "-quiet"))
    8111              :       quiet = 1;
    8112            0 :     else if (! strcmp (argv[nargs], "-ftime-report"))
    8113              :       return;
    8114              : 
    8115            0 :   if (out_arg == -1 || !quiet)
    8116              :     return;
    8117              : 
    8118            0 :   memset (temp_files, '\0', sizeof (temp_files));
    8119            0 :   new_argv = XALLOCAVEC (const char *, nargs + 4);
    8120            0 :   memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *));
    8121            0 :   new_argv[nargs++] = "-frandom-seed=0";
    8122            0 :   new_argv[nargs++] = "-fdump-noaddr";
    8123            0 :   new_argv[nargs] = NULL;
    8124            0 :   if (new_argv[out_arg][2] == '\0')
    8125            0 :     new_argv[out_arg + 1] = "-";
    8126              :   else
    8127            0 :     new_argv[out_arg] = "-o-";
    8128              : 
    8129              : #ifdef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
    8130            0 :   personality (personality (0xffffffffU) | ADDR_NO_RANDOMIZE);
    8131              : #endif
    8132              : 
    8133            0 :   int status;
    8134            0 :   for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS; ++attempt)
    8135              :     {
    8136            0 :       int emit_system_info = 0;
    8137            0 :       int append = 0;
    8138            0 :       temp_stdout_files[attempt] = make_temp_file (".out");
    8139            0 :       temp_stderr_files[attempt] = make_temp_file (".err");
    8140              : 
    8141            0 :       if (attempt == RETRY_ICE_ATTEMPTS - 1)
    8142              :         {
    8143            0 :           append = 1;
    8144            0 :           emit_system_info = 1;
    8145              :         }
    8146              : 
    8147            0 :       status = run_attempt (new_argv, temp_stdout_files[attempt],
    8148              :                             temp_stderr_files[attempt], emit_system_info,
    8149              :                             append);
    8150              : 
    8151            0 :       if (status != ATTEMPT_STATUS_ICE)
    8152              :         {
    8153            0 :           fnotice (stderr, "The bug is not reproducible, so it is"
    8154              :                    " likely a hardware or OS problem.\n");
    8155            0 :           goto out;
    8156              :         }
    8157              :     }
    8158              : 
    8159            0 :   if (!check_repro (temp_stdout_files, temp_stderr_files))
    8160            0 :     goto out;
    8161              : 
    8162            0 :   {
    8163              :     /* Insert commented out backtrace into report file.  */
    8164            0 :     char **stderr_commented = &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1];
    8165            0 :     insert_comments (temp_stderr_files[RETRY_ICE_ATTEMPTS - 1],
    8166              :                      *stderr_commented);
    8167              : 
    8168              :     /* In final attempt we append compiler options and preprocesssed code to last
    8169              :        generated .out file with configuration and backtrace.  */
    8170            0 :     char **err = &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1];
    8171            0 :     do_report_bug (new_argv, nargs, stderr_commented, err);
    8172              :   }
    8173              : 
    8174              : out:
    8175            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS * 2; i++)
    8176            0 :     if (temp_files[i])
    8177              :       {
    8178            0 :         unlink (temp_stdout_files[i]);
    8179            0 :         free (temp_stdout_files[i]);
    8180              :       }
    8181              : }
    8182              : 
    8183              : /* Search for a file named NAME trying various prefixes including the
    8184              :    user's -B prefix and some standard ones.
    8185              :    Return the absolute file name found.  If nothing is found, return NAME.  */
    8186              : 
    8187              : static const char *
    8188       559685 : find_file (const char *name)
    8189              : {
    8190       559685 :   char *newname = find_a_file (&startfile_prefixes, name, true);
    8191       559685 :   return newname ? newname : name;
    8192              : }
    8193              : 
    8194              : /* Determine whether a directory exists.  */
    8195              : 
    8196              : static int
    8197     10754658 : is_directory (const char *path1)
    8198              : {
    8199     10754658 :   int len1;
    8200     10754658 :   char *path;
    8201     10754658 :   char *cp;
    8202     10754658 :   struct stat st;
    8203              : 
    8204              :   /* Ensure the string ends with "/.".  The resulting path will be a
    8205              :      directory even if the given path is a symbolic link.  */
    8206     10754658 :   len1 = strlen (path1);
    8207     10754658 :   path = (char *) alloca (3 + len1);
    8208     10754658 :   memcpy (path, path1, len1);
    8209     10754658 :   cp = path + len1;
    8210     10754658 :   if (!IS_DIR_SEPARATOR (cp[-1]))
    8211      1535816 :     *cp++ = DIR_SEPARATOR;
    8212     10754658 :   *cp++ = '.';
    8213     10754658 :   *cp = '\0';
    8214              : 
    8215     10754658 :   return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
    8216              : }
    8217              : 
    8218              : /* Set up the various global variables to indicate that we're processing
    8219              :    the input file named FILENAME.  */
    8220              : 
    8221              : void
    8222       861083 : set_input (const char *filename)
    8223              : {
    8224       861083 :   const char *p;
    8225              : 
    8226       861083 :   gcc_input_filename = filename;
    8227       861083 :   input_filename_length = strlen (gcc_input_filename);
    8228       861083 :   input_basename = lbasename (gcc_input_filename);
    8229              : 
    8230              :   /* Find a suffix starting with the last period,
    8231              :      and set basename_length to exclude that suffix.  */
    8232       861083 :   basename_length = strlen (input_basename);
    8233       861083 :   suffixed_basename_length = basename_length;
    8234       861083 :   p = input_basename + basename_length;
    8235      3768377 :   while (p != input_basename && *p != '.')
    8236      2907294 :     --p;
    8237       861083 :   if (*p == '.' && p != input_basename)
    8238              :     {
    8239       618937 :       basename_length = p - input_basename;
    8240       618937 :       input_suffix = p + 1;
    8241              :     }
    8242              :   else
    8243       242146 :     input_suffix = "";
    8244              : 
    8245              :   /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then
    8246              :      we will need to do a stat on the gcc_input_filename.  The
    8247              :      INPUT_STAT_SET signals that the stat is needed.  */
    8248       861083 :   input_stat_set = 0;
    8249       861083 : }
    8250              : 
    8251              : /* On fatal signals, delete all the temporary files.  */
    8252              : 
    8253              : static void
    8254            0 : fatal_signal (int signum)
    8255              : {
    8256            0 :   signal (signum, SIG_DFL);
    8257            0 :   delete_failure_queue ();
    8258            0 :   delete_temp_files ();
    8259              :   /* Get the same signal again, this time not handled,
    8260              :      so its normal effect occurs.  */
    8261            0 :   kill (getpid (), signum);
    8262            0 : }
    8263              : 
    8264              : /* Compare the contents of the two files named CMPFILE[0] and
    8265              :    CMPFILE[1].  Return zero if they're identical, nonzero
    8266              :    otherwise.  */
    8267              : 
    8268              : static int
    8269          629 : compare_files (char *cmpfile[])
    8270              : {
    8271          629 :   int ret = 0;
    8272          629 :   FILE *temp[2] = { NULL, NULL };
    8273          629 :   int i;
    8274              : 
    8275              : #if HAVE_MMAP_FILE
    8276          629 :   {
    8277          629 :     size_t length[2];
    8278          629 :     void *map[2] = { NULL, NULL };
    8279              : 
    8280         1887 :     for (i = 0; i < 2; i++)
    8281              :       {
    8282         1258 :         struct stat st;
    8283              : 
    8284         1258 :         if (stat (cmpfile[i], &st) < 0 || !S_ISREG (st.st_mode))
    8285              :           {
    8286            0 :             error ("%s: could not determine length of compare-debug file %s",
    8287              :                    gcc_input_filename, cmpfile[i]);
    8288            0 :             ret = 1;
    8289            0 :             break;
    8290              :           }
    8291              : 
    8292         1258 :         length[i] = st.st_size;
    8293              :       }
    8294              : 
    8295          629 :     if (!ret && length[0] != length[1])
    8296              :       {
    8297           14 :         error ("%s: %<-fcompare-debug%> failure (length)", gcc_input_filename);
    8298           14 :         ret = 1;
    8299              :       }
    8300              : 
    8301           14 :     if (!ret)
    8302         1779 :       for (i = 0; i < 2; i++)
    8303              :         {
    8304         1197 :           int fd = open (cmpfile[i], O_RDONLY);
    8305         1197 :           if (fd < 0)
    8306              :             {
    8307            0 :               error ("%s: could not open compare-debug file %s",
    8308              :                      gcc_input_filename, cmpfile[i]);
    8309            0 :               ret = 1;
    8310            0 :               break;
    8311              :             }
    8312              : 
    8313         1197 :           map[i] = mmap (NULL, length[i], PROT_READ, MAP_PRIVATE, fd, 0);
    8314         1197 :           close (fd);
    8315              : 
    8316         1197 :           if (map[i] == (void *) MAP_FAILED)
    8317              :             {
    8318              :               ret = -1;
    8319              :               break;
    8320              :             }
    8321              :         }
    8322              : 
    8323          615 :     if (!ret)
    8324              :       {
    8325          582 :         if (memcmp (map[0], map[1], length[0]) != 0)
    8326              :           {
    8327            0 :             error ("%s: %<-fcompare-debug%> failure", gcc_input_filename);
    8328            0 :             ret = 1;
    8329              :           }
    8330              :       }
    8331              : 
    8332         1887 :     for (i = 0; i < 2; i++)
    8333         1258 :       if (map[i])
    8334         1197 :         munmap ((caddr_t) map[i], length[i]);
    8335              : 
    8336          629 :     if (ret >= 0)
    8337          596 :       return ret;
    8338              : 
    8339           33 :     ret = 0;
    8340              :   }
    8341              : #endif
    8342              : 
    8343           99 :   for (i = 0; i < 2; i++)
    8344              :     {
    8345           66 :       temp[i] = fopen (cmpfile[i], "r");
    8346           66 :       if (!temp[i])
    8347              :         {
    8348            0 :           error ("%s: could not open compare-debug file %s",
    8349              :                  gcc_input_filename, cmpfile[i]);
    8350            0 :           ret = 1;
    8351            0 :           break;
    8352              :         }
    8353              :     }
    8354              : 
    8355           33 :   if (!ret && temp[0] && temp[1])
    8356           33 :     for (;;)
    8357              :       {
    8358           33 :         int c0, c1;
    8359           33 :         c0 = fgetc (temp[0]);
    8360           33 :         c1 = fgetc (temp[1]);
    8361              : 
    8362           33 :         if (c0 != c1)
    8363              :           {
    8364            0 :             error ("%s: %<-fcompare-debug%> failure",
    8365              :                    gcc_input_filename);
    8366            0 :             ret = 1;
    8367            0 :             break;
    8368              :           }
    8369              : 
    8370           33 :         if (c0 == EOF)
    8371              :           break;
    8372              :       }
    8373              : 
    8374           99 :   for (i = 1; i >= 0; i--)
    8375              :     {
    8376           66 :       if (temp[i])
    8377           66 :         fclose (temp[i]);
    8378              :     }
    8379              : 
    8380              :   return ret;
    8381              : }
    8382              : 
    8383       312002 : driver::driver (bool can_finalize, bool debug) :
    8384       312002 :   explicit_link_files (NULL),
    8385       312002 :   decoded_options (NULL)
    8386              : {
    8387       312002 :   env.init (can_finalize, debug);
    8388       312002 : }
    8389              : 
    8390       311520 : driver::~driver ()
    8391              : {
    8392       311520 :   XDELETEVEC (explicit_link_files);
    8393       311520 :   XDELETEVEC (decoded_options);
    8394       311520 : }
    8395              : 
    8396              : /* driver::main is implemented as a series of driver:: method calls.  */
    8397              : 
    8398              : int
    8399       312002 : driver::main (int argc, char **argv)
    8400              : {
    8401       312002 :   bool early_exit;
    8402              : 
    8403       312002 :   set_progname (argv[0]);
    8404       312002 :   expand_at_files (&argc, &argv);
    8405       312002 :   decode_argv (argc, const_cast <const char **> (argv));
    8406       312002 :   global_initializations ();
    8407       312002 :   build_multilib_strings ();
    8408       312002 :   set_up_specs ();
    8409       311715 :   putenv_COLLECT_AS_OPTIONS (assembler_options);
    8410       311715 :   putenv_COLLECT_GCC (argv[0]);
    8411       311715 :   maybe_putenv_COLLECT_LTO_WRAPPER ();
    8412       311715 :   maybe_putenv_OFFLOAD_TARGETS ();
    8413       311715 :   handle_unrecognized_options ();
    8414              : 
    8415       311715 :   if (completion)
    8416              :     {
    8417            5 :       m_option_proposer.suggest_completion (completion);
    8418            5 :       return 0;
    8419              :     }
    8420              : 
    8421       311710 :   if (!maybe_print_and_exit ())
    8422              :     return 0;
    8423              : 
    8424       294827 :   early_exit = prepare_infiles ();
    8425       294633 :   if (early_exit)
    8426          566 :     return get_exit_code ();
    8427              : 
    8428       294067 :   do_spec_on_infiles ();
    8429       294067 :   maybe_run_linker (argv[0]);
    8430       294067 :   final_actions ();
    8431       294067 :   return get_exit_code ();
    8432              : }
    8433              : 
    8434              : /* Locate the final component of argv[0] after any leading path, and set
    8435              :    the program name accordingly.  */
    8436              : 
    8437              : void
    8438       312002 : driver::set_progname (const char *argv0) const
    8439              : {
    8440       312002 :   const char *p = argv0 + strlen (argv0);
    8441      1719950 :   while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
    8442      1407948 :     --p;
    8443       312002 :   progname = p;
    8444              : 
    8445       312002 :   xmalloc_set_program_name (progname);
    8446       312002 : }
    8447              : 
    8448              : /* Expand any @ files within the command-line args,
    8449              :    setting at_file_supplied if any were expanded.  */
    8450              : 
    8451              : void
    8452       312002 : driver::expand_at_files (int *argc, char ***argv) const
    8453              : {
    8454       312002 :   char **old_argv = *argv;
    8455              : 
    8456       312002 :   expandargv (argc, argv);
    8457              : 
    8458              :   /* Determine if any expansions were made.  */
    8459       312002 :   if (*argv != old_argv)
    8460        13877 :     at_file_supplied = true;
    8461       312002 : }
    8462              : 
    8463              : /* Decode the command-line arguments from argc/argv into the
    8464              :    decoded_options array.  */
    8465              : 
    8466              : void
    8467       312002 : driver::decode_argv (int argc, const char **argv)
    8468              : {
    8469       312002 :   init_opts_obstack ();
    8470       312002 :   init_options_struct (&global_options, &global_options_set);
    8471              : 
    8472       312002 :   decode_cmdline_options_to_array (argc, argv,
    8473              :                                    CL_DRIVER,
    8474              :                                    &decoded_options, &decoded_options_count);
    8475       312002 : }
    8476              : 
    8477              : /* Perform various initializations and setup.  */
    8478              : 
    8479              : void
    8480       312002 : driver::global_initializations ()
    8481              : {
    8482              :   /* Unlock the stdio streams.  */
    8483       312002 :   unlock_std_streams ();
    8484              : 
    8485       312002 :   gcc_init_libintl ();
    8486              : 
    8487       312002 :   diagnostic_initialize (global_dc, 0);
    8488       312002 :   diagnostic_color_init (global_dc);
    8489       312002 :   diagnostic_urls_init (global_dc);
    8490       312002 :   global_dc->push_owned_urlifier (make_gcc_urlifier (0));
    8491              : 
    8492              : #ifdef GCC_DRIVER_HOST_INITIALIZATION
    8493              :   /* Perform host dependent initialization when needed.  */
    8494              :   GCC_DRIVER_HOST_INITIALIZATION;
    8495              : #endif
    8496              : 
    8497       312002 :   if (atexit (delete_temp_files) != 0)
    8498            0 :     fatal_error (input_location, "atexit failed");
    8499              : 
    8500       312002 :   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
    8501       311851 :     signal (SIGINT, fatal_signal);
    8502              : #ifdef SIGHUP
    8503       312002 :   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
    8504        21415 :     signal (SIGHUP, fatal_signal);
    8505              : #endif
    8506       312002 :   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
    8507       312002 :     signal (SIGTERM, fatal_signal);
    8508              : #ifdef SIGPIPE
    8509       312002 :   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
    8510       312002 :     signal (SIGPIPE, fatal_signal);
    8511              : #endif
    8512              : #ifdef SIGCHLD
    8513              :   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
    8514              :      receive the signal.  A different setting is inheritable */
    8515       312002 :   signal (SIGCHLD, SIG_DFL);
    8516              : #endif
    8517              : 
    8518              :   /* Parsing and gimplification sometimes need quite large stack.
    8519              :      Increase stack size limits if possible.  */
    8520              : #ifdef __SANITIZE_ADDRESS__
    8521              :   stack_limit_increase (128 * 1024 * 1024);
    8522              : #else
    8523       312002 :   stack_limit_increase (64 * 1024 * 1024);
    8524              : #endif
    8525              : 
    8526              :   /* Allocate the argument vector.  */
    8527       312002 :   alloc_args ();
    8528              : 
    8529       312002 :   obstack_init (&obstack);
    8530       312002 : }
    8531              : 
    8532              : /* Build multilib_select, et. al from the separate lines that make up each
    8533              :    multilib selection.  */
    8534              : 
    8535              : void
    8536       312002 : driver::build_multilib_strings () const
    8537              : {
    8538       312002 :   {
    8539       312002 :     const char *p;
    8540       312002 :     const char *const *q = multilib_raw;
    8541       312002 :     int need_space;
    8542              : 
    8543       312002 :     obstack_init (&multilib_obstack);
    8544       312002 :     while ((p = *q++) != (char *) 0)
    8545      1248008 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8546              : 
    8547       312002 :     obstack_1grow (&multilib_obstack, 0);
    8548       312002 :     multilib_select = XOBFINISH (&multilib_obstack, const char *);
    8549              : 
    8550       312002 :     q = multilib_matches_raw;
    8551       312002 :     while ((p = *q++) != (char *) 0)
    8552       936006 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8553              : 
    8554       312002 :     obstack_1grow (&multilib_obstack, 0);
    8555       312002 :     multilib_matches = XOBFINISH (&multilib_obstack, const char *);
    8556              : 
    8557       312002 :     q = multilib_exclusions_raw;
    8558       312002 :     while ((p = *q++) != (char *) 0)
    8559       312002 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8560              : 
    8561       312002 :     obstack_1grow (&multilib_obstack, 0);
    8562       312002 :     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
    8563              : 
    8564       312002 :     q = multilib_reuse_raw;
    8565       312002 :     while ((p = *q++) != (char *) 0)
    8566       312002 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8567              : 
    8568       312002 :     obstack_1grow (&multilib_obstack, 0);
    8569       312002 :     multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
    8570              : 
    8571       312002 :     need_space = false;
    8572       624004 :     for (size_t i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
    8573              :       {
    8574       312002 :         if (need_space)
    8575            0 :           obstack_1grow (&multilib_obstack, ' ');
    8576       312002 :         obstack_grow (&multilib_obstack,
    8577              :                       multilib_defaults_raw[i],
    8578              :                       strlen (multilib_defaults_raw[i]));
    8579       312002 :         need_space = true;
    8580              :       }
    8581              : 
    8582       312002 :     obstack_1grow (&multilib_obstack, 0);
    8583       312002 :     multilib_defaults = XOBFINISH (&multilib_obstack, const char *);
    8584              :   }
    8585       312002 : }
    8586              : 
    8587              : /* Set up the spec-handling machinery.  */
    8588              : 
    8589              : void
    8590       312002 : driver::set_up_specs () const
    8591              : {
    8592       312002 :   const char *spec_machine_suffix;
    8593       312002 :   char *specs_file;
    8594       312002 :   size_t i;
    8595              : 
    8596              : #ifdef INIT_ENVIRONMENT
    8597              :   /* Set up any other necessary machine specific environment variables.  */
    8598              :   xputenv (INIT_ENVIRONMENT);
    8599              : #endif
    8600              : 
    8601              :   /* Make a table of what switches there are (switches, n_switches).
    8602              :      Make a table of specified input files (infiles, n_infiles).
    8603              :      Decode switches that are handled locally.  */
    8604              : 
    8605       312002 :   process_command (decoded_options_count, decoded_options);
    8606              : 
    8607              :   /* Initialize the vector of specs to just the default.
    8608              :      This means one element containing 0s, as a terminator.  */
    8609              : 
    8610       311716 :   compilers = XNEWVAR (struct compiler, sizeof default_compilers);
    8611       311716 :   memcpy (compilers, default_compilers, sizeof default_compilers);
    8612       311716 :   n_compilers = n_default_compilers;
    8613              : 
    8614              :   /* Read specs from a file if there is one.  */
    8615              : 
    8616       311716 :   machine_suffix = concat (spec_host_machine, dir_separator_str, spec_version,
    8617              :                            accel_dir_suffix, dir_separator_str, NULL);
    8618       311716 :   just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
    8619       311716 :   just_machine_prefix = concat (spec_machine, "-", NULL);
    8620              : 
    8621       311716 :   specs_file = find_a_file (&startfile_prefixes, "specs", true);
    8622              :   /* Read the specs file unless it is a default one.  */
    8623       311716 :   if (specs_file != 0 && strcmp (specs_file, "specs"))
    8624       310520 :     read_specs (specs_file, true, false);
    8625              :   else
    8626         1196 :     init_spec ();
    8627              : 
    8628              : #ifdef ACCEL_COMPILER
    8629              :   spec_machine_suffix = machine_suffix;
    8630              : #else
    8631       311716 :   spec_machine_suffix = just_machine_suffix;
    8632              : #endif
    8633              : 
    8634       311716 :   const char *exec_prefix
    8635       311716 :     = gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix;
    8636              :   /* We need to check standard_exec_prefix/spec_machine_suffix/specs
    8637              :      for any override of as, ld and libraries.  */
    8638       311716 :   specs_file = (char *) alloca (
    8639              :     strlen (exec_prefix) + strlen (spec_machine_suffix) + sizeof ("specs"));
    8640       311716 :   strcpy (specs_file, exec_prefix);
    8641       311716 :   strcat (specs_file, spec_machine_suffix);
    8642       311716 :   strcat (specs_file, "specs");
    8643       311716 :   if (access (specs_file, R_OK) == 0)
    8644            0 :     read_specs (specs_file, true, false);
    8645              : 
    8646              :   /* Process any configure-time defaults specified for the command line
    8647              :      options, via OPTION_DEFAULT_SPECS.  */
    8648      3428876 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
    8649      3117160 :     do_option_spec (option_default_specs[i].name,
    8650      3117160 :                     option_default_specs[i].spec);
    8651              : 
    8652              :   /* Process DRIVER_SELF_SPECS, adding any new options to the end
    8653              :      of the command line.  */
    8654              : 
    8655      2182012 :   for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
    8656      1870296 :     do_self_spec (driver_self_specs[i]);
    8657              : 
    8658              :   /* If not cross-compiling, look for executables in the standard
    8659              :      places.  */
    8660       311716 :   if (*cross_compile == '0')
    8661              :     {
    8662       311716 :       if (*md_exec_prefix)
    8663              :         {
    8664            0 :           add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
    8665              :                       PREFIX_PRIORITY_LAST, 0, 0);
    8666              :         }
    8667              :     }
    8668              : 
    8669              :   /* Process sysroot_suffix_spec.  */
    8670       311716 :   if (*sysroot_suffix_spec != 0
    8671            0 :       && !no_sysroot_suffix
    8672       311716 :       && do_spec_2 (sysroot_suffix_spec, NULL) == 0)
    8673              :     {
    8674            0 :       if (argbuf.length () > 1)
    8675            0 :         error ("spec failure: more than one argument to "
    8676              :                "%<SYSROOT_SUFFIX_SPEC%>");
    8677            0 :       else if (argbuf.length () == 1)
    8678            0 :         target_sysroot_suffix = xstrdup (argbuf.last ());
    8679              :     }
    8680              : 
    8681              : #ifdef HAVE_LD_SYSROOT
    8682              :   /* Pass the --sysroot option to the linker, if it supports that.  If
    8683              :      there is a sysroot_suffix_spec, it has already been processed by
    8684              :      this point, so target_system_root really is the system root we
    8685              :      should be using.  */
    8686       311716 :   if (target_system_root)
    8687              :     {
    8688            0 :       obstack_grow (&obstack, "%(sysroot_spec) ", strlen ("%(sysroot_spec) "));
    8689            0 :       obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    8690            0 :       set_spec ("link", XOBFINISH (&obstack, const char *), false);
    8691              :     }
    8692              : #endif
    8693              : 
    8694              :   /* Process sysroot_hdrs_suffix_spec.  */
    8695       311716 :   if (*sysroot_hdrs_suffix_spec != 0
    8696            0 :       && !no_sysroot_suffix
    8697       311716 :       && do_spec_2 (sysroot_hdrs_suffix_spec, NULL) == 0)
    8698              :     {
    8699            0 :       if (argbuf.length () > 1)
    8700            0 :         error ("spec failure: more than one argument "
    8701              :                "to %<SYSROOT_HEADERS_SUFFIX_SPEC%>");
    8702            0 :       else if (argbuf.length () == 1)
    8703            0 :         target_sysroot_hdrs_suffix = xstrdup (argbuf.last ());
    8704              :     }
    8705              : 
    8706              :   /* Look for startfiles in the standard places.  */
    8707       311716 :   if (*startfile_prefix_spec != 0
    8708            0 :       && do_spec_2 (startfile_prefix_spec, NULL) == 0
    8709       311716 :       && do_spec_1 (" ", 0, NULL) == 0)
    8710              :     {
    8711            0 :       for (const char *arg : argbuf)
    8712            0 :         add_sysrooted_prefix (&startfile_prefixes, arg, "BINUTILS",
    8713              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8714              :     }
    8715              :   /* We should eventually get rid of all these and stick to
    8716              :      startfile_prefix_spec exclusively.  */
    8717       311716 :   else if (*cross_compile == '0' || target_system_root)
    8718              :     {
    8719       311716 :       if (*md_startfile_prefix)
    8720            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
    8721              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8722              : 
    8723       311716 :       if (*md_startfile_prefix_1)
    8724            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
    8725              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8726              : 
    8727              :       /* If standard_startfile_prefix is relative, base it on
    8728              :          standard_exec_prefix.  This lets us move the installed tree
    8729              :          as a unit.  If GCC_EXEC_PREFIX is defined, base
    8730              :          standard_startfile_prefix on that as well.
    8731              : 
    8732              :          If the prefix is relative, only search it for native compilers;
    8733              :          otherwise we will search a directory containing host libraries.  */
    8734       311716 :       if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
    8735              :         add_sysrooted_prefix (&startfile_prefixes,
    8736              :                               standard_startfile_prefix, "BINUTILS",
    8737              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8738       311716 :       else if (*cross_compile == '0')
    8739              :         {
    8740       311716 :           add_prefix (&startfile_prefixes,
    8741       623432 :                       concat (gcc_exec_prefix
    8742              :                               ? gcc_exec_prefix : standard_exec_prefix,
    8743              :                               machine_suffix,
    8744              :                               standard_startfile_prefix, NULL),
    8745              :                       NULL, PREFIX_PRIORITY_LAST, 0, 1);
    8746              :         }
    8747              : 
    8748              :       /* Sysrooted prefixes are relocated because target_system_root is
    8749              :          also relocated by gcc_exec_prefix.  */
    8750       311716 :       if (*standard_startfile_prefix_1)
    8751       311716 :         add_sysrooted_prefix (&startfile_prefixes,
    8752              :                               standard_startfile_prefix_1, "BINUTILS",
    8753              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8754       311716 :       if (*standard_startfile_prefix_2)
    8755       311716 :         add_sysrooted_prefix (&startfile_prefixes,
    8756              :                               standard_startfile_prefix_2, "BINUTILS",
    8757              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8758              :     }
    8759              : 
    8760              :   /* Process any user specified specs in the order given on the command
    8761              :      line.  */
    8762       311718 :   for (struct user_specs *uptr = user_specs_head; uptr; uptr = uptr->next)
    8763              :     {
    8764            3 :       char *filename = find_a_file (&startfile_prefixes, uptr->filename,
    8765              :                                     true);
    8766            3 :       read_specs (filename ? filename : uptr->filename, false, true);
    8767              :     }
    8768              : 
    8769              :   /* Process any user self specs.  */
    8770       311715 :   {
    8771       311715 :     struct spec_list *sl;
    8772     14650605 :     for (sl = specs; sl; sl = sl->next)
    8773     14338890 :       if (sl->name_len == sizeof "self_spec" - 1
    8774      2182005 :           && !strcmp (sl->name, "self_spec"))
    8775       311715 :         do_self_spec (*sl->ptr_spec);
    8776              :   }
    8777              : 
    8778       311715 :   if (compare_debug)
    8779              :     {
    8780          635 :       enum save_temps save;
    8781              : 
    8782          635 :       if (!compare_debug_second)
    8783              :         {
    8784          635 :           n_switches_debug_check[1] = n_switches;
    8785          635 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8786          635 :           switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
    8787              :                                              n_switches_alloc);
    8788              : 
    8789          635 :           do_self_spec ("%:compare-debug-self-opt()");
    8790          635 :           n_switches_debug_check[0] = n_switches;
    8791          635 :           n_switches_alloc_debug_check[0] = n_switches_alloc;
    8792          635 :           switches_debug_check[0] = switches;
    8793              : 
    8794          635 :           n_switches = n_switches_debug_check[1];
    8795          635 :           n_switches_alloc = n_switches_alloc_debug_check[1];
    8796          635 :           switches = switches_debug_check[1];
    8797              :         }
    8798              : 
    8799              :       /* Avoid crash when computing %j in this early.  */
    8800          635 :       save = save_temps_flag;
    8801          635 :       save_temps_flag = SAVE_TEMPS_NONE;
    8802              : 
    8803          635 :       compare_debug = -compare_debug;
    8804          635 :       do_self_spec ("%:compare-debug-self-opt()");
    8805              : 
    8806          635 :       save_temps_flag = save;
    8807              : 
    8808          635 :       if (!compare_debug_second)
    8809              :         {
    8810          635 :           n_switches_debug_check[1] = n_switches;
    8811          635 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8812          635 :           switches_debug_check[1] = switches;
    8813          635 :           compare_debug = -compare_debug;
    8814          635 :           n_switches = n_switches_debug_check[0];
    8815          635 :           n_switches_alloc = n_switches_debug_check[0];
    8816          635 :           switches = switches_debug_check[0];
    8817              :         }
    8818              :     }
    8819              : 
    8820              : 
    8821              :   /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake.  */
    8822       311715 :   if (gcc_exec_prefix)
    8823       311715 :     gcc_exec_prefix = concat (gcc_exec_prefix, spec_host_machine,
    8824              :                               dir_separator_str, spec_version,
    8825              :                               accel_dir_suffix, dir_separator_str, NULL);
    8826              : 
    8827              :   /* Now we have the specs.
    8828              :      Set the `valid' bits for switches that match anything in any spec.  */
    8829              : 
    8830       311715 :   validate_all_switches ();
    8831              : 
    8832              :   /* Now that we have the switches and the specs, set
    8833              :      the subdirectory based on the options.  */
    8834       311715 :   set_multilib_dir ();
    8835       311715 : }
    8836              : 
    8837              : /* Set up to remember the pathname of gcc and any options
    8838              :    needed for collect.  We use argv[0] instead of progname because
    8839              :    we need the complete pathname.  */
    8840              : 
    8841              : void
    8842       311715 : driver::putenv_COLLECT_GCC (const char *argv0) const
    8843              : {
    8844       311715 :   obstack_init (&collect_obstack);
    8845       311715 :   obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
    8846       311715 :   obstack_grow (&collect_obstack, argv0, strlen (argv0) + 1);
    8847       311715 :   xputenv (XOBFINISH (&collect_obstack, char *));
    8848       311715 : }
    8849              : 
    8850              : /* Set up to remember the pathname of the lto wrapper. */
    8851              : 
    8852              : void
    8853       311715 : driver::maybe_putenv_COLLECT_LTO_WRAPPER () const
    8854              : {
    8855       311715 :   char *lto_wrapper_file;
    8856              : 
    8857       311715 :   if (have_c)
    8858              :     lto_wrapper_file = NULL;
    8859              :   else
    8860       115435 :     lto_wrapper_file = find_a_program ("lto-wrapper");
    8861       115435 :   if (lto_wrapper_file)
    8862              :     {
    8863       226198 :       lto_wrapper_file = convert_white_space (lto_wrapper_file);
    8864       113099 :       set_static_spec_owned (&lto_wrapper_spec, lto_wrapper_file);
    8865       113099 :       obstack_init (&collect_obstack);
    8866       113099 :       obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
    8867              :                     sizeof ("COLLECT_LTO_WRAPPER=") - 1);
    8868       113099 :       obstack_grow (&collect_obstack, lto_wrapper_spec,
    8869              :                     strlen (lto_wrapper_spec) + 1);
    8870       113099 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8871              :     }
    8872              : 
    8873       311715 : }
    8874              : 
    8875              : /* Set up to remember the names of offload targets.  */
    8876              : 
    8877              : void
    8878       311715 : driver::maybe_putenv_OFFLOAD_TARGETS () const
    8879              : {
    8880       311715 :   if (offload_targets && offload_targets[0] != '\0')
    8881              :     {
    8882            0 :       obstack_grow (&collect_obstack, "OFFLOAD_TARGET_NAMES=",
    8883              :                     sizeof ("OFFLOAD_TARGET_NAMES=") - 1);
    8884            0 :       obstack_grow (&collect_obstack, offload_targets,
    8885              :                     strlen (offload_targets) + 1);
    8886            0 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8887              : #if OFFLOAD_DEFAULTED
    8888              :       if (offload_targets_default)
    8889              :         xputenv ("OFFLOAD_TARGET_DEFAULT=1");
    8890              : #endif
    8891              :     }
    8892              : 
    8893       311715 :   free (offload_targets);
    8894       311715 :   offload_targets = NULL;
    8895       311715 : }
    8896              : 
    8897              : /* Reject switches that no pass was interested in.  */
    8898              : 
    8899              : void
    8900       311715 : driver::handle_unrecognized_options ()
    8901              : {
    8902      7291964 :   for (size_t i = 0; (int) i < n_switches; i++)
    8903      6980249 :     if (! switches[i].validated)
    8904              :       {
    8905          700 :         const char *hint = m_option_proposer.suggest_option (switches[i].part1);
    8906          700 :         if (hint)
    8907          219 :           error ("unrecognized command-line option %<-%s%>;"
    8908              :                  " did you mean %<-%s%>?",
    8909          219 :                  switches[i].part1, hint);
    8910              :         else
    8911          481 :           error ("unrecognized command-line option %<-%s%>",
    8912          481 :                  switches[i].part1);
    8913              :       }
    8914       311715 : }
    8915              : 
    8916              : /* Handle the various -print-* options, returning 0 if the driver
    8917              :    should exit, or nonzero if the driver should continue.  */
    8918              : 
    8919              : int
    8920       311710 : driver::maybe_print_and_exit () const
    8921              : {
    8922       311710 :   if (print_search_dirs)
    8923              :     {
    8924           56 :       printf (_("install: %s%s\n"),
    8925              :               gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    8926           28 :               gcc_exec_prefix ? "" : machine_suffix);
    8927           28 :       printf (_("programs: %s\n"),
    8928              :               build_search_list (&exec_prefixes, "", false, false));
    8929           28 :       printf (_("libraries: %s\n"),
    8930              :               build_search_list (&startfile_prefixes, "", false, true));
    8931           28 :       return (0);
    8932              :     }
    8933              : 
    8934       311682 :   if (print_autofdo_gcov_version)
    8935              :     {
    8936            0 :       printf ("%d\n", AUTO_PROFILE_VERSION);
    8937            0 :       return (0);
    8938              :     }
    8939              : 
    8940       311682 :   if (print_file_name)
    8941              :     {
    8942         5032 :       printf ("%s\n", find_file (print_file_name));
    8943         5032 :       return (0);
    8944              :     }
    8945              : 
    8946       306650 :   if (print_prog_name)
    8947              :     {
    8948          217 :       if (use_ld != NULL && ! strcmp (print_prog_name, "ld"))
    8949              :         {
    8950              :           /* Append USE_LD to the default linker.  */
    8951              : #ifdef DEFAULT_LINKER
    8952              :           char *ld;
    8953              : # ifdef HAVE_HOST_EXECUTABLE_SUFFIX
    8954              :           int len = (sizeof (DEFAULT_LINKER)
    8955              :                      - sizeof (HOST_EXECUTABLE_SUFFIX));
    8956              :           ld = NULL;
    8957              :           if (len > 0)
    8958              :             {
    8959              :               char *default_linker = xstrdup (DEFAULT_LINKER);
    8960              :               /* Strip HOST_EXECUTABLE_SUFFIX if DEFAULT_LINKER contains
    8961              :                  HOST_EXECUTABLE_SUFFIX.  */
    8962              :               if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
    8963              :                 {
    8964              :                   default_linker[len] = '\0';
    8965              :                   ld = concat (default_linker, use_ld,
    8966              :                                HOST_EXECUTABLE_SUFFIX, NULL);
    8967              :                 }
    8968              :             }
    8969              :           if (ld == NULL)
    8970              : # endif
    8971              :           ld = concat (DEFAULT_LINKER, use_ld, NULL);
    8972              :           if (access (ld, X_OK) == 0)
    8973              :             {
    8974              :               printf ("%s\n", ld);
    8975              :               return (0);
    8976              :             }
    8977              : #endif
    8978            0 :           print_prog_name = concat (print_prog_name, use_ld, NULL);
    8979              :         }
    8980          217 :       char *newname = find_a_program (print_prog_name);
    8981          217 :       printf ("%s\n", (newname ? newname : print_prog_name));
    8982          217 :       return (0);
    8983              :     }
    8984              : 
    8985       306433 :   if (print_multi_lib)
    8986              :     {
    8987         5577 :       print_multilib_info ();
    8988         5577 :       return (0);
    8989              :     }
    8990              : 
    8991       300856 :   if (print_multi_directory)
    8992              :     {
    8993         4996 :       if (multilib_dir == NULL)
    8994         4971 :         printf (".\n");
    8995              :       else
    8996           25 :         printf ("%s\n", multilib_dir);
    8997         4996 :       return (0);
    8998              :     }
    8999              : 
    9000       295860 :   if (print_multiarch)
    9001              :     {
    9002            0 :       if (multiarch_dir == NULL)
    9003            0 :         printf ("\n");
    9004              :       else
    9005            0 :         printf ("%s\n", multiarch_dir);
    9006            0 :       return (0);
    9007              :     }
    9008              : 
    9009       295860 :   if (print_sysroot)
    9010              :     {
    9011            0 :       if (target_system_root)
    9012              :         {
    9013            0 :           if (target_sysroot_suffix)
    9014            0 :             printf ("%s%s\n", target_system_root, target_sysroot_suffix);
    9015              :           else
    9016            0 :             printf ("%s\n", target_system_root);
    9017              :         }
    9018            0 :       return (0);
    9019              :     }
    9020              : 
    9021       295860 :   if (print_multi_os_directory)
    9022              :     {
    9023          149 :       if (multilib_os_dir == NULL)
    9024            0 :         printf (".\n");
    9025              :       else
    9026          149 :         printf ("%s\n", multilib_os_dir);
    9027          149 :       return (0);
    9028              :     }
    9029              : 
    9030       295711 :   if (print_sysroot_headers_suffix)
    9031              :     {
    9032            1 :       if (*sysroot_hdrs_suffix_spec)
    9033              :         {
    9034            0 :           printf("%s\n", (target_sysroot_hdrs_suffix
    9035              :                           ? target_sysroot_hdrs_suffix
    9036              :                           : ""));
    9037            0 :           return (0);
    9038              :         }
    9039              :       else
    9040              :         /* The error status indicates that only one set of fixed
    9041              :            headers should be built.  */
    9042            1 :         fatal_error (input_location,
    9043              :                      "not configured with sysroot headers suffix");
    9044              :     }
    9045              : 
    9046       295710 :   if (print_help_list)
    9047              :     {
    9048            4 :       display_help ();
    9049              : 
    9050            4 :       if (! verbose_flag)
    9051              :         {
    9052            1 :           printf (_("\nFor bug reporting instructions, please see:\n"));
    9053            1 :           printf ("%s.\n", bug_report_url);
    9054              : 
    9055            1 :           return (0);
    9056              :         }
    9057              : 
    9058              :       /* We do not exit here.  Instead we have created a fake input file
    9059              :          called 'help-dummy' which needs to be compiled, and we pass this
    9060              :          on the various sub-processes, along with the --help switch.
    9061              :          Ensure their output appears after ours.  */
    9062            3 :       fputc ('\n', stdout);
    9063            3 :       fflush (stdout);
    9064              :     }
    9065              : 
    9066       295709 :   if (print_version)
    9067              :     {
    9068           78 :       printf (_("%s %s%s\n"), progname, pkgversion_string,
    9069              :               version_string);
    9070           78 :       printf ("Copyright %s 2026 Free Software Foundation, Inc.\n",
    9071              :               _("(C)"));
    9072           78 :       fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
    9073              : warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
    9074              :              stdout);
    9075           78 :       if (! verbose_flag)
    9076              :         return 0;
    9077              : 
    9078              :       /* We do not exit here. We use the same mechanism of --help to print
    9079              :          the version of the sub-processes. */
    9080            0 :       fputc ('\n', stdout);
    9081            0 :       fflush (stdout);
    9082              :     }
    9083              : 
    9084       295631 :   if (verbose_flag)
    9085              :     {
    9086         1658 :       print_configuration (stderr);
    9087         1658 :       if (n_infiles == 0)
    9088              :         return (0);
    9089              :     }
    9090              : 
    9091              :   return 1;
    9092              : }
    9093              : 
    9094              : /* Figure out what to do with each input file.
    9095              :    Return true if we need to exit early from "main", false otherwise.  */
    9096              : 
    9097              : bool
    9098       294827 : driver::prepare_infiles ()
    9099              : {
    9100       294827 :   size_t i;
    9101       294827 :   int lang_n_infiles = 0;
    9102              : 
    9103       294827 :   if (n_infiles == added_libraries)
    9104          194 :     fatal_error (input_location, "no input files");
    9105              : 
    9106       294633 :   if (seen_error ())
    9107              :     /* Early exit needed from main.  */
    9108              :     return true;
    9109              : 
    9110              :   /* Make a place to record the compiler output file names
    9111              :      that correspond to the input files.  */
    9112              : 
    9113       294067 :   i = n_infiles;
    9114       294067 :   i += lang_specific_extra_outfiles;
    9115       294067 :   outfiles = XCNEWVEC (const char *, i);
    9116              : 
    9117              :   /* Record which files were specified explicitly as link input.  */
    9118              : 
    9119       294067 :   explicit_link_files = XCNEWVEC (char, n_infiles);
    9120              : 
    9121       294067 :   combine_inputs = have_o || flag_wpa;
    9122              : 
    9123       862995 :   for (i = 0; (int) i < n_infiles; i++)
    9124              :     {
    9125       568928 :       const char *name = infiles[i].name;
    9126       568928 :       struct compiler *compiler = lookup_compiler (name,
    9127              :                                                    strlen (name),
    9128              :                                                    infiles[i].language);
    9129              : 
    9130       568928 :       if (compiler && !(compiler->combinable))
    9131       262634 :         combine_inputs = false;
    9132              : 
    9133       568928 :       if (lang_n_infiles > 0 && compiler != input_file_compiler
    9134       253021 :           && infiles[i].language && infiles[i].language[0] != '*')
    9135           36 :         infiles[i].incompiler = compiler;
    9136       568892 :       else if (infiles[i].artificial)
    9137              :         /* Leave lang_n_infiles alone so files added by the driver don't
    9138              :            interfere with -c -o.  */
    9139            3 :         infiles[i].incompiler = compiler;
    9140       568889 :       else if (compiler)
    9141              :         {
    9142       305068 :           lang_n_infiles++;
    9143       305068 :           input_file_compiler = compiler;
    9144       305068 :           infiles[i].incompiler = compiler;
    9145              :         }
    9146              :       else
    9147              :         {
    9148              :           /* Since there is no compiler for this input file, assume it is a
    9149              :              linker file.  */
    9150       263821 :           explicit_link_files[i] = 1;
    9151       263821 :           infiles[i].incompiler = NULL;
    9152              :         }
    9153       568928 :       infiles[i].compiled = false;
    9154       568928 :       infiles[i].preprocessed = false;
    9155              :     }
    9156              : 
    9157       294067 :   if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
    9158            0 :     fatal_error (input_location,
    9159              :                  "cannot specify %<-o%> with %<-c%>, %<-S%> or %<-E%> "
    9160              :                  "with multiple files");
    9161              : 
    9162              :   /* No early exit needed from main; we can continue.  */
    9163              :   return false;
    9164              : }
    9165              : 
    9166              : /* Run the spec machinery on each input file.  */
    9167              : 
    9168              : void
    9169       294067 : driver::do_spec_on_infiles () const
    9170              : {
    9171       294067 :   size_t i;
    9172              : 
    9173       862995 :   for (i = 0; (int) i < n_infiles; i++)
    9174              :     {
    9175       568928 :       int this_file_error = 0;
    9176              : 
    9177              :       /* Tell do_spec what to substitute for %i.  */
    9178              : 
    9179       568928 :       input_file_number = i;
    9180       568928 :       set_input (infiles[i].name);
    9181              : 
    9182       568928 :       if (infiles[i].compiled)
    9183         9116 :         continue;
    9184              : 
    9185              :       /* Use the same thing in %o, unless cp->spec says otherwise.  */
    9186              : 
    9187       559812 :       outfiles[i] = gcc_input_filename;
    9188              : 
    9189              :       /* Figure out which compiler from the file's suffix.  */
    9190              : 
    9191       559812 :       input_file_compiler
    9192       559812 :         = lookup_compiler (infiles[i].name, input_filename_length,
    9193              :                            infiles[i].language);
    9194              : 
    9195       559812 :       if (input_file_compiler)
    9196              :         {
    9197              :           /* Ok, we found an applicable compiler.  Run its spec.  */
    9198              : 
    9199       295991 :           if (input_file_compiler->spec[0] == '#')
    9200              :             {
    9201            0 :               error ("%s: %s compiler not installed on this system",
    9202              :                      gcc_input_filename, &input_file_compiler->spec[1]);
    9203            0 :               this_file_error = 1;
    9204              :             }
    9205              :           else
    9206              :             {
    9207       295991 :               int value;
    9208              : 
    9209       295991 :               if (compare_debug)
    9210              :                 {
    9211          633 :                   free (debug_check_temp_file[0]);
    9212          633 :                   debug_check_temp_file[0] = NULL;
    9213              : 
    9214          633 :                   free (debug_check_temp_file[1]);
    9215          633 :                   debug_check_temp_file[1] = NULL;
    9216              :                 }
    9217              : 
    9218       295991 :               value = do_spec (input_file_compiler->spec);
    9219       295991 :               infiles[i].compiled = true;
    9220       295991 :               if (value < 0)
    9221              :                 this_file_error = 1;
    9222       265603 :               else if (compare_debug && debug_check_temp_file[0])
    9223              :                 {
    9224          629 :                   if (verbose_flag)
    9225            0 :                     inform (UNKNOWN_LOCATION,
    9226              :                             "recompiling with %<-fcompare-debug%>");
    9227              : 
    9228          629 :                   compare_debug = -compare_debug;
    9229          629 :                   n_switches = n_switches_debug_check[1];
    9230          629 :                   n_switches_alloc = n_switches_alloc_debug_check[1];
    9231          629 :                   switches = switches_debug_check[1];
    9232              : 
    9233          629 :                   value = do_spec (input_file_compiler->spec);
    9234              : 
    9235          629 :                   compare_debug = -compare_debug;
    9236          629 :                   n_switches = n_switches_debug_check[0];
    9237          629 :                   n_switches_alloc = n_switches_alloc_debug_check[0];
    9238          629 :                   switches = switches_debug_check[0];
    9239              : 
    9240          629 :                   if (value < 0)
    9241              :                     {
    9242            2 :                       error ("during %<-fcompare-debug%> recompilation");
    9243            2 :                       this_file_error = 1;
    9244              :                     }
    9245              : 
    9246          629 :                   gcc_assert (debug_check_temp_file[1]
    9247              :                               && filename_cmp (debug_check_temp_file[0],
    9248              :                                                debug_check_temp_file[1]));
    9249              : 
    9250          629 :                   if (verbose_flag)
    9251            0 :                     inform (UNKNOWN_LOCATION, "comparing final insns dumps");
    9252              : 
    9253          629 :                   if (compare_files (debug_check_temp_file))
    9254        30402 :                     this_file_error = 1;
    9255              :                 }
    9256              : 
    9257       295991 :               if (compare_debug)
    9258              :                 {
    9259          633 :                   free (debug_check_temp_file[0]);
    9260          633 :                   debug_check_temp_file[0] = NULL;
    9261              : 
    9262          633 :                   free (debug_check_temp_file[1]);
    9263          633 :                   debug_check_temp_file[1] = NULL;
    9264              :                 }
    9265              :             }
    9266              :         }
    9267              : 
    9268              :       /* If this file's name does not contain a recognized suffix,
    9269              :          record it as explicit linker input.  */
    9270              : 
    9271              :       else
    9272       263821 :         explicit_link_files[i] = 1;
    9273              : 
    9274              :       /* Clear the delete-on-failure queue, deleting the files in it
    9275              :          if this compilation failed.  */
    9276              : 
    9277       559812 :       if (this_file_error)
    9278              :         {
    9279        30402 :           delete_failure_queue ();
    9280        30402 :           errorcount++;
    9281              :         }
    9282              :       /* If this compilation succeeded, don't delete those files later.  */
    9283       559812 :       clear_failure_queue ();
    9284              :     }
    9285              : 
    9286              :   /* Reset the input file name to the first compile/object file name, for use
    9287              :      with %b in LINK_SPEC. We use the first input file that we can find
    9288              :      a compiler to compile it instead of using infiles.language since for
    9289              :      languages other than C we use aliases that we then lookup later.  */
    9290       294067 :   if (n_infiles > 0)
    9291              :     {
    9292              :       int i;
    9293              : 
    9294       306302 :       for (i = 0; i < n_infiles ; i++)
    9295       304390 :         if (infiles[i].incompiler
    9296        12235 :             || (infiles[i].language && infiles[i].language[0] != '*'))
    9297              :           {
    9298       292155 :             set_input (infiles[i].name);
    9299       292155 :             break;
    9300              :           }
    9301              :     }
    9302              : 
    9303       294067 :   if (!seen_error ())
    9304              :     {
    9305              :       /* Make sure INPUT_FILE_NUMBER points to first available open
    9306              :          slot.  */
    9307       263665 :       input_file_number = n_infiles;
    9308       263665 :       if (lang_specific_pre_link ())
    9309            0 :         errorcount++;
    9310              :     }
    9311       294067 : }
    9312              : 
    9313              : /* If we have to run the linker, do it now.  */
    9314              : 
    9315              : void
    9316       294067 : driver::maybe_run_linker (const char *argv0) const
    9317              : {
    9318       294067 :   size_t i;
    9319       294067 :   int linker_was_run = 0;
    9320       294067 :   int num_linker_inputs;
    9321              : 
    9322              :   /* Determine if there are any linker input files.  */
    9323       294067 :   num_linker_inputs = 0;
    9324       862995 :   for (i = 0; (int) i < n_infiles; i++)
    9325       568928 :     if (explicit_link_files[i] || outfiles[i] != NULL)
    9326       559345 :       num_linker_inputs++;
    9327              : 
    9328              :   /* Arrange for temporary file names created during linking to take
    9329              :      on names related with the linker output rather than with the
    9330              :      inputs when appropriate.  */
    9331       294067 :   if (outbase && *outbase)
    9332              :     {
    9333       272293 :       if (dumpdir)
    9334              :         {
    9335        90683 :           char *tofree = dumpdir;
    9336        90683 :           gcc_checking_assert (strlen (dumpdir) == dumpdir_length);
    9337        90683 :           dumpdir = concat (dumpdir, outbase, ".", NULL);
    9338        90683 :           free (tofree);
    9339              :         }
    9340              :       else
    9341       181610 :         dumpdir = concat (outbase, ".", NULL);
    9342       272293 :       dumpdir_length += strlen (outbase) + 1;
    9343       272293 :       dumpdir_trailing_dash_added = true;
    9344       272293 :     }
    9345        21774 :   else if (dumpdir_trailing_dash_added)
    9346              :     {
    9347        17339 :       gcc_assert (dumpdir[dumpdir_length - 1] == '-');
    9348        17339 :       dumpdir[dumpdir_length - 1] = '.';
    9349              :     }
    9350              : 
    9351       294067 :   if (dumpdir_trailing_dash_added)
    9352              :     {
    9353       289632 :       gcc_assert (dumpdir_length > 0);
    9354       289632 :       gcc_assert (dumpdir[dumpdir_length - 1] == '.');
    9355       289632 :       dumpdir_length--;
    9356              :     }
    9357              : 
    9358       294067 :   free (outbase);
    9359       294067 :   input_basename = outbase = NULL;
    9360       294067 :   outbase_length = suffixed_basename_length = basename_length = 0;
    9361              : 
    9362              :   /* Run ld to link all the compiler output files.  */
    9363              : 
    9364       294067 :   if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
    9365              :     {
    9366       263090 :       int tmp = execution_count;
    9367              : 
    9368       263090 :       detect_jobserver ();
    9369              : 
    9370       263090 :       if (! have_c)
    9371              :         {
    9372              : #if HAVE_LTO_PLUGIN > 0
    9373              : #if HAVE_LTO_PLUGIN == 2
    9374        98149 :           const char *fno_use_linker_plugin = "fno-use-linker-plugin";
    9375              : #else
    9376              :           const char *fuse_linker_plugin = "fuse-linker-plugin";
    9377              : #endif
    9378              : #endif
    9379              : 
    9380              :           /* We'll use ld if we can't find collect2.  */
    9381        98149 :           if (! strcmp (linker_name_spec, "collect2"))
    9382              :             {
    9383        98149 :               char *s = find_a_program ("collect2");
    9384        98149 :               if (s == NULL)
    9385         1139 :                 set_static_spec_shared (&linker_name_spec, "ld");
    9386              :             }
    9387              : 
    9388              : #if HAVE_LTO_PLUGIN > 0
    9389              : #if HAVE_LTO_PLUGIN == 2
    9390        98149 :           if (!switch_matches (fno_use_linker_plugin,
    9391              :                                fno_use_linker_plugin
    9392              :                                + strlen (fno_use_linker_plugin), 0))
    9393              : #else
    9394              :           if (switch_matches (fuse_linker_plugin,
    9395              :                               fuse_linker_plugin
    9396              :                               + strlen (fuse_linker_plugin), 0))
    9397              : #endif
    9398              :             {
    9399        92602 :               char *temp_spec = find_a_file (&exec_prefixes,
    9400              :                                              LTOPLUGINSONAME,
    9401              :                                              false);
    9402        92602 :               if (!temp_spec)
    9403            0 :                 fatal_error (input_location,
    9404              :                              "%<-fuse-linker-plugin%>, but %s not found",
    9405              :                              LTOPLUGINSONAME);
    9406        92602 :               linker_plugin_file_spec = convert_white_space (temp_spec);
    9407              :             }
    9408              : #endif
    9409        98149 :           set_static_spec_shared (&lto_gcc_spec, argv0);
    9410              :         }
    9411              : 
    9412              :       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    9413              :          for collect.  */
    9414       263090 :       putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
    9415       263090 :       putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
    9416              : 
    9417       263090 :       if (print_subprocess_help == 1)
    9418              :         {
    9419            0 :           printf (_("\nLinker options\n==============\n\n"));
    9420            0 :           printf (_("Use \"-Wl,OPTION\" to pass \"OPTION\""
    9421              :                     " to the linker.\n\n"));
    9422            0 :           fflush (stdout);
    9423              :         }
    9424       263090 :       int value = do_spec (link_command_spec);
    9425       263090 :       if (value < 0)
    9426          132 :         errorcount = 1;
    9427       263090 :       linker_was_run = (tmp != execution_count);
    9428              :     }
    9429              : 
    9430              :   /* If options said don't run linker,
    9431              :      complain about input files to be given to the linker.  */
    9432              : 
    9433       294067 :   if (! linker_was_run && !seen_error ())
    9434       364393 :     for (i = 0; (int) i < n_infiles; i++)
    9435       198873 :       if (explicit_link_files[i]
    9436        24252 :           && !(infiles[i].language && infiles[i].language[0] == '*'))
    9437              :         {
    9438           38 :           warning (0, "%s: linker input file unused because linking not done",
    9439           19 :                    outfiles[i]);
    9440           19 :           if (access (outfiles[i], F_OK) < 0)
    9441              :             /* This is can be an indication the user specified an erroneous
    9442              :                separated option value, (or used the wrong prefix for an
    9443              :                option).  */
    9444            7 :             error ("%s: linker input file not found: %m", outfiles[i]);
    9445              :         }
    9446       294067 : }
    9447              : 
    9448              : /* The end of "main".  */
    9449              : 
    9450              : void
    9451       294067 : driver::final_actions () const
    9452              : {
    9453              :   /* Delete some or all of the temporary files we made.  */
    9454              : 
    9455       294067 :   if (seen_error ())
    9456        30539 :     delete_failure_queue ();
    9457       294067 :   delete_temp_files ();
    9458              : 
    9459       294067 :   if (totruncate_file != NULL && !seen_error ())
    9460              :     /* Truncate file specified by -truncate.
    9461              :        Used by lto-wrapper to reduce temporary disk-space usage. */
    9462         9532 :     truncate(totruncate_file, 0);
    9463              : 
    9464       294067 :   if (print_help_list)
    9465              :     {
    9466            3 :       printf (("\nFor bug reporting instructions, please see:\n"));
    9467            3 :       printf ("%s\n", bug_report_url);
    9468              :     }
    9469       294067 : }
    9470              : 
    9471              : /* Detect whether jobserver is active and working.  If not drop
    9472              :    --jobserver-auth from MAKEFLAGS.  */
    9473              : 
    9474              : void
    9475       263090 : driver::detect_jobserver () const
    9476              : {
    9477       263090 :   jobserver_info jinfo;
    9478       263090 :   if (!jinfo.is_active && !jinfo.skipped_makeflags.empty ())
    9479            0 :     xputenv (xstrdup (jinfo.skipped_makeflags.c_str ()));
    9480       263090 : }
    9481              : 
    9482              : /* Determine what the exit code of the driver should be.  */
    9483              : 
    9484              : int
    9485       294633 : driver::get_exit_code () const
    9486              : {
    9487       294633 :   return (signal_count != 0 ? 2
    9488       294633 :           : seen_error () ? (pass_exit_codes ? greatest_status : 1)
    9489            0 :           : 0);
    9490              : }
    9491              : 
    9492              : /* Find the proper compilation spec for the file name NAME,
    9493              :    whose length is LENGTH.  LANGUAGE is the specified language,
    9494              :    or 0 if this file is to be passed to the linker.  */
    9495              : 
    9496              : static struct compiler *
    9497      1128740 : lookup_compiler (const char *name, size_t length, const char *language)
    9498              : {
    9499      1651159 :   struct compiler *cp;
    9500              : 
    9501              :   /* If this was specified by the user to be a linker input, indicate that.  */
    9502      1651159 :   if (language != 0 && language[0] == '*')
    9503              :     return 0;
    9504              : 
    9505              :   /* Otherwise, look for the language, if one is spec'd.  */
    9506      1171315 :   if (language != 0)
    9507              :     {
    9508     23961317 :       for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9509     23961317 :         if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language))
    9510              :           {
    9511       601084 :             if (name != NULL && strcmp (name, "-") == 0
    9512         2072 :                 && (strcmp (cp->suffix, "@c-header") == 0
    9513         2072 :                     || strcmp (cp->suffix, "@c++-header") == 0)
    9514            0 :                 && !have_E)
    9515            0 :               fatal_error (input_location,
    9516              :                            "cannot use %<-%> as input filename for a "
    9517              :                            "precompiled header");
    9518              : 
    9519              :             return cp;
    9520              :           }
    9521              : 
    9522            0 :       error ("language %s not recognized", language);
    9523            0 :       return 0;
    9524              :     }
    9525              : 
    9526              :   /* Look for a suffix.  */
    9527     31710289 :   for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9528              :     {
    9529     31662491 :       if (/* The suffix `-' matches only the file name `-'.  */
    9530     31662491 :           (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9531     31662477 :           || (strlen (cp->suffix) < length
    9532              :               /* See if the suffix matches the end of NAME.  */
    9533     31181190 :               && !strcmp (cp->suffix,
    9534     31181190 :                           name + length - strlen (cp->suffix))
    9535              :          ))
    9536              :         break;
    9537              :     }
    9538              : 
    9539              : #if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
    9540              :   /* Look again, but case-insensitively this time.  */
    9541              :   if (cp < compilers)
    9542              :     for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9543              :       {
    9544              :         if (/* The suffix `-' matches only the file name `-'.  */
    9545              :             (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9546              :             || (strlen (cp->suffix) < length
    9547              :                 /* See if the suffix matches the end of NAME.  */
    9548              :                 && ((!strcmp (cp->suffix,
    9549              :                              name + length - strlen (cp->suffix))
    9550              :                      || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
    9551              :                     && !strcasecmp (cp->suffix,
    9552              :                                     name + length - strlen (cp->suffix)))
    9553              :            ))
    9554              :           break;
    9555              :       }
    9556              : #endif
    9557              : 
    9558       570231 :   if (cp >= compilers)
    9559              :     {
    9560       522433 :       if (cp->spec[0] != '@')
    9561              :         /* A non-alias entry: return it.  */
    9562              :         return cp;
    9563              : 
    9564              :       /* An alias entry maps a suffix to a language.
    9565              :          Search for the language; pass 0 for NAME and LENGTH
    9566              :          to avoid infinite recursion if language not found.  */
    9567       522419 :       return lookup_compiler (NULL, 0, cp->spec + 1);
    9568              :     }
    9569              :   return 0;
    9570              : }
    9571              : 
    9572              : static char *
    9573     48176461 : save_string (const char *s, int len)
    9574              : {
    9575     48176461 :   char *result = XNEWVEC (char, len + 1);
    9576              : 
    9577     48176461 :   gcc_checking_assert (strlen (s) >= (unsigned int) len);
    9578     48176461 :   memcpy (result, s, len);
    9579     48176461 :   result[len] = 0;
    9580     48176461 :   return result;
    9581              : }
    9582              : 
    9583              : 
    9584              : static inline void
    9585     48315825 : validate_switches_from_spec (const char *spec, bool user)
    9586              : {
    9587     48315825 :   const char *p = spec;
    9588     48315825 :   char c;
    9589    596310798 :   while ((c = *p++))
    9590    499679148 :     if (c == '%'
    9591    499679148 :         && (*p == '{'
    9592     11845170 :             || *p == '<'
    9593     10910025 :             || (*p == 'W' && *++p == '{')
    9594     10910025 :             || (*p == '@' && *++p == '{')))
    9595              :       /* We have a switch spec.  */
    9596     48004112 :       p = validate_switches (p + 1, user, *p == '{');
    9597     48315825 : }
    9598              : 
    9599              : static void
    9600       311715 : validate_all_switches (void)
    9601              : {
    9602       311715 :   struct compiler *comp;
    9603       311715 :   struct spec_list *spec;
    9604              : 
    9605     33976935 :   for (comp = compilers; comp->spec; comp++)
    9606     33665220 :     validate_switches_from_spec (comp->spec, false);
    9607              : 
    9608              :   /* Look through the linked list of specs read from the specs file.  */
    9609     14650605 :   for (spec = specs; spec; spec = spec->next)
    9610     14338890 :     validate_switches_from_spec (*spec->ptr_spec, spec->user_p);
    9611              : 
    9612       311715 :   validate_switches_from_spec (link_command_spec, false);
    9613       311715 : }
    9614              : 
    9615              : /* Look at the switch-name that comes after START and mark as valid
    9616              :    all supplied switches that match it.  If BRACED, handle other
    9617              :    switches after '|' and '&', and specs after ':' until ';' or '}',
    9618              :    going back for more switches after ';'.  Without BRACED, handle
    9619              :    only one atom.  Return a pointer to whatever follows the handled
    9620              :    items, after the closing brace if BRACED.  */
    9621              : 
    9622              : static const char *
    9623    207602192 : validate_switches (const char *start, bool user_spec, bool braced)
    9624              : {
    9625    207602192 :   const char *p = start;
    9626    267763187 :   const char *atom;
    9627    267763187 :   size_t len;
    9628    267763187 :   int i;
    9629    267763187 :   bool suffix;
    9630    267763187 :   bool starred;
    9631              : 
    9632              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    9633              : 
    9634    267763187 : next_member:
    9635    267763187 :   suffix = false;
    9636    267763187 :   starred = false;
    9637              : 
    9638    295817537 :   SKIP_WHITE ();
    9639              : 
    9640    267763187 :   if (*p == '!')
    9641     82916191 :     p++;
    9642              : 
    9643    267763187 :   SKIP_WHITE ();
    9644    267763187 :   if (*p == '.' || *p == ',')
    9645            0 :     suffix = true, p++;
    9646              : 
    9647    267763187 :   atom = p;
    9648    267763187 :   while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    9649   1792672981 :          || *p == ',' || *p == '.' || *p == '@')
    9650   1524909794 :     p++;
    9651    267763187 :   len = p - atom;
    9652              : 
    9653    267763187 :   if (*p == '*')
    9654     70759305 :     starred = true, p++;
    9655              : 
    9656    269010047 :   SKIP_WHITE ();
    9657              : 
    9658    267763187 :   if (!suffix)
    9659              :     {
    9660              :       /* Mark all matching switches as valid.  */
    9661   6263797108 :       for (i = 0; i < n_switches; i++)
    9662   5996033921 :         if (!strncmp (switches[i].part1, atom, len)
    9663    498746043 :             && (starred || switches[i].part1[len] == '\0')
    9664     51883082 :             && (switches[i].known || user_spec))
    9665     51880006 :               switches[i].validated = true;
    9666              :     }
    9667              : 
    9668    267763187 :   if (!braced)
    9669              :     return p;
    9670              : 
    9671    266204612 :   if (*p) p++;
    9672    266204612 :   if (*p && (p[-1] == '|' || p[-1] == '&'))
    9673     41146380 :     goto next_member;
    9674              : 
    9675    225058232 :   if (*p && p[-1] == ':')
    9676              :     {
    9677   3022388636 :       while (*p && *p != ';' && *p != '}')
    9678              :         {
    9679   2848763378 :           if (*p == '%')
    9680              :             {
    9681    268074900 :               p++;
    9682    268074900 :               if (*p == '{' || *p == '<')
    9683    156792645 :                 p = validate_switches (p+1, user_spec, *p == '{');
    9684    111282255 :               else if (p[0] == 'W' && p[1] == '{')
    9685      2493720 :                 p = validate_switches (p+2, user_spec, true);
    9686    108788535 :               else if (p[0] == '@' && p[1] == '{')
    9687       311715 :                 p = validate_switches (p+2, user_spec, true);
    9688              :             }
    9689              :           else
    9690   2580688478 :             p++;
    9691              :         }
    9692              : 
    9693    173625258 :       if (*p) p++;
    9694    173625258 :       if (*p && p[-1] == ';')
    9695     19014615 :         goto next_member;
    9696              :     }
    9697              : 
    9698              :   return p;
    9699              : #undef SKIP_WHITE
    9700              : }
    9701              : 
    9702              : struct mdswitchstr
    9703              : {
    9704              :   const char *str;
    9705              :   int len;
    9706              : };
    9707              : 
    9708              : static struct mdswitchstr *mdswitches;
    9709              : static int n_mdswitches;
    9710              : 
    9711              : /* Check whether a particular argument was used.  The first time we
    9712              :    canonicalize the switches to keep only the ones we care about.  */
    9713              : 
    9714              : struct used_arg_t
    9715              : {
    9716              :  public:
    9717              :   int operator () (const char *p, int len);
    9718              :   void finalize ();
    9719              : 
    9720              :  private:
    9721              :   struct mswitchstr
    9722              :   {
    9723              :     const char *str;
    9724              :     const char *replace;
    9725              :     int len;
    9726              :     int rep_len;
    9727              :   };
    9728              : 
    9729              :   mswitchstr *mswitches;
    9730              :   int n_mswitches;
    9731              : 
    9732              : };
    9733              : 
    9734              : used_arg_t used_arg;
    9735              : 
    9736              : int
    9737      1883731 : used_arg_t::operator () (const char *p, int len)
    9738              : {
    9739      1883731 :   int i, j;
    9740              : 
    9741      1883731 :   if (!mswitches)
    9742              :     {
    9743       311715 :       struct mswitchstr *matches;
    9744       311715 :       const char *q;
    9745       311715 :       int cnt = 0;
    9746              : 
    9747              :       /* Break multilib_matches into the component strings of string
    9748              :          and replacement string.  */
    9749      5299155 :       for (q = multilib_matches; *q != '\0'; q++)
    9750      4987440 :         if (*q == ';')
    9751       623430 :           cnt++;
    9752              : 
    9753       311715 :       matches
    9754       311715 :         = (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
    9755       311715 :       i = 0;
    9756       311715 :       q = multilib_matches;
    9757       935145 :       while (*q != '\0')
    9758              :         {
    9759       623430 :           matches[i].str = q;
    9760      2493720 :           while (*q != ' ')
    9761              :             {
    9762      1870290 :               if (*q == '\0')
    9763              :                 {
    9764            0 :                 invalid_matches:
    9765            0 :                   fatal_error (input_location, "multilib spec %qs is invalid",
    9766              :                                multilib_matches);
    9767              :                 }
    9768      1870290 :               q++;
    9769              :             }
    9770       623430 :           matches[i].len = q - matches[i].str;
    9771              : 
    9772       623430 :           matches[i].replace = ++q;
    9773      2493720 :           while (*q != ';' && *q != '\0')
    9774              :             {
    9775      1870290 :               if (*q == ' ')
    9776            0 :                 goto invalid_matches;
    9777      1870290 :               q++;
    9778              :             }
    9779       623430 :           matches[i].rep_len = q - matches[i].replace;
    9780       623430 :           i++;
    9781       623430 :           if (*q == ';')
    9782       623430 :             q++;
    9783              :         }
    9784              : 
    9785              :       /* Now build a list of the replacement string for switches that we care
    9786              :          about.  Make sure we allocate at least one entry.  This prevents
    9787              :          xmalloc from calling fatal, and prevents us from re-executing this
    9788              :          block of code.  */
    9789       311715 :       mswitches
    9790       623430 :         = XNEWVEC (struct mswitchstr, n_mdswitches + (n_switches ? n_switches : 1));
    9791      7291964 :       for (i = 0; i < n_switches; i++)
    9792      6980249 :         if ((switches[i].live_cond & SWITCH_IGNORE) == 0)
    9793              :           {
    9794      6980243 :             int xlen = strlen (switches[i].part1);
    9795     20927896 :             for (j = 0; j < cnt; j++)
    9796     13958041 :               if (xlen == matches[j].len
    9797        19195 :                   && ! strncmp (switches[i].part1, matches[j].str, xlen))
    9798              :                 {
    9799        10388 :                   mswitches[n_mswitches].str = matches[j].replace;
    9800        10388 :                   mswitches[n_mswitches].len = matches[j].rep_len;
    9801        10388 :                   mswitches[n_mswitches].replace = (char *) 0;
    9802        10388 :                   mswitches[n_mswitches].rep_len = 0;
    9803        10388 :                   n_mswitches++;
    9804        10388 :                   break;
    9805              :                 }
    9806              :           }
    9807              : 
    9808              :       /* Add MULTILIB_DEFAULTS switches too, as long as they were not present
    9809              :          on the command line nor any options mutually incompatible with
    9810              :          them.  */
    9811       623430 :       for (i = 0; i < n_mdswitches; i++)
    9812              :         {
    9813       311715 :           const char *r;
    9814              : 
    9815       623430 :           for (q = multilib_options; *q != '\0'; *q && q++)
    9816              :             {
    9817       311715 :               while (*q == ' ')
    9818            0 :                 q++;
    9819              : 
    9820       311715 :               r = q;
    9821       311715 :               while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
    9822       311715 :                      || strchr (" /", q[mdswitches[i].len]) == NULL)
    9823              :                 {
    9824            0 :                   while (*q != ' ' && *q != '/' && *q != '\0')
    9825            0 :                     q++;
    9826            0 :                   if (*q != '/')
    9827              :                     break;
    9828            0 :                   q++;
    9829              :                 }
    9830              : 
    9831       311715 :               if (*q != ' ' && *q != '\0')
    9832              :                 {
    9833       620985 :                   while (*r != ' ' && *r != '\0')
    9834              :                     {
    9835              :                       q = r;
    9836      2483940 :                       while (*q != ' ' && *q != '/' && *q != '\0')
    9837      1862955 :                         q++;
    9838              : 
    9839       620985 :                       if (used_arg (r, q - r))
    9840              :                         break;
    9841              : 
    9842       610597 :                       if (*q != '/')
    9843              :                         {
    9844       301327 :                           mswitches[n_mswitches].str = mdswitches[i].str;
    9845       301327 :                           mswitches[n_mswitches].len = mdswitches[i].len;
    9846       301327 :                           mswitches[n_mswitches].replace = (char *) 0;
    9847       301327 :                           mswitches[n_mswitches].rep_len = 0;
    9848       301327 :                           n_mswitches++;
    9849       301327 :                           break;
    9850              :                         }
    9851              : 
    9852       309270 :                       r = q + 1;
    9853              :                     }
    9854              :                   break;
    9855              :                 }
    9856              :             }
    9857              :         }
    9858              :     }
    9859              : 
    9860      2523047 :   for (i = 0; i < n_mswitches; i++)
    9861      1281077 :     if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
    9862              :       return 1;
    9863              : 
    9864              :   return 0;
    9865              : }
    9866              : 
    9867         1144 : void used_arg_t::finalize ()
    9868              : {
    9869         1144 :   XDELETEVEC (mswitches);
    9870         1144 :   mswitches = NULL;
    9871         1144 :   n_mswitches = 0;
    9872         1144 : }
    9873              : 
    9874              : 
    9875              : static int
    9876      1285054 : default_arg (const char *p, int len)
    9877              : {
    9878      1285054 :   int i;
    9879              : 
    9880      1922004 :   for (i = 0; i < n_mdswitches; i++)
    9881      1285054 :     if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
    9882              :       return 1;
    9883              : 
    9884              :   return 0;
    9885              : }
    9886              : 
    9887              : /* Use multilib_dir as key to find corresponding multilib_os_dir and
    9888              :    multiarch_dir.  */
    9889              : 
    9890              : static void
    9891            0 : find_multilib_os_dir_by_multilib_dir (const char *multilib_dir,
    9892              :                                       const char **p_multilib_os_dir,
    9893              :                                       const char **p_multiarch_dir)
    9894              : {
    9895            0 :   const char *p = multilib_select;
    9896            0 :   unsigned int this_path_len;
    9897            0 :   const char *this_path;
    9898            0 :   int ok = 0;
    9899              : 
    9900            0 :   while (*p != '\0')
    9901              :     {
    9902              :       /* Ignore newlines.  */
    9903            0 :       if (*p == '\n')
    9904              :         {
    9905            0 :           ++p;
    9906            0 :           continue;
    9907              :         }
    9908              : 
    9909              :       /* Get the initial path.  */
    9910              :       this_path = p;
    9911            0 :       while (*p != ' ')
    9912              :         {
    9913            0 :           if (*p == '\0')
    9914              :             {
    9915            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
    9916              :                            multilib_select, multilib_reuse);
    9917              :             }
    9918            0 :           ++p;
    9919              :         }
    9920            0 :       this_path_len = p - this_path;
    9921              : 
    9922            0 :       ok = 0;
    9923              : 
    9924              :       /* Skip any arguments, we don't care at this stage.  */
    9925            0 :       while (*++p != ';');
    9926              : 
    9927            0 :       if (this_path_len != 1
    9928            0 :           || this_path[0] != '.')
    9929              :         {
    9930            0 :           char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
    9931            0 :           char *q;
    9932              : 
    9933            0 :           strncpy (new_multilib_dir, this_path, this_path_len);
    9934            0 :           new_multilib_dir[this_path_len] = '\0';
    9935            0 :           q = strchr (new_multilib_dir, ':');
    9936            0 :           if (q != NULL)
    9937            0 :             *q = '\0';
    9938              : 
    9939            0 :           if (strcmp (new_multilib_dir, multilib_dir) == 0)
    9940            0 :             ok = 1;
    9941              :         }
    9942              : 
    9943              :       /* Found matched multilib_dir, update multilib_os_dir and
    9944              :          multiarch_dir.  */
    9945            0 :       if (ok)
    9946              :         {
    9947            0 :           const char *q = this_path, *end = this_path + this_path_len;
    9948              : 
    9949            0 :           while (q < end && *q != ':')
    9950            0 :             q++;
    9951            0 :           if (q < end)
    9952              :             {
    9953            0 :               const char *q2 = q + 1, *ml_end = end;
    9954            0 :               char *new_multilib_os_dir;
    9955              : 
    9956            0 :               while (q2 < end && *q2 != ':')
    9957            0 :                 q2++;
    9958            0 :               if (*q2 == ':')
    9959            0 :                 ml_end = q2;
    9960            0 :               if (ml_end - q == 1)
    9961            0 :                 *p_multilib_os_dir = xstrdup (".");
    9962              :               else
    9963              :                 {
    9964            0 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
    9965            0 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
    9966            0 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
    9967            0 :                   *p_multilib_os_dir = new_multilib_os_dir;
    9968              :                 }
    9969              : 
    9970            0 :               if (q2 < end && *q2 == ':')
    9971              :                 {
    9972            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
    9973            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
    9974            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
    9975            0 :                   *p_multiarch_dir = new_multiarch_dir;
    9976              :                 }
    9977              :               break;
    9978              :             }
    9979              :         }
    9980            0 :       ++p;
    9981              :     }
    9982            0 : }
    9983              : 
    9984              : /* Work out the subdirectory to use based on the options. The format of
    9985              :    multilib_select is a list of elements. Each element is a subdirectory
    9986              :    name followed by a list of options followed by a semicolon. The format
    9987              :    of multilib_exclusions is the same, but without the preceding
    9988              :    directory. First gcc will check the exclusions, if none of the options
    9989              :    beginning with an exclamation point are present, and all of the other
    9990              :    options are present, then we will ignore this completely. Passing
    9991              :    that, gcc will consider each multilib_select in turn using the same
    9992              :    rules for matching the options. If a match is found, that subdirectory
    9993              :    will be used.
    9994              :    A subdirectory name is optionally followed by a colon and the corresponding
    9995              :    multiarch name.  */
    9996              : 
    9997              : static void
    9998       311715 : set_multilib_dir (void)
    9999              : {
   10000       311715 :   const char *p;
   10001       311715 :   unsigned int this_path_len;
   10002       311715 :   const char *this_path, *this_arg;
   10003       311715 :   const char *start, *end;
   10004       311715 :   int not_arg;
   10005       311715 :   int ok, ndfltok, first;
   10006              : 
   10007       311715 :   n_mdswitches = 0;
   10008       311715 :   start = multilib_defaults;
   10009       311715 :   while (*start == ' ' || *start == '\t')
   10010            0 :     start++;
   10011       623430 :   while (*start != '\0')
   10012              :     {
   10013       311715 :       n_mdswitches++;
   10014      1246860 :       while (*start != ' ' && *start != '\t' && *start != '\0')
   10015       935145 :         start++;
   10016       311715 :       while (*start == ' ' || *start == '\t')
   10017            0 :         start++;
   10018              :     }
   10019              : 
   10020       311715 :   if (n_mdswitches)
   10021              :     {
   10022       311715 :       int i = 0;
   10023              : 
   10024       311715 :       mdswitches = XNEWVEC (struct mdswitchstr, n_mdswitches);
   10025       311715 :       for (start = multilib_defaults; *start != '\0'; start = end + 1)
   10026              :         {
   10027       311715 :           while (*start == ' ' || *start == '\t')
   10028            0 :             start++;
   10029              : 
   10030       311715 :           if (*start == '\0')
   10031              :             break;
   10032              : 
   10033       935145 :           for (end = start + 1;
   10034       935145 :                *end != ' ' && *end != '\t' && *end != '\0'; end++)
   10035              :             ;
   10036              : 
   10037       311715 :           obstack_grow (&multilib_obstack, start, end - start);
   10038       311715 :           obstack_1grow (&multilib_obstack, 0);
   10039       311715 :           mdswitches[i].str = XOBFINISH (&multilib_obstack, const char *);
   10040       311715 :           mdswitches[i++].len = end - start;
   10041              : 
   10042       311715 :           if (*end == '\0')
   10043              :             break;
   10044              :         }
   10045              :     }
   10046              : 
   10047       311715 :   p = multilib_exclusions;
   10048       311715 :   while (*p != '\0')
   10049              :     {
   10050              :       /* Ignore newlines.  */
   10051            0 :       if (*p == '\n')
   10052              :         {
   10053            0 :           ++p;
   10054            0 :           continue;
   10055              :         }
   10056              : 
   10057              :       /* Check the arguments.  */
   10058              :       ok = 1;
   10059            0 :       while (*p != ';')
   10060              :         {
   10061            0 :           if (*p == '\0')
   10062              :             {
   10063            0 :             invalid_exclusions:
   10064            0 :               fatal_error (input_location, "multilib exclusions %qs is invalid",
   10065              :                            multilib_exclusions);
   10066              :             }
   10067              : 
   10068            0 :           if (! ok)
   10069              :             {
   10070            0 :               ++p;
   10071            0 :               continue;
   10072              :             }
   10073              : 
   10074            0 :           this_arg = p;
   10075            0 :           while (*p != ' ' && *p != ';')
   10076              :             {
   10077            0 :               if (*p == '\0')
   10078            0 :                 goto invalid_exclusions;
   10079            0 :               ++p;
   10080              :             }
   10081              : 
   10082            0 :           if (*this_arg != '!')
   10083              :             not_arg = 0;
   10084              :           else
   10085              :             {
   10086            0 :               not_arg = 1;
   10087            0 :               ++this_arg;
   10088              :             }
   10089              : 
   10090            0 :           ok = used_arg (this_arg, p - this_arg);
   10091            0 :           if (not_arg)
   10092            0 :             ok = ! ok;
   10093              : 
   10094            0 :           if (*p == ' ')
   10095            0 :             ++p;
   10096              :         }
   10097              : 
   10098            0 :       if (ok)
   10099              :         return;
   10100              : 
   10101            0 :       ++p;
   10102              :     }
   10103              : 
   10104       311715 :   first = 1;
   10105       311715 :   p = multilib_select;
   10106              : 
   10107              :   /* Append multilib reuse rules if any.  With those rules, we can reuse
   10108              :      one multilib for certain different options sets.  */
   10109       311715 :   if (strlen (multilib_reuse) > 0)
   10110            0 :     p = concat (p, multilib_reuse, NULL);
   10111              : 
   10112       631373 :   while (*p != '\0')
   10113              :     {
   10114              :       /* Ignore newlines.  */
   10115       631373 :       if (*p == '\n')
   10116              :         {
   10117            0 :           ++p;
   10118            0 :           continue;
   10119              :         }
   10120              : 
   10121              :       /* Get the initial path.  */
   10122              :       this_path = p;
   10123      4443440 :       while (*p != ' ')
   10124              :         {
   10125      3812067 :           if (*p == '\0')
   10126              :             {
   10127            0 :             invalid_select:
   10128            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
   10129              :                            multilib_select, multilib_reuse);
   10130              :             }
   10131      3812067 :           ++p;
   10132              :         }
   10133       631373 :       this_path_len = p - this_path;
   10134              : 
   10135              :       /* Check the arguments.  */
   10136       631373 :       ok = 1;
   10137       631373 :       ndfltok = 1;
   10138       631373 :       ++p;
   10139      1894119 :       while (*p != ';')
   10140              :         {
   10141      1262746 :           if (*p == '\0')
   10142            0 :             goto invalid_select;
   10143              : 
   10144      1262746 :           if (! ok)
   10145              :             {
   10146            0 :               ++p;
   10147            0 :               continue;
   10148              :             }
   10149              : 
   10150      5994072 :           this_arg = p;
   10151      5994072 :           while (*p != ' ' && *p != ';')
   10152              :             {
   10153      4731326 :               if (*p == '\0')
   10154            0 :                 goto invalid_select;
   10155      4731326 :               ++p;
   10156              :             }
   10157              : 
   10158      1262746 :           if (*this_arg != '!')
   10159              :             not_arg = 0;
   10160              :           else
   10161              :             {
   10162       943088 :               not_arg = 1;
   10163       943088 :               ++this_arg;
   10164              :             }
   10165              : 
   10166              :           /* If this is a default argument, we can just ignore it.
   10167              :              This is true even if this_arg begins with '!'.  Beginning
   10168              :              with '!' does not mean that this argument is necessarily
   10169              :              inappropriate for this library: it merely means that
   10170              :              there is a more specific library which uses this
   10171              :              argument.  If this argument is a default, we need not
   10172              :              consider that more specific library.  */
   10173      1262746 :           ok = used_arg (this_arg, p - this_arg);
   10174      1262746 :           if (not_arg)
   10175       943088 :             ok = ! ok;
   10176              : 
   10177      1262746 :           if (! ok)
   10178       327601 :             ndfltok = 0;
   10179              : 
   10180      1262746 :           if (default_arg (this_arg, p - this_arg))
   10181       631373 :             ok = 1;
   10182              : 
   10183      1262746 :           if (*p == ' ')
   10184       631373 :             ++p;
   10185              :         }
   10186              : 
   10187       631373 :       if (ok && first)
   10188              :         {
   10189       311715 :           if (this_path_len != 1
   10190       303772 :               || this_path[0] != '.')
   10191              :             {
   10192         7943 :               char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
   10193         7943 :               char *q;
   10194              : 
   10195         7943 :               strncpy (new_multilib_dir, this_path, this_path_len);
   10196         7943 :               new_multilib_dir[this_path_len] = '\0';
   10197         7943 :               q = strchr (new_multilib_dir, ':');
   10198         7943 :               if (q != NULL)
   10199         7943 :                 *q = '\0';
   10200         7943 :               multilib_dir = new_multilib_dir;
   10201              :             }
   10202              :           first = 0;
   10203              :         }
   10204              : 
   10205       631373 :       if (ndfltok)
   10206              :         {
   10207       311715 :           const char *q = this_path, *end = this_path + this_path_len;
   10208              : 
   10209       935145 :           while (q < end && *q != ':')
   10210       623430 :             q++;
   10211       311715 :           if (q < end)
   10212              :             {
   10213       311715 :               const char *q2 = q + 1, *ml_end = end;
   10214       311715 :               char *new_multilib_os_dir;
   10215              : 
   10216      2789549 :               while (q2 < end && *q2 != ':')
   10217      2477834 :                 q2++;
   10218       311715 :               if (*q2 == ':')
   10219            0 :                 ml_end = q2;
   10220       311715 :               if (ml_end - q == 1)
   10221            0 :                 multilib_os_dir = xstrdup (".");
   10222              :               else
   10223              :                 {
   10224       311715 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
   10225       311715 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
   10226       311715 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
   10227       311715 :                   multilib_os_dir = new_multilib_os_dir;
   10228              :                 }
   10229              : 
   10230       311715 :               if (q2 < end && *q2 == ':')
   10231              :                 {
   10232            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
   10233            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
   10234            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
   10235            0 :                   multiarch_dir = new_multiarch_dir;
   10236              :                 }
   10237              :               break;
   10238              :             }
   10239              :         }
   10240              : 
   10241       319658 :       ++p;
   10242              :     }
   10243              : 
   10244       623430 :   multilib_dir =
   10245       311715 :     targetm_common.compute_multilib (
   10246              :       switches,
   10247              :       n_switches,
   10248              :       multilib_dir,
   10249              :       multilib_defaults,
   10250              :       multilib_select,
   10251              :       multilib_matches,
   10252              :       multilib_exclusions,
   10253              :       multilib_reuse);
   10254              : 
   10255       311715 :   if (multilib_dir == NULL && multilib_os_dir != NULL
   10256       303772 :       && strcmp (multilib_os_dir, ".") == 0)
   10257              :     {
   10258            0 :       free (const_cast<char *> (multilib_os_dir));
   10259            0 :       multilib_os_dir = NULL;
   10260              :     }
   10261       311715 :   else if (multilib_dir != NULL && multilib_os_dir == NULL)
   10262              :     {
   10263              :       /* Give second chance to search matched multilib_os_dir again by matching
   10264              :          the multilib_dir since some target may use TARGET_COMPUTE_MULTILIB
   10265              :          hook rather than the builtin way.  */
   10266            0 :       find_multilib_os_dir_by_multilib_dir (multilib_dir, &multilib_os_dir,
   10267              :                                             &multiarch_dir);
   10268              : 
   10269            0 :       if (multilib_os_dir == NULL)
   10270            0 :         multilib_os_dir = multilib_dir;
   10271              :     }
   10272              : }
   10273              : 
   10274              : /* Print out the multiple library subdirectory selection
   10275              :    information.  This prints out a series of lines.  Each line looks
   10276              :    like SUBDIRECTORY;@OPTION@OPTION, with as many options as is
   10277              :    required.  Only the desired options are printed out, the negative
   10278              :    matches.  The options are print without a leading dash.  There are
   10279              :    no spaces to make it easy to use the information in the shell.
   10280              :    Each subdirectory is printed only once.  This assumes the ordering
   10281              :    generated by the genmultilib script. Also, we leave out ones that match
   10282              :    the exclusions.  */
   10283              : 
   10284              : static void
   10285         5577 : print_multilib_info (void)
   10286              : {
   10287         5577 :   const char *p = multilib_select;
   10288         5577 :   const char *last_path = 0, *this_path;
   10289         5577 :   int skip;
   10290         5577 :   int not_arg;
   10291         5577 :   unsigned int last_path_len = 0;
   10292              : 
   10293        22308 :   while (*p != '\0')
   10294              :     {
   10295        16731 :       skip = 0;
   10296              :       /* Ignore newlines.  */
   10297        16731 :       if (*p == '\n')
   10298              :         {
   10299            0 :           ++p;
   10300            0 :           continue;
   10301              :         }
   10302              : 
   10303              :       /* Get the initial path.  */
   10304              :       this_path = p;
   10305       133848 :       while (*p != ' ')
   10306              :         {
   10307       117117 :           if (*p == '\0')
   10308              :             {
   10309            0 :             invalid_select:
   10310            0 :               fatal_error (input_location,
   10311              :                            "multilib select %qs is invalid", multilib_select);
   10312              :             }
   10313              : 
   10314       117117 :           ++p;
   10315              :         }
   10316              : 
   10317              :       /* When --disable-multilib was used but target defines
   10318              :          MULTILIB_OSDIRNAMES, entries starting with .: (and not starting
   10319              :          with .:: for multiarch configurations) are there just to find
   10320              :          multilib_os_dir, so skip them from output.  */
   10321        16731 :       if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
   10322        16731 :         skip = 1;
   10323              : 
   10324              :       /* Check for matches with the multilib_exclusions. We don't bother
   10325              :          with the '!' in either list. If any of the exclusion rules match
   10326              :          all of its options with the select rule, we skip it.  */
   10327        16731 :       {
   10328        16731 :         const char *e = multilib_exclusions;
   10329        16731 :         const char *this_arg;
   10330              : 
   10331        16731 :         while (*e != '\0')
   10332              :           {
   10333            0 :             int m = 1;
   10334              :             /* Ignore newlines.  */
   10335            0 :             if (*e == '\n')
   10336              :               {
   10337            0 :                 ++e;
   10338            0 :                 continue;
   10339              :               }
   10340              : 
   10341              :             /* Check the arguments.  */
   10342            0 :             while (*e != ';')
   10343              :               {
   10344            0 :                 const char *q;
   10345            0 :                 int mp = 0;
   10346              : 
   10347            0 :                 if (*e == '\0')
   10348              :                   {
   10349            0 :                   invalid_exclusion:
   10350            0 :                     fatal_error (input_location,
   10351              :                                  "multilib exclusion %qs is invalid",
   10352              :                                  multilib_exclusions);
   10353              :                   }
   10354              : 
   10355            0 :                 if (! m)
   10356              :                   {
   10357            0 :                     ++e;
   10358            0 :                     continue;
   10359              :                   }
   10360              : 
   10361              :                 this_arg = e;
   10362              : 
   10363            0 :                 while (*e != ' ' && *e != ';')
   10364              :                   {
   10365            0 :                     if (*e == '\0')
   10366            0 :                       goto invalid_exclusion;
   10367            0 :                     ++e;
   10368              :                   }
   10369              : 
   10370            0 :                 q = p + 1;
   10371            0 :                 while (*q != ';')
   10372              :                   {
   10373            0 :                     const char *arg;
   10374            0 :                     int len = e - this_arg;
   10375              : 
   10376            0 :                     if (*q == '\0')
   10377            0 :                       goto invalid_select;
   10378              : 
   10379              :                     arg = q;
   10380              : 
   10381            0 :                     while (*q != ' ' && *q != ';')
   10382              :                       {
   10383            0 :                         if (*q == '\0')
   10384            0 :                           goto invalid_select;
   10385            0 :                         ++q;
   10386              :                       }
   10387              : 
   10388            0 :                     if (! strncmp (arg, this_arg,
   10389            0 :                                    (len < q - arg) ? q - arg : len)
   10390            0 :                         || default_arg (this_arg, e - this_arg))
   10391              :                       {
   10392              :                         mp = 1;
   10393              :                         break;
   10394              :                       }
   10395              : 
   10396            0 :                     if (*q == ' ')
   10397            0 :                       ++q;
   10398              :                   }
   10399              : 
   10400            0 :                 if (! mp)
   10401            0 :                   m = 0;
   10402              : 
   10403            0 :                 if (*e == ' ')
   10404            0 :                   ++e;
   10405              :               }
   10406              : 
   10407            0 :             if (m)
   10408              :               {
   10409              :                 skip = 1;
   10410              :                 break;
   10411              :               }
   10412              : 
   10413            0 :             if (*e != '\0')
   10414            0 :               ++e;
   10415              :           }
   10416              :       }
   10417              : 
   10418        16731 :       if (! skip)
   10419              :         {
   10420              :           /* If this is a duplicate, skip it.  */
   10421        33462 :           skip = (last_path != 0
   10422        11154 :                   && (unsigned int) (p - this_path) == last_path_len
   10423        16731 :                   && ! filename_ncmp (last_path, this_path, last_path_len));
   10424              : 
   10425        16731 :           last_path = this_path;
   10426        16731 :           last_path_len = p - this_path;
   10427              :         }
   10428              : 
   10429              :       /* If all required arguments are default arguments, and no default
   10430              :          arguments appear in the ! argument list, then we can skip it.
   10431              :          We will already have printed a directory identical to this one
   10432              :          which does not require that default argument.  */
   10433        16731 :       if (! skip)
   10434              :         {
   10435        16731 :           const char *q;
   10436        16731 :           bool default_arg_ok = false;
   10437              : 
   10438        16731 :           q = p + 1;
   10439        27885 :           while (*q != ';')
   10440              :             {
   10441        22308 :               const char *arg;
   10442              : 
   10443        22308 :               if (*q == '\0')
   10444            0 :                 goto invalid_select;
   10445              : 
   10446        22308 :               if (*q == '!')
   10447              :                 {
   10448        16731 :                   not_arg = 1;
   10449        16731 :                   q++;
   10450              :                 }
   10451              :               else
   10452              :                 not_arg = 0;
   10453        22308 :               arg = q;
   10454              : 
   10455        89232 :               while (*q != ' ' && *q != ';')
   10456              :                 {
   10457        66924 :                   if (*q == '\0')
   10458            0 :                     goto invalid_select;
   10459        66924 :                   ++q;
   10460              :                 }
   10461              : 
   10462        22308 :               if (default_arg (arg, q - arg))
   10463              :                 {
   10464              :                   /* Stop checking if any default arguments appeared in not
   10465              :                      list.  */
   10466        16731 :                   if (not_arg)
   10467              :                     {
   10468              :                       default_arg_ok = false;
   10469              :                       break;
   10470              :                     }
   10471              : 
   10472              :                   default_arg_ok = true;
   10473              :                 }
   10474         5577 :               else if (!not_arg)
   10475              :                 {
   10476              :                   /* Stop checking if any required argument is not provided by
   10477              :                      default arguments.  */
   10478              :                   default_arg_ok = false;
   10479              :                   break;
   10480              :                 }
   10481              : 
   10482        11154 :               if (*q == ' ')
   10483         5577 :                 ++q;
   10484              :             }
   10485              : 
   10486              :           /* Make sure all default argument is OK for this multi-lib set.  */
   10487        16731 :           if (default_arg_ok)
   10488              :             skip = 1;
   10489              :           else
   10490              :             skip = 0;
   10491              :         }
   10492              : 
   10493              :       if (! skip)
   10494              :         {
   10495              :           const char *p1;
   10496              : 
   10497        27885 :           for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
   10498        16731 :             putchar (*p1);
   10499        11154 :           putchar (';');
   10500              :         }
   10501              : 
   10502        16731 :       ++p;
   10503        83655 :       while (*p != ';')
   10504              :         {
   10505        66924 :           int use_arg;
   10506              : 
   10507        66924 :           if (*p == '\0')
   10508            0 :             goto invalid_select;
   10509              : 
   10510        66924 :           if (skip)
   10511              :             {
   10512        44616 :               ++p;
   10513        44616 :               continue;
   10514              :             }
   10515              : 
   10516        22308 :           use_arg = *p != '!';
   10517              : 
   10518        22308 :           if (use_arg)
   10519         5577 :             putchar ('@');
   10520              : 
   10521       105963 :           while (*p != ' ' && *p != ';')
   10522              :             {
   10523        83655 :               if (*p == '\0')
   10524            0 :                 goto invalid_select;
   10525        83655 :               if (use_arg)
   10526        16731 :                 putchar (*p);
   10527        83655 :               ++p;
   10528              :             }
   10529              : 
   10530        22308 :           if (*p == ' ')
   10531        11154 :             ++p;
   10532              :         }
   10533              : 
   10534        16731 :       if (! skip)
   10535              :         {
   10536              :           /* If there are extra options, print them now.  */
   10537        11154 :           if (multilib_extra && *multilib_extra)
   10538              :             {
   10539              :               int print_at = true;
   10540              :               const char *q;
   10541              : 
   10542            0 :               for (q = multilib_extra; *q != '\0'; q++)
   10543              :                 {
   10544            0 :                   if (*q == ' ')
   10545              :                     print_at = true;
   10546              :                   else
   10547              :                     {
   10548            0 :                       if (print_at)
   10549            0 :                         putchar ('@');
   10550            0 :                       putchar (*q);
   10551            0 :                       print_at = false;
   10552              :                     }
   10553              :                 }
   10554              :             }
   10555              : 
   10556        11154 :           putchar ('\n');
   10557              :         }
   10558              : 
   10559        16731 :       ++p;
   10560              :     }
   10561         5577 : }
   10562              : 
   10563              : /* getenv built-in spec function.
   10564              : 
   10565              :    Returns the value of the environment variable given by its first argument,
   10566              :    concatenated with the second argument.  If the variable is not defined, a
   10567              :    fatal error is issued unless such undefs are internally allowed, in which
   10568              :    case the variable name prefixed by a '/' is used as the variable value.
   10569              : 
   10570              :    The leading '/' allows using the result at a spot where a full path would
   10571              :    normally be expected and when the actual value doesn't really matter since
   10572              :    undef vars are allowed.  */
   10573              : 
   10574              : static const char *
   10575            0 : getenv_spec_function (int argc, const char **argv)
   10576              : {
   10577            0 :   const char *value;
   10578            0 :   const char *varname;
   10579              : 
   10580            0 :   char *result;
   10581            0 :   char *ptr;
   10582            0 :   size_t len;
   10583              : 
   10584            0 :   if (argc != 2)
   10585              :     return NULL;
   10586              : 
   10587            0 :   varname = argv[0];
   10588            0 :   value = env.get (varname);
   10589              : 
   10590              :   /* If the variable isn't defined and this is allowed, craft our expected
   10591              :      return value.  Assume variable names used in specs strings don't contain
   10592              :      any active spec character so don't need escaping.  */
   10593            0 :   if (!value && spec_undefvar_allowed)
   10594              :     {
   10595            0 :       result = XNEWVAR (char, strlen(varname) + 2);
   10596            0 :       sprintf (result, "/%s", varname);
   10597            0 :       return result;
   10598              :     }
   10599              : 
   10600            0 :   if (!value)
   10601            0 :     fatal_error (input_location,
   10602              :                  "environment variable %qs not defined", varname);
   10603              : 
   10604              :   /* We have to escape every character of the environment variable so
   10605              :      they are not interpreted as active spec characters.  A
   10606              :      particularly painful case is when we are reading a variable
   10607              :      holding a windows path complete with \ separators.  */
   10608            0 :   len = strlen (value) * 2 + strlen (argv[1]) + 1;
   10609            0 :   result = XNEWVAR (char, len);
   10610            0 :   for (ptr = result; *value; ptr += 2)
   10611              :     {
   10612            0 :       ptr[0] = '\\';
   10613            0 :       ptr[1] = *value++;
   10614              :     }
   10615              : 
   10616            0 :   strcpy (ptr, argv[1]);
   10617              : 
   10618            0 :   return result;
   10619              : }
   10620              : 
   10621              : /* if-exists built-in spec function.
   10622              : 
   10623              :    Checks to see if the file specified by the absolute pathname in
   10624              :    ARGS exists.  Returns that pathname if found.
   10625              : 
   10626              :    The usual use for this function is to check for a library file
   10627              :    (whose name has been expanded with %s).  */
   10628              : 
   10629              : static const char *
   10630            0 : if_exists_spec_function (int argc, const char **argv)
   10631              : {
   10632              :   /* Must have only one argument.  */
   10633            0 :   if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10634            0 :     return argv[0];
   10635              : 
   10636              :   return NULL;
   10637              : }
   10638              : 
   10639              : /* if-exists-else built-in spec function.
   10640              : 
   10641              :    This is like if-exists, but takes an additional argument which
   10642              :    is returned if the first argument does not exist.  */
   10643              : 
   10644              : static const char *
   10645            0 : if_exists_else_spec_function (int argc, const char **argv)
   10646              : {
   10647              :   /* Must have exactly two arguments.  */
   10648            0 :   if (argc != 2)
   10649              :     return NULL;
   10650              : 
   10651            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10652            0 :     return argv[0];
   10653              : 
   10654            0 :   return argv[1];
   10655              : }
   10656              : 
   10657              : /* if-exists-then-else built-in spec function.
   10658              : 
   10659              :    Checks to see if the file specified by the absolute pathname in
   10660              :    the first arg exists.  Returns the second arg if so, otherwise returns
   10661              :    the third arg if it is present.  */
   10662              : 
   10663              : static const char *
   10664            0 : if_exists_then_else_spec_function (int argc, const char **argv)
   10665              : {
   10666              : 
   10667              :   /* Must have two or three arguments.  */
   10668            0 :   if (argc != 2 && argc != 3)
   10669              :     return NULL;
   10670              : 
   10671            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10672            0 :     return argv[1];
   10673              : 
   10674            0 :   if (argc == 3)
   10675            0 :     return argv[2];
   10676              : 
   10677              :   return NULL;
   10678              : }
   10679              : 
   10680              : /* sanitize built-in spec function.
   10681              : 
   10682              :    This returns non-NULL, if sanitizing address, thread or
   10683              :    any of the undefined behavior sanitizers.  */
   10684              : 
   10685              : static const char *
   10686       881442 : sanitize_spec_function (int argc, const char **argv)
   10687              : {
   10688       881442 :   if (argc != 1)
   10689              :     return NULL;
   10690              : 
   10691       881442 :   if (strcmp (argv[0], "address") == 0)
   10692       388936 :     return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL;
   10693       685566 :   if (strcmp (argv[0], "hwaddress") == 0)
   10694       391372 :     return (flag_sanitize & SANITIZE_USER_HWADDRESS) ? "" : NULL;
   10695       489690 :   if (strcmp (argv[0], "kernel-address") == 0)
   10696            0 :     return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL;
   10697       489690 :   if (strcmp (argv[0], "kernel-hwaddress") == 0)
   10698            0 :     return (flag_sanitize & SANITIZE_KERNEL_HWADDRESS) ? "" : NULL;
   10699       489690 :   if (strcmp (argv[0], "memtag-stack") == 0)
   10700            0 :     return (flag_sanitize & SANITIZE_MEMTAG_STACK) ? "" : NULL;
   10701       489690 :   if (strcmp (argv[0], "thread") == 0)
   10702       391168 :     return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
   10703       293814 :   if (strcmp (argv[0], "undefined") == 0)
   10704        97938 :     return ((flag_sanitize
   10705        97938 :              & ~flag_sanitize_trap
   10706        97938 :              & (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)))
   10707       193922 :            ? "" : NULL;
   10708       195876 :   if (strcmp (argv[0], "leak") == 0)
   10709       195876 :     return ((flag_sanitize
   10710       195876 :              & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
   10711       391752 :             == SANITIZE_LEAK) ? "" : NULL;
   10712              :   return NULL;
   10713              : }
   10714              : 
   10715              : /* replace-outfile built-in spec function.
   10716              : 
   10717              :    This looks for the first argument in the outfiles array's name and
   10718              :    replaces it with the second argument.  */
   10719              : 
   10720              : static const char *
   10721            0 : replace_outfile_spec_function (int argc, const char **argv)
   10722              : {
   10723            0 :   int i;
   10724              :   /* Must have exactly two arguments.  */
   10725            0 :   if (argc != 2)
   10726            0 :     abort ();
   10727              : 
   10728            0 :   for (i = 0; i < n_infiles; i++)
   10729              :     {
   10730            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10731            0 :         outfiles[i] = xstrdup (argv[1]);
   10732              :     }
   10733            0 :   return NULL;
   10734              : }
   10735              : 
   10736              : /* remove-outfile built-in spec function.
   10737              :  *
   10738              :  *    This looks for the first argument in the outfiles array's name and
   10739              :  *       removes it.  */
   10740              : 
   10741              : static const char *
   10742            0 : remove_outfile_spec_function (int argc, const char **argv)
   10743              : {
   10744            0 :   int i;
   10745              :   /* Must have exactly one argument.  */
   10746            0 :   if (argc != 1)
   10747            0 :     abort ();
   10748              : 
   10749            0 :   for (i = 0; i < n_infiles; i++)
   10750              :     {
   10751            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10752            0 :         outfiles[i] = NULL;
   10753              :     }
   10754            0 :   return NULL;
   10755              : }
   10756              : 
   10757              : /* Given two version numbers, compares the two numbers.
   10758              :    A version number must match the regular expression
   10759              :    ([1-9][0-9]*|0)(\.([1-9][0-9]*|0))*
   10760              : */
   10761              : static int
   10762            0 : compare_version_strings (const char *v1, const char *v2)
   10763              : {
   10764            0 :   int rresult;
   10765            0 :   regex_t r;
   10766              : 
   10767            0 :   if (regcomp (&r, "^([1-9][0-9]*|0)(\\.([1-9][0-9]*|0))*$",
   10768              :                REG_EXTENDED | REG_NOSUB) != 0)
   10769            0 :     abort ();
   10770            0 :   rresult = regexec (&r, v1, 0, NULL, 0);
   10771            0 :   if (rresult == REG_NOMATCH)
   10772            0 :     fatal_error (input_location, "invalid version number %qs", v1);
   10773            0 :   else if (rresult != 0)
   10774            0 :     abort ();
   10775            0 :   rresult = regexec (&r, v2, 0, NULL, 0);
   10776            0 :   if (rresult == REG_NOMATCH)
   10777            0 :     fatal_error (input_location, "invalid version number %qs", v2);
   10778            0 :   else if (rresult != 0)
   10779            0 :     abort ();
   10780              : 
   10781            0 :   return strverscmp (v1, v2);
   10782              : }
   10783              : 
   10784              : 
   10785              : /* version_compare built-in spec function.
   10786              : 
   10787              :    This takes an argument of the following form:
   10788              : 
   10789              :    <comparison-op> <arg1> [<arg2>] <switch> <result>
   10790              : 
   10791              :    and produces "result" if the comparison evaluates to true,
   10792              :    and nothing if it doesn't.
   10793              : 
   10794              :    The supported <comparison-op> values are:
   10795              : 
   10796              :    >=  true if switch is a later (or same) version than arg1
   10797              :    !>  opposite of >=
   10798              :    <   true if switch is an earlier version than arg1
   10799              :    !<  opposite of <
   10800              :    ><  true if switch is arg1 or later, and earlier than arg2
   10801              :    <>  true if switch is earlier than arg1 or is arg2 or later
   10802              : 
   10803              :    If the switch is not present, the condition is false unless
   10804              :    the first character of the <comparison-op> is '!'.
   10805              : 
   10806              :    For example,
   10807              :    %:version-compare(>= 10.3 mmacosx-version-min= -lmx)
   10808              :    adds -lmx if -mmacosx-version-min=10.3.9 was passed.  */
   10809              : 
   10810              : static const char *
   10811            0 : version_compare_spec_function (int argc, const char **argv)
   10812              : {
   10813            0 :   int comp1, comp2;
   10814            0 :   size_t switch_len;
   10815            0 :   const char *switch_value = NULL;
   10816            0 :   int nargs = 1, i;
   10817            0 :   bool result;
   10818              : 
   10819            0 :   if (argc < 3)
   10820            0 :     fatal_error (input_location, "too few arguments to %%:version-compare");
   10821            0 :   if (argv[0][0] == '\0')
   10822            0 :     abort ();
   10823            0 :   if ((argv[0][1] == '<' || argv[0][1] == '>') && argv[0][0] != '!')
   10824            0 :     nargs = 2;
   10825            0 :   if (argc != nargs + 3)
   10826            0 :     fatal_error (input_location, "too many arguments to %%:version-compare");
   10827              : 
   10828            0 :   switch_len = strlen (argv[nargs + 1]);
   10829            0 :   for (i = 0; i < n_switches; i++)
   10830            0 :     if (!strncmp (switches[i].part1, argv[nargs + 1], switch_len)
   10831            0 :         && check_live_switch (i, switch_len))
   10832            0 :       switch_value = switches[i].part1 + switch_len;
   10833              : 
   10834            0 :   if (switch_value == NULL)
   10835              :     comp1 = comp2 = -1;
   10836              :   else
   10837              :     {
   10838            0 :       comp1 = compare_version_strings (switch_value, argv[1]);
   10839            0 :       if (nargs == 2)
   10840            0 :         comp2 = compare_version_strings (switch_value, argv[2]);
   10841              :       else
   10842              :         comp2 = -1;  /* This value unused.  */
   10843              :     }
   10844              : 
   10845            0 :   switch (argv[0][0] << 8 | argv[0][1])
   10846              :     {
   10847            0 :     case '>' << 8 | '=':
   10848            0 :       result = comp1 >= 0;
   10849            0 :       break;
   10850            0 :     case '!' << 8 | '<':
   10851            0 :       result = comp1 >= 0 || switch_value == NULL;
   10852            0 :       break;
   10853            0 :     case '<' << 8:
   10854            0 :       result = comp1 < 0;
   10855            0 :       break;
   10856            0 :     case '!' << 8 | '>':
   10857            0 :       result = comp1 < 0 || switch_value == NULL;
   10858            0 :       break;
   10859            0 :     case '>' << 8 | '<':
   10860            0 :       result = comp1 >= 0 && comp2 < 0;
   10861            0 :       break;
   10862            0 :     case '<' << 8 | '>':
   10863            0 :       result = comp1 < 0 || comp2 >= 0;
   10864            0 :       break;
   10865              : 
   10866            0 :     default:
   10867            0 :       fatal_error (input_location,
   10868              :                    "unknown operator %qs in %%:version-compare", argv[0]);
   10869              :     }
   10870            0 :   if (! result)
   10871              :     return NULL;
   10872              : 
   10873            0 :   return argv[nargs + 2];
   10874              : }
   10875              : 
   10876              : /* %:include builtin spec function.  This differs from %include in that it
   10877              :    can be nested inside a spec, and thus be conditionalized.  It takes
   10878              :    one argument, the filename, and looks for it in the startfile path.
   10879              :    The result is always NULL, i.e. an empty expansion.  */
   10880              : 
   10881              : static const char *
   10882        31571 : include_spec_function (int argc, const char **argv)
   10883              : {
   10884        31571 :   char *file;
   10885              : 
   10886        31571 :   if (argc != 1)
   10887            0 :     abort ();
   10888              : 
   10889        31571 :   file = find_a_file (&startfile_prefixes, argv[0], true);
   10890        31571 :   read_specs (file ? file : argv[0], false, false);
   10891              : 
   10892        31571 :   return NULL;
   10893              : }
   10894              : 
   10895              : /* %:find-file spec function.  This function replaces its argument by
   10896              :     the file found through find_file, that is the -print-file-name gcc
   10897              :     program option. */
   10898              : static const char *
   10899            0 : find_file_spec_function (int argc, const char **argv)
   10900              : {
   10901            0 :   const char *file;
   10902              : 
   10903            0 :   if (argc != 1)
   10904            0 :     abort ();
   10905              : 
   10906            0 :   file = find_file (argv[0]);
   10907            0 :   return file;
   10908              : }
   10909              : 
   10910              : 
   10911              : /* %:find-plugindir spec function.  This function replaces its argument
   10912              :     by the -iplugindir=<dir> option.  `dir' is found through find_file, that
   10913              :     is the -print-file-name gcc program option. */
   10914              : static const char *
   10915          428 : find_plugindir_spec_function (int argc, const char **argv ATTRIBUTE_UNUSED)
   10916              : {
   10917          428 :   const char *option;
   10918              : 
   10919          428 :   if (argc != 0)
   10920            0 :     abort ();
   10921              : 
   10922          428 :   option = concat ("-iplugindir=", find_file ("plugin"), NULL);
   10923          428 :   return option;
   10924              : }
   10925              : 
   10926              : 
   10927              : /* %:print-asm-header spec function.  Print a banner to say that the
   10928              :    following output is from the assembler.  */
   10929              : 
   10930              : static const char *
   10931            0 : print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
   10932              :                                 const char **argv ATTRIBUTE_UNUSED)
   10933              : {
   10934            0 :   printf (_("Assembler options\n=================\n\n"));
   10935            0 :   printf (_("Use \"-Wa,OPTION\" to pass \"OPTION\" to the assembler.\n\n"));
   10936            0 :   fflush (stdout);
   10937            0 :   return NULL;
   10938              : }
   10939              : 
   10940              : /* Get a random number for -frandom-seed */
   10941              : 
   10942              : static unsigned HOST_WIDE_INT
   10943          636 : get_random_number (void)
   10944              : {
   10945          636 :   unsigned HOST_WIDE_INT ret = 0;
   10946          636 :   int fd;
   10947              : 
   10948          636 :   fd = open ("/dev/urandom", O_RDONLY);
   10949          636 :   if (fd >= 0)
   10950              :     {
   10951          636 :       read (fd, &ret, sizeof (HOST_WIDE_INT));
   10952          636 :       close (fd);
   10953          636 :       if (ret)
   10954              :         return ret;
   10955              :     }
   10956              : 
   10957              :   /* Get some more or less random data.  */
   10958              : #ifdef HAVE_GETTIMEOFDAY
   10959            0 :   {
   10960            0 :     struct timeval tv;
   10961              : 
   10962            0 :     gettimeofday (&tv, NULL);
   10963            0 :     ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
   10964              :   }
   10965              : #else
   10966              :   {
   10967              :     time_t now = time (NULL);
   10968              : 
   10969              :     if (now != (time_t)-1)
   10970              :       ret = (unsigned) now;
   10971              :   }
   10972              : #endif
   10973              : 
   10974            0 :   return ret ^ getpid ();
   10975              : }
   10976              : 
   10977              : /* %:compare-debug-dump-opt spec function.  Save the last argument,
   10978              :    expected to be the last -fdump-final-insns option, or generate a
   10979              :    temporary.  */
   10980              : 
   10981              : static const char *
   10982         1265 : compare_debug_dump_opt_spec_function (int arg,
   10983              :                                       const char **argv ATTRIBUTE_UNUSED)
   10984              : {
   10985         1265 :   char *ret;
   10986         1265 :   char *name;
   10987         1265 :   int which;
   10988         1265 :   static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
   10989              : 
   10990         1265 :   if (arg != 0)
   10991            0 :     fatal_error (input_location,
   10992              :                  "too many arguments to %%:compare-debug-dump-opt");
   10993              : 
   10994         1265 :   do_spec_2 ("%{fdump-final-insns=*:%*}", NULL);
   10995         1265 :   do_spec_1 (" ", 0, NULL);
   10996              : 
   10997         1265 :   if (argbuf.length () > 0
   10998         1265 :       && strcmp (argv[argbuf.length () - 1], ".") != 0)
   10999              :     {
   11000            0 :       if (!compare_debug)
   11001              :         return NULL;
   11002              : 
   11003            0 :       name = xstrdup (argv[argbuf.length () - 1]);
   11004            0 :       ret = NULL;
   11005              :     }
   11006              :   else
   11007              :     {
   11008         1265 :       if (argbuf.length () > 0)
   11009            6 :         do_spec_2 ("%B.gkd", NULL);
   11010         1259 :       else if (!compare_debug)
   11011              :         return NULL;
   11012              :       else
   11013         1259 :         do_spec_2 ("%{!save-temps*:%g.gkd}%{save-temps*:%B.gkd}", NULL);
   11014              : 
   11015         1265 :       do_spec_1 (" ", 0, NULL);
   11016              : 
   11017         1265 :       gcc_assert (argbuf.length () > 0);
   11018              : 
   11019         1265 :       name = xstrdup (argbuf.last ());
   11020              : 
   11021         1265 :       char *arg = quote_spec (xstrdup (name));
   11022         1265 :       ret = concat ("-fdump-final-insns=", arg, NULL);
   11023         1265 :       free (arg);
   11024              :     }
   11025              : 
   11026         1265 :   which = compare_debug < 0;
   11027         1265 :   debug_check_temp_file[which] = name;
   11028              : 
   11029         1265 :   if (!which)
   11030              :     {
   11031          636 :       unsigned HOST_WIDE_INT value = get_random_number ();
   11032              : 
   11033          636 :       sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
   11034              :     }
   11035              : 
   11036         1265 :   if (*random_seed)
   11037              :     {
   11038         1265 :       char *tmp = ret;
   11039         1265 :       ret = concat ("%{!frandom-seed=*:-frandom-seed=", random_seed, "} ",
   11040              :                     ret, NULL);
   11041         1265 :       free (tmp);
   11042              :     }
   11043              : 
   11044         1265 :   if (which)
   11045          629 :     *random_seed = 0;
   11046              : 
   11047              :   return ret;
   11048              : }
   11049              : 
   11050              : /* %:compare-debug-self-opt spec function.  Expands to the options
   11051              :     that are to be passed in the second compilation of
   11052              :     compare-debug.  */
   11053              : 
   11054              : static const char *
   11055         1270 : compare_debug_self_opt_spec_function (int arg,
   11056              :                                       const char **argv ATTRIBUTE_UNUSED)
   11057              : {
   11058         1270 :   if (arg != 0)
   11059            0 :     fatal_error (input_location,
   11060              :                  "too many arguments to %%:compare-debug-self-opt");
   11061              : 
   11062         1270 :   if (compare_debug >= 0)
   11063              :     return NULL;
   11064              : 
   11065          635 :   return concat ("\
   11066              : %<o %<MD %<MMD %<MF* %<MG %<MP %<MQ* %<MT* \
   11067              : %<fdump-final-insns=* -w -S -o %j \
   11068              : %{!fcompare-debug-second:-fcompare-debug-second} \
   11069          635 : ", compare_debug_opt, NULL);
   11070              : }
   11071              : 
   11072              : /* %:pass-through-libs spec function.  Finds all -l options and input
   11073              :    file names in the lib spec passed to it, and makes a list of them
   11074              :    prepended with the plugin option to cause them to be passed through
   11075              :    to the final link after all the new object files have been added.  */
   11076              : 
   11077              : const char *
   11078        92400 : pass_through_libs_spec_func (int argc, const char **argv)
   11079              : {
   11080        92400 :   char *prepended = xstrdup (" ");
   11081        92400 :   int n;
   11082              :   /* Shlemiel the painter's algorithm.  Innately horrible, but at least
   11083              :      we know that there will never be more than a handful of strings to
   11084              :      concat, and it's only once per run, so it's not worth optimising.  */
   11085       739616 :   for (n = 0; n < argc; n++)
   11086              :     {
   11087       647216 :       char *old = prepended;
   11088              :       /* Anything that isn't an option is a full path to an output
   11089              :          file; pass it through if it ends in '.a'.  Among options,
   11090              :          pass only -l.  */
   11091       647216 :       if (argv[n][0] == '-' && argv[n][1] == 'l')
   11092              :         {
   11093       603836 :           const char *lopt = argv[n] + 2;
   11094              :           /* Handle both joined and non-joined -l options.  If for any
   11095              :              reason there's a trailing -l with no joined or following
   11096              :              arg just discard it.  */
   11097       603836 :           if (!*lopt && ++n >= argc)
   11098              :             break;
   11099       603836 :           else if (!*lopt)
   11100            0 :             lopt = argv[n];
   11101       603836 :           prepended = concat (prepended, "-plugin-opt=-pass-through=-l",
   11102              :                 lopt, " ", NULL);
   11103       603836 :         }
   11104        43380 :       else if (!strcmp (".a", argv[n] + strlen (argv[n]) - 2))
   11105              :         {
   11106            0 :           prepended = concat (prepended, "-plugin-opt=-pass-through=",
   11107              :                 argv[n], " ", NULL);
   11108              :         }
   11109       647216 :       if (prepended != old)
   11110       603836 :         free (old);
   11111              :     }
   11112        92400 :   return prepended;
   11113              : }
   11114              : 
   11115              : static bool
   11116       534879 : not_actual_file_p (const char *name)
   11117              : {
   11118       534879 :   return (strcmp (name, "-") == 0
   11119       534879 :           || strcmp (name, HOST_BIT_BUCKET) == 0);
   11120              : }
   11121              : 
   11122              : /* %:dumps spec function.  Take an optional argument that overrides
   11123              :    the default extension for -dumpbase and -dumpbase-ext.
   11124              :    Return -dumpdir, -dumpbase and -dumpbase-ext, if needed.  */
   11125              : const char *
   11126       293767 : dumps_spec_func (int argc, const char **argv ATTRIBUTE_UNUSED)
   11127              : {
   11128       293767 :   const char *ext = dumpbase_ext;
   11129       293767 :   char *p;
   11130              : 
   11131       293767 :   char *args[3] = { NULL, NULL, NULL };
   11132       293767 :   int nargs = 0;
   11133              : 
   11134              :   /* Do not compute a default for -dumpbase-ext when -dumpbase was
   11135              :      given explicitly.  */
   11136       293767 :   if (dumpbase && *dumpbase && !ext)
   11137       293767 :     ext = "";
   11138              : 
   11139       293767 :   if (argc == 1)
   11140              :     {
   11141              :       /* Do not override the explicitly-specified -dumpbase-ext with
   11142              :          the specs-provided overrider.  */
   11143            0 :       if (!ext)
   11144            0 :         ext = argv[0];
   11145              :     }
   11146       293767 :   else if (argc != 0)
   11147            0 :     fatal_error (input_location, "too many arguments for %%:dumps");
   11148              : 
   11149       293767 :   if (dumpdir)
   11150              :     {
   11151       107138 :       p = quote_spec_arg (xstrdup (dumpdir));
   11152       107138 :       args[nargs++] = concat (" -dumpdir ", p, NULL);
   11153       107138 :       free (p);
   11154              :     }
   11155              : 
   11156       293767 :   if (!ext)
   11157       270638 :     ext = input_basename + basename_length;
   11158              : 
   11159              :   /* Use the precomputed outbase, or compute dumpbase from
   11160              :      input_basename, just like %b would.  */
   11161       293767 :   char *base;
   11162              : 
   11163       293767 :   if (dumpbase && *dumpbase)
   11164              :     {
   11165        23129 :       base = xstrdup (dumpbase);
   11166        23129 :       p = base + outbase_length;
   11167        23129 :       gcc_checking_assert (strncmp (base, outbase, outbase_length) == 0);
   11168        23129 :       gcc_checking_assert (strcmp (p, ext) == 0);
   11169              :     }
   11170       270638 :   else if (outbase_length)
   11171              :     {
   11172       168363 :       base = xstrndup (outbase, outbase_length);
   11173       168363 :       p = NULL;
   11174              :     }
   11175              :   else
   11176              :     {
   11177       102275 :       base = xstrndup (input_basename, suffixed_basename_length);
   11178       102275 :       p = base + basename_length;
   11179              :     }
   11180              : 
   11181       293767 :   if (compare_debug < 0 || !p || strcmp (p, ext) != 0)
   11182              :     {
   11183          629 :       if (p)
   11184            9 :         *p = '\0';
   11185              : 
   11186       168372 :       const char *gk;
   11187       168372 :       if (compare_debug < 0)
   11188              :         gk = ".gk";
   11189              :       else
   11190       167743 :         gk = "";
   11191              : 
   11192       168372 :       p = concat (base, gk, ext, NULL);
   11193              : 
   11194       168372 :       free (base);
   11195       168372 :       base = p;
   11196              :     }
   11197              : 
   11198       293767 :   base = quote_spec_arg (base);
   11199       293767 :   args[nargs++] = concat (" -dumpbase ", base, NULL);
   11200       293767 :   free (base);
   11201              : 
   11202       293767 :   if (*ext)
   11203              :     {
   11204       269600 :       p = quote_spec_arg (xstrdup (ext));
   11205       269600 :       args[nargs++] = concat (" -dumpbase-ext ", p, NULL);
   11206       269600 :       free (p);
   11207              :     }
   11208              : 
   11209       293767 :   const char *ret = concat (args[0], args[1], args[2], NULL);
   11210      1258039 :   while (nargs > 0)
   11211       670505 :     free (args[--nargs]);
   11212              : 
   11213       293767 :   return ret;
   11214              : }
   11215              : 
   11216              : /* Returns "" if ARGV[ARGC - 2] is greater than ARGV[ARGC-1].
   11217              :    Otherwise, return NULL.  */
   11218              : 
   11219              : static const char *
   11220       409861 : greater_than_spec_func (int argc, const char **argv)
   11221              : {
   11222       409861 :   char *converted;
   11223              : 
   11224       409861 :   if (argc == 1)
   11225              :     return NULL;
   11226              : 
   11227          252 :   gcc_assert (argc >= 2);
   11228              : 
   11229          252 :   long arg = strtol (argv[argc - 2], &converted, 10);
   11230          252 :   gcc_assert (converted != argv[argc - 2]);
   11231              : 
   11232          252 :   long lim = strtol (argv[argc - 1], &converted, 10);
   11233          252 :   gcc_assert (converted != argv[argc - 1]);
   11234              : 
   11235          252 :   if (arg > lim)
   11236              :     return "";
   11237              : 
   11238              :   return NULL;
   11239              : }
   11240              : 
   11241              : /* Returns "" if debug_info_level is greater than ARGV[ARGC-1].
   11242              :    Otherwise, return NULL.  */
   11243              : 
   11244              : static const char *
   11245       260013 : debug_level_greater_than_spec_func (int argc, const char **argv)
   11246              : {
   11247       260013 :   char *converted;
   11248              : 
   11249       260013 :   if (argc != 1)
   11250            0 :     fatal_error (input_location,
   11251              :                  "wrong number of arguments to %%:debug-level-gt");
   11252              : 
   11253       260013 :   long arg = strtol (argv[0], &converted, 10);
   11254       260013 :   gcc_assert (converted != argv[0]);
   11255              : 
   11256       260013 :   if (debug_info_level > arg)
   11257        45416 :     return "";
   11258              : 
   11259              :   return NULL;
   11260              : }
   11261              : 
   11262              : /* Returns "" if dwarf_version is greater than ARGV[ARGC-1].
   11263              :    Otherwise, return NULL.  */
   11264              : 
   11265              : static const char *
   11266       128790 : dwarf_version_greater_than_spec_func (int argc, const char **argv)
   11267              : {
   11268       128790 :   char *converted;
   11269              : 
   11270       128790 :   if (argc != 1)
   11271            0 :     fatal_error (input_location,
   11272              :                  "wrong number of arguments to %%:dwarf-version-gt");
   11273              : 
   11274       128790 :   long arg = strtol (argv[0], &converted, 10);
   11275       128790 :   gcc_assert (converted != argv[0]);
   11276              : 
   11277       128790 :   if (dwarf_version > arg)
   11278       127919 :     return "";
   11279              : 
   11280              :   return NULL;
   11281              : }
   11282              : 
   11283              : static void
   11284        35195 : path_prefix_reset (path_prefix *prefix)
   11285              : {
   11286        35195 :   struct prefix_list *iter, *next;
   11287        35195 :   iter = prefix->plist;
   11288       139636 :   while (iter)
   11289              :     {
   11290       104441 :       next = iter->next;
   11291       104441 :       free (const_cast <char *> (iter->prefix));
   11292       104441 :       XDELETE (iter);
   11293       104441 :       iter = next;
   11294              :     }
   11295        35195 :   prefix->plist = 0;
   11296        35195 :   prefix->max_len = 0;
   11297        35195 : }
   11298              : 
   11299              : /* The function takes 3 arguments: OPTION name, file name and location
   11300              :    where we search for Fortran modules.
   11301              :    When the FILE is found by find_file, return OPTION=path_to_file.  */
   11302              : 
   11303              : static const char *
   11304        31763 : find_fortran_preinclude_file (int argc, const char **argv)
   11305              : {
   11306        31763 :   char *result = NULL;
   11307        31763 :   if (argc != 3)
   11308              :     return NULL;
   11309              : 
   11310        31763 :   struct path_prefix prefixes = { 0, 0, "preinclude" };
   11311              : 
   11312              :   /* Search first for 'finclude' folder location for a header file
   11313              :      installed by the compiler (similar to omp_lib.h).  */
   11314        31763 :   add_prefix (&prefixes, argv[2], NULL, 0, 0, 0);
   11315              : #ifdef TOOL_INCLUDE_DIR
   11316              :   /* Then search: <prefix>/<target>/<include>/finclude */
   11317        31763 :   add_prefix (&prefixes, TOOL_INCLUDE_DIR "/finclude/",
   11318              :               NULL, 0, 0, 0);
   11319              : #endif
   11320              : #ifdef NATIVE_SYSTEM_HEADER_DIR
   11321              :   /* Then search: <sysroot>/usr/include/finclude/<multilib> */
   11322        31763 :   add_sysrooted_hdrs_prefix (&prefixes, NATIVE_SYSTEM_HEADER_DIR "/finclude/",
   11323              :                              NULL, 0, 0, 0);
   11324              : #endif
   11325              : 
   11326        31763 :   const char *path = find_a_file (&include_prefixes, argv[1], false);
   11327        31763 :   if (path != NULL)
   11328            0 :     result = concat (argv[0], path, NULL);
   11329              :   else
   11330              :     {
   11331        31763 :       path = find_a_file (&prefixes, argv[1], false);
   11332        31763 :       if (path != NULL)
   11333        31763 :         result = concat (argv[0], path, NULL);
   11334              :     }
   11335              : 
   11336        31763 :   path_prefix_reset (&prefixes);
   11337        31763 :   return result;
   11338              : }
   11339              : 
   11340              : /* The function takes any number of arguments and joins them together,
   11341              :    escaping any special characters.
   11342              : 
   11343              :    This seems to be necessary to build "-fjoined=foo.b" from "-fseparate foo.a"
   11344              :    with a %{fseparate*:-fjoined=%.b$*} rule without adding undesired spaces:
   11345              :    when doing $* replacement we first replace $* with the rest of the switch
   11346              :    (in this case ""), and then add any arguments as arguments after the result,
   11347              :    resulting in "-fjoined= foo.b".  Using this function with e.g.
   11348              :    %{fseparate*:-fjoined=%:join(%.b$*)} gets multiple words as separate argv
   11349              :    elements instead of separated by spaces, and we paste them together.  */
   11350              : 
   11351              : static const char *
   11352           39 : join_spec_func (int argc, const char **argv)
   11353              : {
   11354           39 :   const char *result = argv[0];
   11355           39 :   if (argc != 1)
   11356              :     {
   11357          117 :       for (int i = 0; i < argc; ++i)
   11358           78 :         obstack_grow (&obstack, argv[i], strlen (argv[i]));
   11359           39 :       obstack_1grow (&obstack, '\0');
   11360           39 :       result = XOBFINISH (&obstack, const char *);
   11361              :     }
   11362           39 :   return quote_spec (xstrdup (result));
   11363              : }
   11364              : 
   11365              : /* If any character in ORIG fits QUOTE_P (_, P), reallocate the string
   11366              :    so as to precede every one of them with a backslash.  Return the
   11367              :    original string or the reallocated one.  */
   11368              : 
   11369              : static inline char *
   11370       877501 : quote_string (char *orig, bool (*quote_p)(char, void *), void *p)
   11371              : {
   11372       877501 :   int len, number_of_space = 0;
   11373              : 
   11374     20032910 :   for (len = 0; orig[len]; len++)
   11375     19155409 :     if (quote_p (orig[len], p))
   11376            0 :       number_of_space++;
   11377              : 
   11378       877501 :   if (number_of_space)
   11379              :     {
   11380            0 :       char *new_spec = (char *) xmalloc (len + number_of_space + 1);
   11381            0 :       int j, k;
   11382            0 :       for (j = 0, k = 0; j <= len; j++, k++)
   11383              :         {
   11384            0 :           if (quote_p (orig[j], p))
   11385            0 :             new_spec[k++] = '\\';
   11386            0 :           new_spec[k] = orig[j];
   11387              :         }
   11388            0 :       free (orig);
   11389            0 :       return new_spec;
   11390              :     }
   11391              :   else
   11392              :     return orig;
   11393              : }
   11394              : 
   11395              : /* Return true iff C is any of the characters convert_white_space
   11396              :    should quote.  */
   11397              : 
   11398              : static inline bool
   11399     12761436 : whitespace_to_convert_p (char c, void *)
   11400              : {
   11401     12761436 :   return (c == ' ' || c == '\t');
   11402              : }
   11403              : 
   11404              : /* Insert backslash before spaces in ORIG (usually a file path), to
   11405              :    avoid being broken by spec parser.
   11406              : 
   11407              :    This function is needed as do_spec_1 treats white space (' ' and '\t')
   11408              :    as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
   11409              :    the file name should be treated as a single argument rather than being
   11410              :    broken into multiple. Solution is to insert '\\' before the space in a
   11411              :    file name.
   11412              : 
   11413              :    This function converts and only converts all occurrence of ' '
   11414              :    to '\\' + ' ' and '\t' to '\\' + '\t'.  For example:
   11415              :    "a b"  -> "a\\ b"
   11416              :    "a  b" -> "a\\ \\ b"
   11417              :    "a\tb" -> "a\\\tb"
   11418              :    "a\\ b" -> "a\\\\ b"
   11419              : 
   11420              :    orig: input null-terminating string that was allocated by xalloc. The
   11421              :    memory it points to might be freed in this function. Behavior undefined
   11422              :    if ORIG wasn't xalloced or was freed already at entry.
   11423              : 
   11424              :    Return: ORIG if no conversion needed. Otherwise a newly allocated string
   11425              :    that was converted from ORIG.  */
   11426              : 
   11427              : static char *
   11428       205701 : convert_white_space (char *orig)
   11429              : {
   11430       205701 :   return quote_string (orig, whitespace_to_convert_p, NULL);
   11431              : }
   11432              : 
   11433              : /* Return true iff C matches any of the spec active characters.  */
   11434              : static inline bool
   11435      6393973 : quote_spec_char_p (char c, void *)
   11436              : {
   11437      6393973 :   switch (c)
   11438              :     {
   11439              :     case ' ':
   11440              :     case '\t':
   11441              :     case '\n':
   11442              :     case '|':
   11443              :     case '%':
   11444              :     case '\\':
   11445              :       return true;
   11446              : 
   11447      6393973 :     default:
   11448      6393973 :       return false;
   11449              :     }
   11450              : }
   11451              : 
   11452              : /* Like convert_white_space, but deactivate all active spec chars by
   11453              :    quoting them.  */
   11454              : 
   11455              : static inline char *
   11456       671800 : quote_spec (char *orig)
   11457              : {
   11458         1304 :   return quote_string (orig, quote_spec_char_p, NULL);
   11459              : }
   11460              : 
   11461              : /* Like quote_spec, but also turn an empty string into the spec for an
   11462              :    empty argument.  */
   11463              : 
   11464              : static inline char *
   11465       670505 : quote_spec_arg (char *orig)
   11466              : {
   11467       670505 :   if (!*orig)
   11468              :     {
   11469            9 :       free (orig);
   11470            9 :       return xstrdup ("%\"");
   11471              :     }
   11472              : 
   11473       670496 :   return quote_spec (orig);
   11474              : }
   11475              : 
   11476              : /* Restore all state within gcc.cc to the initial state, so that the driver
   11477              :    code can be safely re-run in-process.
   11478              : 
   11479              :    Many const char * variables are referenced by static specs (see
   11480              :    INIT_STATIC_SPEC above).  These variables are restored to their default
   11481              :    values by a simple loop over the static specs.
   11482              : 
   11483              :    For other variables, we directly restore them all to their initial
   11484              :    values (often implicitly 0).
   11485              : 
   11486              :    Free the various obstacks in this file, along with "opts_obstack"
   11487              :    from opts.cc.
   11488              : 
   11489              :    This function also restores any environment variables that were changed.  */
   11490              : 
   11491              : void
   11492         1144 : driver::finalize ()
   11493              : {
   11494         1144 :   env.restore ();
   11495         1144 :   diagnostic_finish (global_dc);
   11496              : 
   11497         1144 :   is_cpp_driver = 0;
   11498         1144 :   at_file_supplied = 0;
   11499         1144 :   print_help_list = 0;
   11500         1144 :   print_version = 0;
   11501         1144 :   verbose_only_flag = 0;
   11502         1144 :   print_subprocess_help = 0;
   11503         1144 :   use_ld = NULL;
   11504         1144 :   report_times_to_file = NULL;
   11505         1144 :   target_system_root = DEFAULT_TARGET_SYSTEM_ROOT;
   11506         1144 :   target_system_root_changed = 0;
   11507         1144 :   target_sysroot_suffix = 0;
   11508         1144 :   target_sysroot_hdrs_suffix = 0;
   11509         1144 :   save_temps_flag = SAVE_TEMPS_NONE;
   11510         1144 :   save_temps_overrides_dumpdir = false;
   11511         1144 :   dumpdir_trailing_dash_added = false;
   11512         1144 :   free (dumpdir);
   11513         1144 :   free (dumpbase);
   11514         1144 :   free (dumpbase_ext);
   11515         1144 :   free (outbase);
   11516         1144 :   dumpdir = dumpbase = dumpbase_ext = outbase = NULL;
   11517         1144 :   dumpdir_length = outbase_length = 0;
   11518         1144 :   spec_machine = DEFAULT_TARGET_MACHINE;
   11519         1144 :   greatest_status = 1;
   11520              : 
   11521         1144 :   obstack_free (&obstack, NULL);
   11522         1144 :   obstack_free (&opts_obstack, NULL); /* in opts.cc */
   11523         1144 :   obstack_free (&collect_obstack, NULL);
   11524              : 
   11525         1144 :   link_command_spec = LINK_COMMAND_SPEC;
   11526              : 
   11527         1144 :   obstack_free (&multilib_obstack, NULL);
   11528              : 
   11529         1144 :   user_specs_head = NULL;
   11530         1144 :   user_specs_tail = NULL;
   11531              : 
   11532              :   /* Within the "compilers" vec, the fields "suffix" and "spec" were
   11533              :      statically allocated for the default compilers, but dynamically
   11534              :      allocated for additional compilers.  Delete them for the latter. */
   11535         1144 :   for (int i = n_default_compilers; i < n_compilers; i++)
   11536              :     {
   11537            0 :       free (const_cast <char *> (compilers[i].suffix));
   11538            0 :       free (const_cast <char *> (compilers[i].spec));
   11539              :     }
   11540         1144 :   XDELETEVEC (compilers);
   11541         1144 :   compilers = NULL;
   11542         1144 :   n_compilers = 0;
   11543              : 
   11544         1144 :   linker_options.truncate (0);
   11545         1144 :   assembler_options.truncate (0);
   11546         1144 :   preprocessor_options.truncate (0);
   11547              : 
   11548         1144 :   path_prefix_reset (&exec_prefixes);
   11549         1144 :   path_prefix_reset (&startfile_prefixes);
   11550         1144 :   path_prefix_reset (&include_prefixes);
   11551              : 
   11552         1144 :   machine_suffix = 0;
   11553         1144 :   just_machine_suffix = 0;
   11554         1144 :   gcc_exec_prefix = 0;
   11555         1144 :   gcc_libexec_prefix = 0;
   11556         1144 :   set_static_spec_shared (&md_exec_prefix, MD_EXEC_PREFIX);
   11557         1144 :   set_static_spec_shared (&md_startfile_prefix, MD_STARTFILE_PREFIX);
   11558         1144 :   set_static_spec_shared (&md_startfile_prefix_1, MD_STARTFILE_PREFIX_1);
   11559         1144 :   multilib_dir = 0;
   11560         1144 :   multilib_os_dir = 0;
   11561         1144 :   multiarch_dir = 0;
   11562              : 
   11563              :   /* Free any specs dynamically-allocated by set_spec.
   11564              :      These will be at the head of the list, before the
   11565              :      statically-allocated ones.  */
   11566         1144 :   if (specs)
   11567              :     {
   11568         2288 :       while (specs != static_specs)
   11569              :         {
   11570         1144 :           spec_list *next = specs->next;
   11571         1144 :           free (const_cast <char *> (specs->name));
   11572         1144 :           XDELETE (specs);
   11573         1144 :           specs = next;
   11574              :         }
   11575         1144 :       specs = 0;
   11576              :     }
   11577        52624 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
   11578              :     {
   11579        51480 :       spec_list *sl = &static_specs[i];
   11580        51480 :       if (sl->alloc_p)
   11581              :         {
   11582        45770 :           free (const_cast <char *> (*(sl->ptr_spec)));
   11583        45770 :           sl->alloc_p = false;
   11584              :         }
   11585        51480 :       *(sl->ptr_spec) = sl->default_ptr;
   11586              :     }
   11587              : #ifdef EXTRA_SPECS
   11588         1144 :   extra_specs = NULL;
   11589              : #endif
   11590              : 
   11591         1144 :   processing_spec_function = 0;
   11592              : 
   11593         1144 :   clear_args ();
   11594              : 
   11595         1144 :   have_c = 0;
   11596         1144 :   have_o = 0;
   11597              : 
   11598         1144 :   temp_names = NULL;
   11599         1144 :   execution_count = 0;
   11600         1144 :   signal_count = 0;
   11601              : 
   11602         1144 :   temp_filename = NULL;
   11603         1144 :   temp_filename_length = 0;
   11604         1144 :   always_delete_queue = NULL;
   11605         1144 :   failure_delete_queue = NULL;
   11606              : 
   11607         1144 :   XDELETEVEC (switches);
   11608         1144 :   switches = NULL;
   11609         1144 :   n_switches = 0;
   11610         1144 :   n_switches_alloc = 0;
   11611              : 
   11612         1144 :   compare_debug = 0;
   11613         1144 :   compare_debug_second = 0;
   11614         1144 :   compare_debug_opt = NULL;
   11615         3432 :   for (int i = 0; i < 2; i++)
   11616              :     {
   11617         2288 :       switches_debug_check[i] = NULL;
   11618         2288 :       n_switches_debug_check[i] = 0;
   11619         2288 :       n_switches_alloc_debug_check[i] = 0;
   11620         2288 :       debug_check_temp_file[i] = NULL;
   11621              :     }
   11622              : 
   11623         1144 :   XDELETEVEC (infiles);
   11624         1144 :   infiles = NULL;
   11625         1144 :   n_infiles = 0;
   11626         1144 :   n_infiles_alloc = 0;
   11627              : 
   11628         1144 :   combine_inputs = false;
   11629         1144 :   added_libraries = 0;
   11630         1144 :   XDELETEVEC (outfiles);
   11631         1144 :   outfiles = NULL;
   11632         1144 :   spec_lang = 0;
   11633         1144 :   last_language_n_infiles = 0;
   11634         1144 :   gcc_input_filename = NULL;
   11635         1144 :   input_file_number = 0;
   11636         1144 :   input_filename_length = 0;
   11637         1144 :   basename_length = 0;
   11638         1144 :   suffixed_basename_length = 0;
   11639         1144 :   input_basename = NULL;
   11640         1144 :   input_suffix = NULL;
   11641              :   /* We don't need to purge "input_stat", just to unset "input_stat_set".  */
   11642         1144 :   input_stat_set = 0;
   11643         1144 :   input_file_compiler = NULL;
   11644         1144 :   arg_going = 0;
   11645         1144 :   delete_this_arg = 0;
   11646         1144 :   this_is_output_file = 0;
   11647         1144 :   this_is_library_file = 0;
   11648         1144 :   this_is_linker_script = 0;
   11649         1144 :   input_from_pipe = 0;
   11650         1144 :   suffix_subst = NULL;
   11651              : 
   11652         1144 :   XDELETEVEC (mdswitches);
   11653         1144 :   mdswitches = NULL;
   11654         1144 :   n_mdswitches = 0;
   11655              : 
   11656         1144 :   used_arg.finalize ();
   11657         1144 : }
   11658              : 
   11659              : /* PR jit/64810.
   11660              :    Targets can provide configure-time default options in
   11661              :    OPTION_DEFAULT_SPECS.  The jit needs to access these, but
   11662              :    they are expressed in the spec language.
   11663              : 
   11664              :    Run just enough of the driver to be able to expand these
   11665              :    specs, and then call the callback CB on each
   11666              :    such option.  The options strings are *without* a leading
   11667              :    '-' character e.g. ("march=x86-64").  Finally, clean up.  */
   11668              : 
   11669              : void
   11670          132 : driver_get_configure_time_options (void (*cb) (const char *option,
   11671              :                                                void *user_data),
   11672              :                                    void *user_data)
   11673              : {
   11674          132 :   size_t i;
   11675              : 
   11676          132 :   obstack_init (&obstack);
   11677          132 :   init_opts_obstack ();
   11678          132 :   n_switches = 0;
   11679              : 
   11680         1452 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
   11681         1320 :     do_option_spec (option_default_specs[i].name,
   11682         1320 :                     option_default_specs[i].spec);
   11683              : 
   11684          396 :   for (i = 0; (int) i < n_switches; i++)
   11685              :     {
   11686          264 :       gcc_assert (switches[i].part1);
   11687          264 :       (*cb) (switches[i].part1, user_data);
   11688              :     }
   11689              : 
   11690          132 :   obstack_free (&opts_obstack, NULL);
   11691          132 :   obstack_free (&obstack, NULL);
   11692          132 :   n_switches = 0;
   11693          132 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.