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-07-11 15:47:05 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       304123 : env_manager::init (bool can_restore, bool debug)
     105              : {
     106       304123 :   m_can_restore = can_restore;
     107       304123 :   m_debug = debug;
     108       304123 : }
     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      1519682 : env_manager::get (const char *name)
     116              : {
     117      1519682 :   const char *result = ::getenv (name);
     118      1519682 :   if (m_debug)
     119            0 :     fprintf (stderr, "env_manager::getenv (%s) -> %s\n", name, result);
     120      1519682 :   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      1790442 : env_manager::xput (const char *string)
     130              : {
     131      1790442 :   if (m_debug)
     132            0 :     fprintf (stderr, "env_manager::xput (%s)\n", string);
     133      1790442 :   if (verbose_flag)
     134         6352 :     fnotice (stderr, "%s\n", string);
     135              : 
     136      1790442 :   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      1790442 :   ::putenv (const_cast<char *> (string));
     151      1790442 : }
     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_V_SPEC to pass equivalents of -v, -w (no warnings),
     713              :    and -I to the assembler.  */
     714              : #ifndef ASM_V_SPEC
     715              : #define ASM_V_SPEC "%{v} %{w:-W} %{I*}"
     716              : #endif
     717              : 
     718              : /* config.h can define ASM_FINAL_SPEC to run a post processor after
     719              :    the assembler has run.  */
     720              : #ifndef ASM_FINAL_SPEC
     721              : #define ASM_FINAL_SPEC \
     722              :   "%{gsplit-dwarf: \n\
     723              :        objcopy --extract-dwo \
     724              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     725              :          %b.dwo \n\
     726              :        objcopy --strip-dwo \
     727              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     728              :     }"
     729              : #endif
     730              : 
     731              : /* config.h can define CPP_SPEC to provide extra args to the C preprocessor
     732              :    or extra switch-translations.  */
     733              : #ifndef CPP_SPEC
     734              : #define CPP_SPEC ""
     735              : #endif
     736              : 
     737              : /* libc can define LIBC_CPP_SPEC to provide extra args to the C preprocessor
     738              :    or extra switch-translations. */
     739              : 
     740              : #ifndef LIBC_CPP_SPEC
     741              : #define LIBC_CPP_SPEC ""
     742              : #endif
     743              : 
     744              : /* Operating systems can define OS_CC1_SPEC to provide extra args to cc1 and
     745              :    cc1plus or extra switch-translations.  The OS_CC1_SPEC is appended
     746              :    to CC1_SPEC in the initialization of cc1_spec.  */
     747              : #ifndef OS_CC1_SPEC
     748              : #define OS_CC1_SPEC ""
     749              : #endif
     750              : 
     751              : /* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
     752              :    or extra switch-translations.  */
     753              : #ifndef CC1_SPEC
     754              : #define CC1_SPEC ""
     755              : #endif
     756              : 
     757              : /* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
     758              :    or extra switch-translations.  */
     759              : #ifndef CC1PLUS_SPEC
     760              : #define CC1PLUS_SPEC ""
     761              : #endif
     762              : 
     763              : /* config.h can define LINK_SPEC to provide extra args to the linker
     764              :    or extra switch-translations.  */
     765              : #ifndef LINK_SPEC
     766              : #define LINK_SPEC ""
     767              : #endif
     768              : 
     769              : /* libc can define LIBC_LINK_SPEC to provide extra args to the linker
     770              :    or extra switch-translations.  */
     771              : #ifndef LIBC_LINK_SPEC
     772              : #define LIBC_LINK_SPEC ""
     773              : #endif
     774              : 
     775              : /* config.h can define LIB_SPEC to override the default libraries.  */
     776              : #ifndef LIB_SPEC
     777              : #define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
     778              : #endif
     779              : 
     780              : /* When using -fsplit-stack we need to wrap pthread_create, in order
     781              :    to initialize the stack guard.  We always use wrapping, rather than
     782              :    shared library ordering, and we keep the wrapper function in
     783              :    libgcc.  This is not yet a real spec, though it could become one;
     784              :    it is currently just stuffed into LINK_SPEC.  FIXME: This wrapping
     785              :    only works with GNU ld and gold.  */
     786              : #ifdef HAVE_GOLD_NON_DEFAULT_SPLIT_STACK
     787              : #define STACK_SPLIT_SPEC " %{fsplit-stack: -fuse-ld=gold --wrap=pthread_create}"
     788              : #else
     789              : #define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
     790              : #endif
     791              : 
     792              : #ifndef LIBASAN_SPEC
     793              : #define STATIC_LIBASAN_LIBS \
     794              :   " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}"
     795              : #ifdef LIBASAN_EARLY_SPEC
     796              : #define LIBASAN_SPEC STATIC_LIBASAN_LIBS
     797              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     798              : #define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
     799              :                      "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
     800              :                      STATIC_LIBASAN_LIBS
     801              : #else
     802              : #define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS
     803              : #endif
     804              : #endif
     805              : 
     806              : #ifndef LIBASAN_EARLY_SPEC
     807              : #define LIBASAN_EARLY_SPEC ""
     808              : #endif
     809              : 
     810              : #ifndef LIBHWASAN_SPEC
     811              : #define STATIC_LIBHWASAN_LIBS \
     812              :   " %{static-libhwasan|static:%:include(libsanitizer.spec)%(link_libhwasan)}"
     813              : #ifdef LIBHWASAN_EARLY_SPEC
     814              : #define LIBHWASAN_SPEC STATIC_LIBHWASAN_LIBS
     815              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     816              : #define LIBHWASAN_SPEC "%{static-libhwasan:" LD_STATIC_OPTION \
     817              :                      "} -lhwasan %{static-libhwasan:" LD_DYNAMIC_OPTION "}" \
     818              :                      STATIC_LIBHWASAN_LIBS
     819              : #else
     820              : #define LIBHWASAN_SPEC "-lhwasan" STATIC_LIBHWASAN_LIBS
     821              : #endif
     822              : #endif
     823              : 
     824              : #ifndef LIBHWASAN_EARLY_SPEC
     825              : #define LIBHWASAN_EARLY_SPEC ""
     826              : #endif
     827              : 
     828              : #ifndef LIBTSAN_SPEC
     829              : #define STATIC_LIBTSAN_LIBS \
     830              :   " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}"
     831              : #ifdef LIBTSAN_EARLY_SPEC
     832              : #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS
     833              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     834              : #define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
     835              :                      "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \
     836              :                      STATIC_LIBTSAN_LIBS
     837              : #else
     838              : #define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS
     839              : #endif
     840              : #endif
     841              : 
     842              : #ifndef LIBTSAN_EARLY_SPEC
     843              : #define LIBTSAN_EARLY_SPEC ""
     844              : #endif
     845              : 
     846              : #ifndef LIBLSAN_SPEC
     847              : #define STATIC_LIBLSAN_LIBS \
     848              :   " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}"
     849              : #ifdef LIBLSAN_EARLY_SPEC
     850              : #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS
     851              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     852              : #define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION \
     853              :                      "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \
     854              :                      STATIC_LIBLSAN_LIBS
     855              : #else
     856              : #define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS
     857              : #endif
     858              : #endif
     859              : 
     860              : #ifndef LIBLSAN_EARLY_SPEC
     861              : #define LIBLSAN_EARLY_SPEC ""
     862              : #endif
     863              : 
     864              : #ifndef LIBUBSAN_SPEC
     865              : #define STATIC_LIBUBSAN_LIBS \
     866              :   " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}"
     867              : #ifdef HAVE_LD_STATIC_DYNAMIC
     868              : #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
     869              :                      "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
     870              :                      STATIC_LIBUBSAN_LIBS
     871              : #else
     872              : #define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS
     873              : #endif
     874              : #endif
     875              : 
     876              : /* Linker options for compressed debug sections.  */
     877              : #if HAVE_LD_COMPRESS_DEBUG == 0
     878              : /* No linker support.  */
     879              : #define LINK_COMPRESS_DEBUG_SPEC \
     880              :         " %{gz*:%e-gz is not supported in this configuration} "
     881              : #elif HAVE_LD_COMPRESS_DEBUG == 1
     882              : /* ELF gABI style.  */
     883              : #define LINK_COMPRESS_DEBUG_SPEC \
     884              :         " %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
     885              :         " %{gz=none:"   LD_COMPRESS_DEBUG_OPTION "=none}" \
     886              :         " %{gz=zstd:%e-gz=zstd is not supported in this configuration} " \
     887              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     888              : #elif HAVE_LD_COMPRESS_DEBUG == 2
     889              : /* ELF gABI style and ZSTD.  */
     890              : #define LINK_COMPRESS_DEBUG_SPEC \
     891              :         " %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
     892              :         " %{gz=none:"   LD_COMPRESS_DEBUG_OPTION "=none}" \
     893              :         " %{gz=zstd:"   LD_COMPRESS_DEBUG_OPTION "=zstd}" \
     894              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     895              : #else
     896              : #error Unknown value for HAVE_LD_COMPRESS_DEBUG.
     897              : #endif
     898              : 
     899              : /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
     900              :    included.  */
     901              : #ifndef LIBGCC_SPEC
     902              : #if defined(REAL_LIBGCC_SPEC)
     903              : #define LIBGCC_SPEC REAL_LIBGCC_SPEC
     904              : #elif defined(LINK_LIBGCC_SPECIAL_1)
     905              : /* Have gcc do the search for libgcc.a.  */
     906              : #define LIBGCC_SPEC "libgcc.a%s"
     907              : #else
     908              : #define LIBGCC_SPEC "-lgcc"
     909              : #endif
     910              : #endif
     911              : 
     912              : /* config.h can define STARTFILE_SPEC to override the default crt0 files.  */
     913              : #ifndef STARTFILE_SPEC
     914              : #define STARTFILE_SPEC  \
     915              :   "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
     916              : #endif
     917              : 
     918              : /* config.h can define ENDFILE_SPEC to override the default crtn files.  */
     919              : #ifndef ENDFILE_SPEC
     920              : #define ENDFILE_SPEC ""
     921              : #endif
     922              : 
     923              : #ifndef LINKER_NAME
     924              : #define LINKER_NAME "collect2"
     925              : #endif
     926              : 
     927              : #ifdef HAVE_AS_DEBUG_PREFIX_MAP
     928              : #define ASM_MAP " %{ffile-prefix-map=*:--debug-prefix-map %*} %{fdebug-prefix-map=*:--debug-prefix-map %*}"
     929              : #else
     930              : #define ASM_MAP ""
     931              : #endif
     932              : 
     933              : /* Assembler options for compressed debug sections.  */
     934              : #if HAVE_LD_COMPRESS_DEBUG == 0
     935              : /* Reject if the linker cannot write compressed debug sections.  */
     936              : #define ASM_COMPRESS_DEBUG_SPEC \
     937              :         " %{gz*:%e-gz is not supported in this configuration} "
     938              : #else /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     939              : #if HAVE_AS_COMPRESS_DEBUG == 0
     940              : /* No assembler support.  Ignore silently.  */
     941              : #define ASM_COMPRESS_DEBUG_SPEC \
     942              :         " %{gz*:} "
     943              : #elif HAVE_AS_COMPRESS_DEBUG == 1
     944              : /* ELF gABI style.  */
     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=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     949              : #elif HAVE_AS_COMPRESS_DEBUG == 2
     950              : /* ELF gABI style and ZSTD.  */
     951              : #define ASM_COMPRESS_DEBUG_SPEC \
     952              :         " %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
     953              :         " %{gz=none:"   AS_COMPRESS_DEBUG_OPTION "=none}" \
     954              :         " %{gz=zstd:"   AS_COMPRESS_DEBUG_OPTION "=zstd}" \
     955              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     956              : #else
     957              : #error Unknown value for HAVE_AS_COMPRESS_DEBUG.
     958              : #endif
     959              : #endif /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     960              : 
     961              : /* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
     962              :    to the assembler, when compiling assembly sources only.  */
     963              : #ifndef ASM_DEBUG_SPEC
     964              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     965              : /* If --gdwarf-N is supported and as can handle even compiler generated
     966              :    .debug_line with it, supply --gdwarf-N in ASM_DEBUG_OPTION_SPEC rather
     967              :    than in ASM_DEBUG_SPEC, so that it applies to both .s and .c etc.
     968              :    compilations.  */
     969              : #  define ASM_DEBUG_DWARF_OPTION ""
     970              : # elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && !defined(HAVE_LD_BROKEN_PE_DWARF5)
     971              : #  define ASM_DEBUG_DWARF_OPTION "%{%:dwarf-version-gt(4):--gdwarf-5;" \
     972              :         "%:dwarf-version-gt(3):--gdwarf-4;"                           \
     973              :         "%:dwarf-version-gt(2):--gdwarf-3;"                           \
     974              :         ":--gdwarf2}"
     975              : # else
     976              : #  define ASM_DEBUG_DWARF_OPTION "--gdwarf2"
     977              : # endif
     978              : #  if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
     979              : #   define ASM_DEBUG_SPEC "%{g*:%{%:debug-level-gt(0):" \
     980              :         ASM_DEBUG_DWARF_OPTION "}}" ASM_MAP
     981              : #  endif
     982              : # endif
     983              : #ifndef ASM_DEBUG_SPEC
     984              : # define ASM_DEBUG_SPEC ""
     985              : #endif
     986              : 
     987              : /* Define ASM_DEBUG_OPTION_SPEC to be a spec suitable for translating '-g'
     988              :    to the assembler when compiling all sources.  */
     989              : #ifndef ASM_DEBUG_OPTION_SPEC
     990              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     991              : #  define ASM_DEBUG_OPTION_DWARF_OPT                                    \
     992              :         "%{%:dwarf-version-gt(4):--gdwarf-5 ;"                                \
     993              :         "%:dwarf-version-gt(3):--gdwarf-4 ;"                          \
     994              :         "%:dwarf-version-gt(2):--gdwarf-3 ;"                          \
     995              :         ":--gdwarf2 }"
     996              : # if defined(DWARF2_DEBUGGING_INFO)
     997              : #   define ASM_DEBUG_OPTION_SPEC "%{g*:%{%:debug-level-gt(0):" \
     998              :         ASM_DEBUG_OPTION_DWARF_OPT "}}"
     999              : #  endif
    1000              : # endif
    1001              : #endif
    1002              : #ifndef ASM_DEBUG_OPTION_SPEC
    1003              : # define ASM_DEBUG_OPTION_SPEC ""
    1004              : #endif
    1005              : 
    1006              : /* Here is the spec for running the linker, after compiling all files.  */
    1007              : 
    1008              : #if defined(TARGET_PROVIDES_LIBATOMIC) && defined(USE_LD_AS_NEEDED)
    1009              : #ifdef USE_LD_AS_NEEDED_LDSCRIPT
    1010              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:-latomic_asneeded} "
    1011              : #else
    1012              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:" LD_AS_NEEDED_OPTION \
    1013              :                             " -latomic " LD_NO_AS_NEEDED_OPTION "} "
    1014              : #endif
    1015              : #else
    1016              : #define LINK_LIBATOMIC_SPEC ""
    1017              : #endif
    1018              : 
    1019              : /* This is overridable by the target in case they need to specify the
    1020              :    -lgcc and -lc order specially, yet not require them to override all
    1021              :    of LINK_COMMAND_SPEC.  */
    1022              : #ifndef LINK_GCC_C_SEQUENCE_SPEC
    1023              : #define LINK_GCC_C_SEQUENCE_SPEC "%G %{!nolibc:%L %G}"
    1024              : #endif
    1025              : 
    1026              : #ifndef LINK_SSP_SPEC
    1027              : #ifdef TARGET_LIBC_PROVIDES_SSP
    1028              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1029              :                        "|fstack-protector-strong|fstack-protector-explicit:}"
    1030              : #else
    1031              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1032              :                        "|fstack-protector-strong|fstack-protector-explicit" \
    1033              :                        ":-lssp_nonshared -lssp}"
    1034              : #endif
    1035              : #endif
    1036              : 
    1037              : #ifdef ENABLE_DEFAULT_PIE
    1038              : #define PIE_SPEC                "!no-pie"
    1039              : #define NO_FPIE1_SPEC           "fno-pie"
    1040              : #define FPIE1_SPEC              NO_FPIE1_SPEC ":;"
    1041              : #define NO_FPIE2_SPEC           "fno-PIE"
    1042              : #define FPIE2_SPEC              NO_FPIE2_SPEC ":;"
    1043              : #define NO_FPIE_SPEC            NO_FPIE1_SPEC "|" NO_FPIE2_SPEC
    1044              : #define FPIE_SPEC               NO_FPIE_SPEC ":;"
    1045              : #define NO_FPIC1_SPEC           "fno-pic"
    1046              : #define FPIC1_SPEC              NO_FPIC1_SPEC ":;"
    1047              : #define NO_FPIC2_SPEC           "fno-PIC"
    1048              : #define FPIC2_SPEC              NO_FPIC2_SPEC ":;"
    1049              : #define NO_FPIC_SPEC            NO_FPIC1_SPEC "|" NO_FPIC2_SPEC
    1050              : #define FPIC_SPEC               NO_FPIC_SPEC ":;"
    1051              : #define NO_FPIE1_AND_FPIC1_SPEC NO_FPIE1_SPEC "|" NO_FPIC1_SPEC
    1052              : #define FPIE1_OR_FPIC1_SPEC     NO_FPIE1_AND_FPIC1_SPEC ":;"
    1053              : #define NO_FPIE2_AND_FPIC2_SPEC NO_FPIE2_SPEC "|" NO_FPIC2_SPEC
    1054              : #define FPIE2_OR_FPIC2_SPEC     NO_FPIE2_AND_FPIC2_SPEC ":;"
    1055              : #define NO_FPIE_AND_FPIC_SPEC   NO_FPIE_SPEC "|" NO_FPIC_SPEC
    1056              : #define FPIE_OR_FPIC_SPEC       NO_FPIE_AND_FPIC_SPEC ":;"
    1057              : #else
    1058              : #define PIE_SPEC                "pie"
    1059              : #define FPIE1_SPEC              "fpie"
    1060              : #define NO_FPIE1_SPEC           FPIE1_SPEC ":;"
    1061              : #define FPIE2_SPEC              "fPIE"
    1062              : #define NO_FPIE2_SPEC           FPIE2_SPEC ":;"
    1063              : #define FPIE_SPEC               FPIE1_SPEC "|" FPIE2_SPEC
    1064              : #define NO_FPIE_SPEC            FPIE_SPEC ":;"
    1065              : #define FPIC1_SPEC              "fpic"
    1066              : #define NO_FPIC1_SPEC           FPIC1_SPEC ":;"
    1067              : #define FPIC2_SPEC              "fPIC"
    1068              : #define NO_FPIC2_SPEC           FPIC2_SPEC ":;"
    1069              : #define FPIC_SPEC               FPIC1_SPEC "|" FPIC2_SPEC
    1070              : #define NO_FPIC_SPEC            FPIC_SPEC ":;"
    1071              : #define FPIE1_OR_FPIC1_SPEC     FPIE1_SPEC "|" FPIC1_SPEC
    1072              : #define NO_FPIE1_AND_FPIC1_SPEC FPIE1_OR_FPIC1_SPEC ":;"
    1073              : #define FPIE2_OR_FPIC2_SPEC     FPIE2_SPEC "|" FPIC2_SPEC
    1074              : #define NO_FPIE2_AND_FPIC2_SPEC FPIE1_OR_FPIC2_SPEC ":;"
    1075              : #define FPIE_OR_FPIC_SPEC       FPIE_SPEC "|" FPIC_SPEC
    1076              : #define NO_FPIE_AND_FPIC_SPEC   FPIE_OR_FPIC_SPEC ":;"
    1077              : #endif
    1078              : 
    1079              : #ifndef LINK_PIE_SPEC
    1080              : #ifdef HAVE_LD_PIE
    1081              : #ifndef LD_PIE_SPEC
    1082              : #define LD_PIE_SPEC "-pie"
    1083              : #endif
    1084              : #else
    1085              : #define LD_PIE_SPEC ""
    1086              : #endif
    1087              : #define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} "
    1088              : #endif
    1089              : 
    1090              : #ifndef LINK_BUILDID_SPEC
    1091              : # if defined(HAVE_LD_BUILDID) && defined(ENABLE_LD_BUILDID)
    1092              : #  define LINK_BUILDID_SPEC "%{!r:--build-id} "
    1093              : # endif
    1094              : #endif
    1095              : 
    1096              : #ifndef LTO_PLUGIN_SPEC
    1097              : #define LTO_PLUGIN_SPEC ""
    1098              : #endif
    1099              : 
    1100              : /* Conditional to test whether the LTO plugin is used or not.
    1101              :    FIXME: For slim LTO we will need to enable plugin unconditionally.  This
    1102              :    still cause problems with PLUGIN_LD != LD and when plugin is built but
    1103              :    not usable.  For GCC 4.6 we don't support slim LTO and thus we can enable
    1104              :    plugin only when LTO is enabled.  We still honor explicit
    1105              :    -fuse-linker-plugin if the linker used understands -plugin.  */
    1106              : 
    1107              : /* The linker has some plugin support.  */
    1108              : #if HAVE_LTO_PLUGIN > 0
    1109              : /* The linker used has full plugin support, use LTO plugin by default.  */
    1110              : #if HAVE_LTO_PLUGIN == 2
    1111              : #define PLUGIN_COND "!fno-use-linker-plugin:%{!fno-lto"
    1112              : #define PLUGIN_COND_CLOSE "}"
    1113              : #else
    1114              : /* The linker used has limited plugin support, use LTO plugin with explicit
    1115              :    -fuse-linker-plugin.  */
    1116              : #define PLUGIN_COND "fuse-linker-plugin"
    1117              : #define PLUGIN_COND_CLOSE ""
    1118              : #endif
    1119              : #define LINK_PLUGIN_SPEC \
    1120              :     "%{" PLUGIN_COND": \
    1121              :     -plugin %(linker_plugin_file) \
    1122              :     -plugin-opt=%(lto_wrapper) \
    1123              :     -plugin-opt=-fresolution=%u.res \
    1124              :     " LTO_PLUGIN_SPEC "\
    1125              :     %{flinker-output=*:-plugin-opt=-linker-output-known} \
    1126              :     %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
    1127              :     }" PLUGIN_COND_CLOSE
    1128              : #else
    1129              : /* The linker used doesn't support -plugin, reject -fuse-linker-plugin.  */
    1130              : #define LINK_PLUGIN_SPEC "%{fuse-linker-plugin:\
    1131              :     %e-fuse-linker-plugin is not supported in this configuration}"
    1132              : #endif
    1133              : 
    1134              : /* Linker command line options for -fsanitize= early on the command line.  */
    1135              : #ifndef SANITIZER_EARLY_SPEC
    1136              : #define SANITIZER_EARLY_SPEC "\
    1137              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
    1138              :     %{%:sanitize(hwaddress):" LIBHWASAN_EARLY_SPEC "} \
    1139              :     %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
    1140              :     %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}}"
    1141              : #endif
    1142              : 
    1143              : /* Linker command line options for -fsanitize= late on the command line.  */
    1144              : #ifndef SANITIZER_SPEC
    1145              : #define SANITIZER_SPEC "\
    1146              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
    1147              :     %{static:%ecannot specify -static with -fsanitize=address}}\
    1148              :     %{%:sanitize(hwaddress):" LIBHWASAN_SPEC "\
    1149              :         %{static:%ecannot specify -static with -fsanitize=hwaddress}}\
    1150              :     %{%:sanitize(thread):" LIBTSAN_SPEC "\
    1151              :     %{static:%ecannot specify -static with -fsanitize=thread}}\
    1152              :     %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
    1153              :     %{%:sanitize(leak):" LIBLSAN_SPEC "}}}}"
    1154              : #endif
    1155              : 
    1156              : #ifndef POST_LINK_SPEC
    1157              : #define POST_LINK_SPEC ""
    1158              : #endif
    1159              : 
    1160              : /*  This is the spec to use, once the code for creating the vtable
    1161              :     verification runtime library, libvtv.so, has been created.  Currently
    1162              :     the vtable verification runtime functions are in libstdc++, so we use
    1163              :     the spec just below this one.  */
    1164              : #ifndef VTABLE_VERIFICATION_SPEC
    1165              : #if ENABLE_VTABLE_VERIFY
    1166              : #define VTABLE_VERIFICATION_SPEC "\
    1167              : %{!nostdlib:%{!r:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
    1168              :     %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}}"
    1169              : #else
    1170              : #define VTABLE_VERIFICATION_SPEC "\
    1171              : %{fvtable-verify=none:} \
    1172              : %{fvtable-verify=std: \
    1173              :   %e-fvtable-verify=std is not supported in this configuration} \
    1174              : %{fvtable-verify=preinit: \
    1175              :   %e-fvtable-verify=preinit is not supported in this configuration}"
    1176              : #endif
    1177              : #endif
    1178              : 
    1179              : /* -u* was put back because both BSD and SysV seem to support it.  */
    1180              : /* %{static|no-pie|static-pie:} simply prevents an error message:
    1181              :    1. If the target machine doesn't handle -static.
    1182              :    2. If PIE isn't enabled by default.
    1183              :    3. If the target machine doesn't handle -static-pie.
    1184              :  */
    1185              : /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
    1186              :    scripts which exist in user specified directories, or in standard
    1187              :    directories.  */
    1188              : /* We pass any -flto flags on to the linker, which is expected
    1189              :    to understand them.  In practice, this means it had better be collect2.  */
    1190              : /* %{e*} includes -export-dynamic; see comment in common.opt.  */
    1191              : #ifndef LINK_COMMAND_SPEC
    1192              : #define LINK_COMMAND_SPEC "\
    1193              : %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
    1194              :     %(linker) " \
    1195              :     LINK_PLUGIN_SPEC \
    1196              :    "%{flto|flto=*:%<fcompare-debug*} \
    1197              :     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    1198              :    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    1199              :    "%X %{o*} %{e*} %{N} %{n} %{r}\
    1200              :     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
    1201              :     %{static|no-pie|static-pie:} %@{L*} %(link_libgcc) " \
    1202              :     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o "" \
    1203              :     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
    1204              :         %:include(libgomp.spec)%(link_gomp)}\
    1205              :     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
    1206              :     " STACK_SPLIT_SPEC "\
    1207              :     %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
    1208              :     %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\
    1209              :     %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*}  \n%(post_link) }}}}}}"
    1210              : #endif
    1211              : 
    1212              : #ifndef LINK_LIBGCC_SPEC
    1213              : /* Generate -L options for startfile prefix list.  */
    1214              : # define LINK_LIBGCC_SPEC "%D"
    1215              : #endif
    1216              : 
    1217              : #ifndef STARTFILE_PREFIX_SPEC
    1218              : # define STARTFILE_PREFIX_SPEC ""
    1219              : #endif
    1220              : 
    1221              : #ifndef SYSROOT_SPEC
    1222              : # define SYSROOT_SPEC "--sysroot=%R"
    1223              : #endif
    1224              : 
    1225              : #ifndef SYSROOT_SUFFIX_SPEC
    1226              : # define SYSROOT_SUFFIX_SPEC ""
    1227              : #endif
    1228              : 
    1229              : #ifndef SYSROOT_HEADERS_SUFFIX_SPEC
    1230              : # define SYSROOT_HEADERS_SUFFIX_SPEC ""
    1231              : #endif
    1232              : 
    1233              : #ifndef RUNPATH_OPTION
    1234              : # define RUNPATH_OPTION "-rpath"
    1235              : #endif
    1236              : 
    1237              : static const char *asm_debug = ASM_DEBUG_SPEC;
    1238              : static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC;
    1239              : static const char *cpp_spec = CPP_SPEC LIBC_CPP_SPEC;
    1240              : static const char *cc1_spec = CC1_SPEC OS_CC1_SPEC;
    1241              : static const char *cc1plus_spec = CC1PLUS_SPEC;
    1242              : static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
    1243              : static const char *link_ssp_spec = LINK_SSP_SPEC;
    1244              : static const char *asm_spec = ASM_SPEC;
    1245              : static const char *asm_final_spec = ASM_FINAL_SPEC;
    1246              : static const char *link_spec = LINK_SPEC LIBC_LINK_SPEC;
    1247              : static const char *lib_spec = LIB_SPEC;
    1248              : static const char *link_gomp_spec = "";
    1249              : static const char *libgcc_spec = LIBGCC_SPEC;
    1250              : static const char *endfile_spec = ENDFILE_SPEC;
    1251              : static const char *startfile_spec = STARTFILE_SPEC;
    1252              : static const char *linker_name_spec = LINKER_NAME;
    1253              : static const char *linker_plugin_file_spec = "";
    1254              : static const char *lto_wrapper_spec = "";
    1255              : static const char *lto_gcc_spec = "";
    1256              : static const char *post_link_spec = POST_LINK_SPEC;
    1257              : static const char *link_command_spec = LINK_COMMAND_SPEC;
    1258              : static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
    1259              : static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
    1260              : static const char *sysroot_spec = SYSROOT_SPEC;
    1261              : static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
    1262              : static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
    1263              : static const char *self_spec = "";
    1264              : 
    1265              : /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    1266              :    There should be no need to override these in target dependent files,
    1267              :    but we need to copy them to the specs file so that newer versions
    1268              :    of the GCC driver can correctly drive older tool chains with the
    1269              :    appropriate -B options.  */
    1270              : 
    1271              : /* When cpplib handles traditional preprocessing, get rid of this, and
    1272              :    call cc1 (or cc1obj in objc/lang-specs.h) from the main specs so
    1273              :    that we default the front end language better.  */
    1274              : static const char *trad_capable_cpp =
    1275              : "cc1 -E %{traditional|traditional-cpp:-traditional-cpp}";
    1276              : 
    1277              : /* We don't wrap .d files in %W{} since a missing .d file, and
    1278              :    therefore no dependency entry, confuses make into thinking a .o
    1279              :    file that happens to exist is up-to-date.  */
    1280              : static const char *cpp_unique_options =
    1281              : "%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %@{I*&F*} %{P} %I\
    1282              :  %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
    1283              :  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
    1284              :  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
    1285              :  %{Mmodules} %{Mno-modules}\
    1286              :  %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
    1287              :  %{remap} %{%:debug-level-gt(2):-dD}\
    1288              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1289              :  %{H} %C %{D*&U*&A*} %{i*} %Z %i\
    1290              :  %{E|M|MM:%W{o*}} %{-embed*}\
    1291              :  %{fdeps-format=*:%{!fdeps-file=*:-fdeps-file=%:join(%{!o:%b.ddi}%{o*:%.ddi%*})}}\
    1292              :  %{fdeps-format=*:%{!fdeps-target=*:-fdeps-target=%:join(%{!o:%b.o}%{o*:%.o%*})}}";
    1293              : 
    1294              : /* This contains cpp options which are common with cc1_options and are passed
    1295              :    only when preprocessing only to avoid duplication.  We pass the cc1 spec
    1296              :    options to the preprocessor so that it the cc1 spec may manipulate
    1297              :    options used to set target flags.  Those special target flags settings may
    1298              :    in turn cause preprocessor symbols to be defined specially.  */
    1299              : static const char *cpp_options =
    1300              : "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
    1301              :  %{f*} %{g*:%{%:debug-level-gt(0):%{g*}\
    1302              :  %{!fno-working-directory:-fworking-directory}}} %{O*}\
    1303              :  %{undef} %{save-temps*:-fpch-preprocess}";
    1304              : 
    1305              : /* Pass -d* flags, possibly modifying -dumpdir, -dumpbase et al.
    1306              : 
    1307              :    Make it easy for a language to override the argument for the
    1308              :    %:dumps specs function call.  */
    1309              : #define DUMPS_OPTIONS(EXTS) \
    1310              :   "%<dumpdir %<dumpbase %<dumpbase-ext %{d*} %:dumps(" EXTS ")"
    1311              : 
    1312              : /* This contains cpp options which are not passed when the preprocessor
    1313              :    output will be used by another program.  */
    1314              : static const char *cpp_debug_options = DUMPS_OPTIONS ("");
    1315              : 
    1316              : /* NB: This is shared amongst all front-ends, except for Ada.  */
    1317              : static const char *cc1_options =
    1318              : "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
    1319              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1320              :  %1 %{!Q:-quiet} %(cpp_debug_options) %{m*} %{aux-info*}\
    1321              :  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
    1322              :  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
    1323              :  %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
    1324              :  %{-target-help:--target-help}\
    1325              :  %{-version:--version}\
    1326              :  %{-help=*:--help=%*}\
    1327              :  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %w%b.s}}}\
    1328              :  %{fsyntax-only:-o %j} %{-param*}\
    1329              :  %{coverage:-fprofile-arcs -ftest-coverage}\
    1330              :  %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:\
    1331              :    %{!fprofile-update=single:\
    1332              :      %{pthread:-fprofile-update=prefer-atomic}}}";
    1333              : 
    1334              : static const char *asm_options =
    1335              : "%{-target-help:%:print-asm-header()} "
    1336              : ASM_V_SPEC
    1337              : " %(asm_debug_option)"
    1338              : ASM_COMPRESS_DEBUG_SPEC
    1339              : "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
    1340              : 
    1341              : static const char *invoke_as =
    1342              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1343              : "%{!fwpa*:\
    1344              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1345              :    %{!S:-o %|.s |\n as %(asm_options) %|.s %A }\
    1346              :   }";
    1347              : #else
    1348              : "%{!fwpa*:\
    1349              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1350              :    %{!S:-o %|.s |\n as %(asm_options) %m.s %A }\
    1351              :   }";
    1352              : #endif
    1353              : 
    1354              : /* Some compilers have limits on line lengths, and the multilib_select
    1355              :    and/or multilib_matches strings can be very long, so we build them at
    1356              :    run time.  */
    1357              : static struct obstack multilib_obstack;
    1358              : static const char *multilib_select;
    1359              : static const char *multilib_matches;
    1360              : static const char *multilib_defaults;
    1361              : static const char *multilib_exclusions;
    1362              : static const char *multilib_reuse;
    1363              : 
    1364              : /* Check whether a particular argument is a default argument.  */
    1365              : 
    1366              : #ifndef MULTILIB_DEFAULTS
    1367              : #define MULTILIB_DEFAULTS { "" }
    1368              : #endif
    1369              : 
    1370              : static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
    1371              : 
    1372              : #ifndef DRIVER_SELF_SPECS
    1373              : #define DRIVER_SELF_SPECS ""
    1374              : #endif
    1375              : 
    1376              : /* Linking to libgomp implies pthreads.  This is particularly important
    1377              :    for targets that use different start files and suchlike.  */
    1378              : #ifndef GOMP_SELF_SPECS
    1379              : #define GOMP_SELF_SPECS \
    1380              :   "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): " \
    1381              :   "-pthread}"
    1382              : #endif
    1383              : 
    1384              : /* Likewise for -fgnu-tm.  */
    1385              : #ifndef GTM_SELF_SPECS
    1386              : #define GTM_SELF_SPECS "%{fgnu-tm: -pthread}"
    1387              : #endif
    1388              : 
    1389              : static const char *const driver_self_specs[] = {
    1390              :   "%{fdump-final-insns:-fdump-final-insns=.} %<fdump-final-insns",
    1391              :   DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS,
    1392              :   /* This discards -fmultiflags at the end of self specs processing in the
    1393              :      driver, so that it is effectively Ignored, without actually marking it as
    1394              :      Ignored, which would get it discarded before self specs could remap it.  */
    1395              :   "%<fmultiflags"
    1396              : };
    1397              : 
    1398              : #ifndef OPTION_DEFAULT_SPECS
    1399              : #define OPTION_DEFAULT_SPECS { "", "" }
    1400              : #endif
    1401              : 
    1402              : struct default_spec
    1403              : {
    1404              :   const char *name;
    1405              :   const char *spec;
    1406              : };
    1407              : 
    1408              : static const struct default_spec
    1409              :   option_default_specs[] = { OPTION_DEFAULT_SPECS };
    1410              : 
    1411              : struct user_specs
    1412              : {
    1413              :   struct user_specs *next;
    1414              :   const char *filename;
    1415              : };
    1416              : 
    1417              : static struct user_specs *user_specs_head, *user_specs_tail;
    1418              : 
    1419              : 
    1420              : /* Record the mapping from file suffixes for compilation specs.  */
    1421              : 
    1422              : struct compiler
    1423              : {
    1424              :   const char *suffix;           /* Use this compiler for input files
    1425              :                                    whose names end in this suffix.  */
    1426              : 
    1427              :   const char *spec;             /* To use this compiler, run this spec.  */
    1428              : 
    1429              :   const char *cpp_spec;         /* If non-NULL, substitute this spec
    1430              :                                    for `%C', rather than the usual
    1431              :                                    cpp_spec.  */
    1432              :   int combinable;               /* If nonzero, compiler can deal with
    1433              :                                     multiple source files at once (IMA).  */
    1434              :   int needs_preprocessing;       /* If nonzero, source files need to
    1435              :                                     be run through a preprocessor.  */
    1436              : };
    1437              : 
    1438              : /* Pointer to a vector of `struct compiler' that gives the spec for
    1439              :    compiling a file, based on its suffix.
    1440              :    A file that does not end in any of these suffixes will be passed
    1441              :    unchanged to the loader and nothing else will be done to it.
    1442              : 
    1443              :    An entry containing two 0s is used to terminate the vector.
    1444              : 
    1445              :    If multiple entries match a file, the last matching one is used.  */
    1446              : 
    1447              : static struct compiler *compilers;
    1448              : 
    1449              : /* Number of entries in `compilers', not counting the null terminator.  */
    1450              : 
    1451              : static int n_compilers;
    1452              : 
    1453              : /* The default list of file name suffixes and their compilation specs.  */
    1454              : 
    1455              : static const struct compiler default_compilers[] =
    1456              : {
    1457              :   /* Add lists of suffixes of known languages here.  If those languages
    1458              :      were not present when we built the driver, we will hit these copies
    1459              :      and be given a more meaningful error than "file not used since
    1460              :      linking is not done".  */
    1461              :   {".m",  "#Objective-C", 0, 0, 0}, {".mi",  "#Objective-C", 0, 0, 0},
    1462              :   {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
    1463              :   {".mii", "#Objective-C++", 0, 0, 0},
    1464              :   {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
    1465              :   {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
    1466              :   {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
    1467              :   {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
    1468              :   {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
    1469              :   {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
    1470              :   {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
    1471              :   {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0},
    1472              :   {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
    1473              :   {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0},
    1474              :   {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
    1475              :   {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0},
    1476              :   {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0},
    1477              :   {".r", "#Ratfor", 0, 0, 0},
    1478              :   {".go", "#Go", 0, 1, 0},
    1479              :   {".d", "#D", 0, 1, 0}, {".dd", "#D", 0, 1, 0}, {".di", "#D", 0, 1, 0},
    1480              :   {".mod", "#Modula-2", 0, 0, 0}, {".m2i", "#Modula-2", 0, 0, 0},
    1481              :   /* Next come the entries for C.  */
    1482              :   {".c", "@c", 0, 0, 1},
    1483              :   {"@c",
    1484              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1485              :       external preprocessor if -save-temps is given.  */
    1486              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1487              :       %{!E:%{!M:%{!MM:\
    1488              :           %{traditional:\
    1489              : %eGNU C no longer supports -traditional without -E}\
    1490              :       %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1491              :           %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1492              :             cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1493              :           %(cc1_options)}\
    1494              :       %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1495              :           cc1 %(cpp_unique_options) %(cc1_options)}}}\
    1496              :       %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
    1497              :   {"-",
    1498              :    "%{!E:%e-E or -x required when input is from standard input}\
    1499              :     %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
    1500              :   {".h", "@c-header", 0, 0, 0},
    1501              :   {"@c-header",
    1502              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1503              :       external preprocessor if -save-temps is given.  */
    1504              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1505              :       %{!E:%{!M:%{!MM:\
    1506              :           %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1507              :                 %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1508              :                     cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1509              :                         %(cc1_options)\
    1510              :                         %{!fsyntax-only:%{!S:-o %g.s} \
    1511              :                             %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1512              :                                                %W{o*:--output-pch %w%*}}%{!S:%V}}}\
    1513              :           %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1514              :                 cc1 %(cpp_unique_options) %(cc1_options)\
    1515              :                     %{!fsyntax-only:%{!S:-o %g.s} \
    1516              :                         %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1517              :                                            %W{o*:--output-pch %w%*}}%{!S:%V}}}}}}}}", 0, 0, 0},
    1518              :   {".i", "@cpp-output", 0, 0, 0},
    1519              :   {"@cpp-output",
    1520              :    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
    1521              :   {".s", "@assembler", 0, 0, 0},
    1522              :   {"@assembler",
    1523              :    "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
    1524              :   {".sx", "@assembler-with-cpp", 0, 0, 0},
    1525              :   {".S", "@assembler-with-cpp", 0, 0, 0},
    1526              :   {"@assembler-with-cpp",
    1527              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1528              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1529              :       %{E|M|MM:%(cpp_debug_options)}\
    1530              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1531              :        as %(asm_debug) %(asm_options) %|.s %A }}}}"
    1532              : #else
    1533              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1534              :       %{E|M|MM:%(cpp_debug_options)}\
    1535              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1536              :        as %(asm_debug) %(asm_options) %m.s %A }}}}"
    1537              : #endif
    1538              :    , 0, 0, 0},
    1539              : 
    1540              : #ifndef EXTRA_DEFAULT_COMPILERS
    1541              : #define EXTRA_DEFAULT_COMPILERS
    1542              : #endif
    1543              :   EXTRA_DEFAULT_COMPILERS
    1544              : 
    1545              : #include "specs.h"
    1546              :   /* Mark end of table.  */
    1547              :   {0, 0, 0, 0, 0}
    1548              : };
    1549              : 
    1550              : /* Number of elements in default_compilers, not counting the terminator.  */
    1551              : 
    1552              : static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
    1553              : 
    1554              : typedef char *char_p; /* For DEF_VEC_P.  */
    1555              : 
    1556              : /* A vector of options to give to the linker.
    1557              :    These options are accumulated by %x,
    1558              :    and substituted into the linker command with %X.  */
    1559              : static vec<char_p> linker_options;
    1560              : 
    1561              : /* A vector of options to give to the assembler.
    1562              :    These options are accumulated by -Wa,
    1563              :    and substituted into the assembler command with %Y.  */
    1564              : static vec<char_p> assembler_options;
    1565              : 
    1566              : /* A vector of options to give to the preprocessor.
    1567              :    These options are accumulated by -Wp,
    1568              :    and substituted into the preprocessor command with %Z.  */
    1569              : static vec<char_p> preprocessor_options;
    1570              : 
    1571              : static char *
    1572     28868184 : skip_whitespace (char *p)
    1573              : {
    1574     66906825 :   while (1)
    1575              :     {
    1576              :       /* A fully-blank line is a delimiter in the SPEC file and shouldn't
    1577              :          be considered whitespace.  */
    1578     66906825 :       if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
    1579      4843776 :         return p + 1;
    1580     62063049 :       else if (*p == '\n' || *p == ' ' || *p == '\t')
    1581     37918946 :         p++;
    1582     24144103 :       else if (*p == '#')
    1583              :         {
    1584      3718615 :           while (*p != '\n')
    1585      3598920 :             p++;
    1586       119695 :           p++;
    1587              :         }
    1588              :       else
    1589              :         break;
    1590              :     }
    1591              : 
    1592              :   return p;
    1593              : }
    1594              : /* Structures to keep track of prefixes to try when looking for files.  */
    1595              : 
    1596              : struct prefix_list
    1597              : {
    1598              :   const char *prefix;         /* String to prepend to the path.  */
    1599              :   struct prefix_list *next;   /* Next in linked list.  */
    1600              :   int require_machine_suffix; /* Don't use without machine_suffix.  */
    1601              :   /* 2 means try both machine_suffix and just_machine_suffix.  */
    1602              :   int priority;               /* Sort key - priority within list.  */
    1603              :   int os_multilib;            /* 1 if OS multilib scheme should be used,
    1604              :                                  0 for GCC multilib scheme.  */
    1605              : };
    1606              : 
    1607              : struct path_prefix
    1608              : {
    1609              :   struct prefix_list *plist;  /* List of prefixes to try */
    1610              :   int max_len;                /* Max length of a prefix in PLIST */
    1611              :   const char *name;           /* Name of this list (used in config stuff) */
    1612              : };
    1613              : 
    1614              : /* List of prefixes to try when looking for executables.  */
    1615              : 
    1616              : static struct path_prefix exec_prefixes = { 0, 0, "exec" };
    1617              : 
    1618              : /* List of prefixes to try when looking for startup (crt0) files.  */
    1619              : 
    1620              : static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };
    1621              : 
    1622              : /* List of prefixes to try when looking for include files.  */
    1623              : 
    1624              : static struct path_prefix include_prefixes = { 0, 0, "include" };
    1625              : 
    1626              : /* Suffix to attach to directories searched for commands.
    1627              :    This looks like `MACHINE/VERSION/'.  */
    1628              : 
    1629              : static const char *machine_suffix = 0;
    1630              : 
    1631              : /* Suffix to attach to directories searched for commands.
    1632              :    This is just `MACHINE/'.  */
    1633              : 
    1634              : static const char *just_machine_suffix = 0;
    1635              : 
    1636              : /* Prefix to attach to *basename* of commands being searched.
    1637              :    This is just `MACHINE-'.  */
    1638              : 
    1639              : static const char *just_machine_prefix = 0;
    1640              : 
    1641              : /* Adjusted value of GCC_EXEC_PREFIX envvar.  */
    1642              : 
    1643              : static const char *gcc_exec_prefix;
    1644              : 
    1645              : /* Adjusted value of standard_libexec_prefix.  */
    1646              : 
    1647              : static const char *gcc_libexec_prefix;
    1648              : 
    1649              : /* Default prefixes to attach to command names.  */
    1650              : 
    1651              : #ifndef STANDARD_STARTFILE_PREFIX_1
    1652              : #define STANDARD_STARTFILE_PREFIX_1 "/lib/"
    1653              : #endif
    1654              : #ifndef STANDARD_STARTFILE_PREFIX_2
    1655              : #define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
    1656              : #endif
    1657              : 
    1658              : #ifdef CROSS_DIRECTORY_STRUCTURE  /* Don't use these prefixes for a cross compiler.  */
    1659              : #undef MD_EXEC_PREFIX
    1660              : #undef MD_STARTFILE_PREFIX
    1661              : #undef MD_STARTFILE_PREFIX_1
    1662              : #endif
    1663              : 
    1664              : /* If no prefixes defined, use the null string, which will disable them.  */
    1665              : #ifndef MD_EXEC_PREFIX
    1666              : #define MD_EXEC_PREFIX ""
    1667              : #endif
    1668              : #ifndef MD_STARTFILE_PREFIX
    1669              : #define MD_STARTFILE_PREFIX ""
    1670              : #endif
    1671              : #ifndef MD_STARTFILE_PREFIX_1
    1672              : #define MD_STARTFILE_PREFIX_1 ""
    1673              : #endif
    1674              : 
    1675              : /* These directories are locations set at configure-time based on the
    1676              :    --prefix option provided to configure.  Their initializers are
    1677              :    defined in Makefile.in.  These paths are not *directly* used when
    1678              :    gcc_exec_prefix is set because, in that case, we know where the
    1679              :    compiler has been installed, and use paths relative to that
    1680              :    location instead.  */
    1681              : static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
    1682              : static const char *const standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
    1683              : static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
    1684              : static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
    1685              : 
    1686              : /* For native compilers, these are well-known paths containing
    1687              :    components that may be provided by the system.  For cross
    1688              :    compilers, these paths are not used.  */
    1689              : static const char *md_exec_prefix = MD_EXEC_PREFIX;
    1690              : static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
    1691              : static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
    1692              : static const char *const standard_startfile_prefix_1
    1693              :   = STANDARD_STARTFILE_PREFIX_1;
    1694              : static const char *const standard_startfile_prefix_2
    1695              :   = STANDARD_STARTFILE_PREFIX_2;
    1696              : 
    1697              : /* A relative path to be used in finding the location of tools
    1698              :    relative to the driver.  */
    1699              : static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
    1700              : 
    1701              : /* A prefix to be used when this is an accelerator compiler.  */
    1702              : static const char *const accel_dir_suffix = ACCEL_DIR_SUFFIX;
    1703              : 
    1704              : /* Subdirectory to use for locating libraries.  Set by
    1705              :    set_multilib_dir based on the compilation options.  */
    1706              : 
    1707              : static const char *multilib_dir;
    1708              : 
    1709              : /* Subdirectory to use for locating libraries in OS conventions.  Set by
    1710              :    set_multilib_dir based on the compilation options.  */
    1711              : 
    1712              : static const char *multilib_os_dir;
    1713              : 
    1714              : /* Subdirectory to use for locating libraries in multiarch conventions.  Set by
    1715              :    set_multilib_dir based on the compilation options.  */
    1716              : 
    1717              : static const char *multiarch_dir;
    1718              : 
    1719              : /* Structure to keep track of the specs that have been defined so far.
    1720              :    These are accessed using %(specname) in a compiler or link
    1721              :    spec.  */
    1722              : 
    1723              : struct spec_list
    1724              : {
    1725              :                                 /* The following 2 fields must be first */
    1726              :                                 /* to allow EXTRA_SPECS to be initialized */
    1727              :   const char *name;             /* name of the spec.  */
    1728              :   const char *ptr;              /* available ptr if no static pointer */
    1729              : 
    1730              :                                 /* The following fields are not initialized */
    1731              :                                 /* by EXTRA_SPECS */
    1732              :   const char **ptr_spec;        /* pointer to the spec itself.  */
    1733              :   struct spec_list *next;       /* Next spec in linked list.  */
    1734              :   int name_len;                 /* length of the name */
    1735              :   bool user_p;                  /* whether string come from file spec.  */
    1736              :   bool alloc_p;                 /* whether string was allocated */
    1737              :   const char *default_ptr;      /* The default value of *ptr_spec.  */
    1738              : };
    1739              : 
    1740              : #define INIT_STATIC_SPEC(NAME,PTR) \
    1741              :   { NAME, NULL, PTR, (struct spec_list *) 0, sizeof (NAME) - 1, false, false, \
    1742              :     *PTR }
    1743              : 
    1744              : /* List of statically defined specs.  */
    1745              : static struct spec_list static_specs[] =
    1746              : {
    1747              :   INIT_STATIC_SPEC ("asm",                    &asm_spec),
    1748              :   INIT_STATIC_SPEC ("asm_debug",              &asm_debug),
    1749              :   INIT_STATIC_SPEC ("asm_debug_option",               &asm_debug_option),
    1750              :   INIT_STATIC_SPEC ("asm_final",              &asm_final_spec),
    1751              :   INIT_STATIC_SPEC ("asm_options",            &asm_options),
    1752              :   INIT_STATIC_SPEC ("invoke_as",              &invoke_as),
    1753              :   INIT_STATIC_SPEC ("cpp",                    &cpp_spec),
    1754              :   INIT_STATIC_SPEC ("cpp_options",            &cpp_options),
    1755              :   INIT_STATIC_SPEC ("cpp_debug_options",      &cpp_debug_options),
    1756              :   INIT_STATIC_SPEC ("cpp_unique_options",     &cpp_unique_options),
    1757              :   INIT_STATIC_SPEC ("trad_capable_cpp",               &trad_capable_cpp),
    1758              :   INIT_STATIC_SPEC ("cc1",                    &cc1_spec),
    1759              :   INIT_STATIC_SPEC ("cc1_options",            &cc1_options),
    1760              :   INIT_STATIC_SPEC ("cc1plus",                        &cc1plus_spec),
    1761              :   INIT_STATIC_SPEC ("link_gcc_c_sequence",    &link_gcc_c_sequence_spec),
    1762              :   INIT_STATIC_SPEC ("link_ssp",                       &link_ssp_spec),
    1763              :   INIT_STATIC_SPEC ("endfile",                        &endfile_spec),
    1764              :   INIT_STATIC_SPEC ("link",                   &link_spec),
    1765              :   INIT_STATIC_SPEC ("lib",                    &lib_spec),
    1766              :   INIT_STATIC_SPEC ("link_gomp",              &link_gomp_spec),
    1767              :   INIT_STATIC_SPEC ("libgcc",                 &libgcc_spec),
    1768              :   INIT_STATIC_SPEC ("startfile",              &startfile_spec),
    1769              :   INIT_STATIC_SPEC ("cross_compile",          &cross_compile),
    1770              :   INIT_STATIC_SPEC ("version",                        &compiler_version),
    1771              :   INIT_STATIC_SPEC ("multilib",                       &multilib_select),
    1772              :   INIT_STATIC_SPEC ("multilib_defaults",      &multilib_defaults),
    1773              :   INIT_STATIC_SPEC ("multilib_extra",         &multilib_extra),
    1774              :   INIT_STATIC_SPEC ("multilib_matches",               &multilib_matches),
    1775              :   INIT_STATIC_SPEC ("multilib_exclusions",    &multilib_exclusions),
    1776              :   INIT_STATIC_SPEC ("multilib_options",               &multilib_options),
    1777              :   INIT_STATIC_SPEC ("multilib_reuse",         &multilib_reuse),
    1778              :   INIT_STATIC_SPEC ("linker",                 &linker_name_spec),
    1779              :   INIT_STATIC_SPEC ("linker_plugin_file",     &linker_plugin_file_spec),
    1780              :   INIT_STATIC_SPEC ("lto_wrapper",            &lto_wrapper_spec),
    1781              :   INIT_STATIC_SPEC ("lto_gcc",                        &lto_gcc_spec),
    1782              :   INIT_STATIC_SPEC ("post_link",              &post_link_spec),
    1783              :   INIT_STATIC_SPEC ("link_libgcc",            &link_libgcc_spec),
    1784              :   INIT_STATIC_SPEC ("md_exec_prefix",         &md_exec_prefix),
    1785              :   INIT_STATIC_SPEC ("md_startfile_prefix",    &md_startfile_prefix),
    1786              :   INIT_STATIC_SPEC ("md_startfile_prefix_1",  &md_startfile_prefix_1),
    1787              :   INIT_STATIC_SPEC ("startfile_prefix_spec",  &startfile_prefix_spec),
    1788              :   INIT_STATIC_SPEC ("sysroot_spec",             &sysroot_spec),
    1789              :   INIT_STATIC_SPEC ("sysroot_suffix_spec",    &sysroot_suffix_spec),
    1790              :   INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec",       &sysroot_hdrs_suffix_spec),
    1791              :   INIT_STATIC_SPEC ("self_spec",              &self_spec),
    1792              : };
    1793              : 
    1794              : #ifdef EXTRA_SPECS              /* additional specs needed */
    1795              : /* Structure to keep track of just the first two args of a spec_list.
    1796              :    That is all that the EXTRA_SPECS macro gives us.  */
    1797              : struct spec_list_1
    1798              : {
    1799              :   const char *const name;
    1800              :   const char *const ptr;
    1801              : };
    1802              : 
    1803              : static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
    1804              : static struct spec_list *extra_specs = (struct spec_list *) 0;
    1805              : #endif
    1806              : 
    1807              : /* List of dynamically allocates specs that have been defined so far.  */
    1808              : 
    1809              : static struct spec_list *specs = (struct spec_list *) 0;
    1810              : 
    1811              : /* List of static spec functions.  */
    1812              : 
    1813              : static const struct spec_function static_spec_functions[] =
    1814              : {
    1815              :   { "getenv",                   getenv_spec_function },
    1816              :   { "if-exists",              if_exists_spec_function },
    1817              :   { "if-exists-else",         if_exists_else_spec_function },
    1818              :   { "if-exists-then-else",    if_exists_then_else_spec_function },
    1819              :   { "sanitize",                       sanitize_spec_function },
    1820              :   { "replace-outfile",                replace_outfile_spec_function },
    1821              :   { "remove-outfile",         remove_outfile_spec_function },
    1822              :   { "version-compare",                version_compare_spec_function },
    1823              :   { "include",                        include_spec_function },
    1824              :   { "find-file",              find_file_spec_function },
    1825              :   { "find-plugindir",         find_plugindir_spec_function },
    1826              :   { "print-asm-header",               print_asm_header_spec_function },
    1827              :   { "compare-debug-dump-opt", compare_debug_dump_opt_spec_function },
    1828              :   { "compare-debug-self-opt", compare_debug_self_opt_spec_function },
    1829              :   { "pass-through-libs",      pass_through_libs_spec_func },
    1830              :   { "dumps",                    dumps_spec_func },
    1831              :   { "gt",                     greater_than_spec_func },
    1832              :   { "debug-level-gt",         debug_level_greater_than_spec_func },
    1833              :   { "dwarf-version-gt",               dwarf_version_greater_than_spec_func },
    1834              :   { "fortran-preinclude-file",        find_fortran_preinclude_file},
    1835              :   { "join",                   join_spec_func},
    1836              : #ifdef EXTRA_SPEC_FUNCTIONS
    1837              :   EXTRA_SPEC_FUNCTIONS
    1838              : #endif
    1839              :   { 0, 0 }
    1840              : };
    1841              : 
    1842              : static int processing_spec_function;
    1843              : 
    1844              : /* Add appropriate libgcc specs to OBSTACK, taking into account
    1845              :    various permutations of -shared-libgcc, -shared, and such.  */
    1846              : 
    1847              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1848              : 
    1849              : #ifndef USE_LD_AS_NEEDED
    1850              : #define USE_LD_AS_NEEDED 0
    1851              : #endif
    1852              : 
    1853              : static void
    1854         1102 : init_gcc_specs (struct obstack *obstack, const char *shared_name,
    1855              :                 const char *static_name, const char *eh_name)
    1856              : {
    1857         1102 :   char *buf;
    1858              : 
    1859              : #if USE_LD_AS_NEEDED
    1860              : #if defined(USE_LD_AS_NEEDED_LDSCRIPT) && !defined(USE_LIBUNWIND_EXCEPTIONS)
    1861         1102 :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1862              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1863              :                 "%{!shared-libgcc:",
    1864              :                 static_name, " ",
    1865              :                 shared_name, "_asneeded}"
    1866              :                 "%{shared-libgcc:",
    1867              :                 shared_name, "%{!shared: ", static_name, "}"
    1868              :                 "}}"
    1869              : #else
    1870              :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1871              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1872              :                 "%{!shared-libgcc:",
    1873              :                 static_name, " " LD_AS_NEEDED_OPTION " ",
    1874              :                 shared_name, " " LD_NO_AS_NEEDED_OPTION
    1875              :                 "}"
    1876              :                 "%{shared-libgcc:",
    1877              :                 shared_name, "%{!shared: ", static_name, "}"
    1878              :                 "}}"
    1879              : #endif
    1880              : #else
    1881              :   buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name, "}"
    1882              :                 "%{!static:%{!static-libgcc:"
    1883              :                 "%{!shared:"
    1884              :                 "%{!shared-libgcc:", static_name, " ", eh_name, "}"
    1885              :                 "%{shared-libgcc:", shared_name, " ", static_name, "}"
    1886              :                 "}"
    1887              : #ifdef LINK_EH_SPEC
    1888              :                 "%{shared:"
    1889              :                 "%{shared-libgcc:", shared_name, "}"
    1890              :                 "%{!shared-libgcc:", static_name, "}"
    1891              :                 "}"
    1892              : #else
    1893              :                 "%{shared:", shared_name, "}"
    1894              : #endif
    1895              : #endif
    1896              :                 "}}", NULL);
    1897              : 
    1898         1102 :   obstack_grow (obstack, buf, strlen (buf));
    1899         1102 :   free (buf);
    1900         1102 : }
    1901              : #endif /* ENABLE_SHARED_LIBGCC */
    1902              : 
    1903              : /* Initialize the specs lookup routines.  */
    1904              : 
    1905              : static void
    1906         1102 : init_spec (void)
    1907              : {
    1908         1102 :   struct spec_list *next = (struct spec_list *) 0;
    1909         1102 :   struct spec_list *sl   = (struct spec_list *) 0;
    1910         1102 :   int i;
    1911              : 
    1912         1102 :   if (specs)
    1913              :     return;                     /* Already initialized.  */
    1914              : 
    1915         1102 :   if (verbose_flag)
    1916           55 :     fnotice (stderr, "Using built-in specs.\n");
    1917              : 
    1918              : #ifdef EXTRA_SPECS
    1919         1102 :   extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1));
    1920              : 
    1921         2204 :   for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
    1922              :     {
    1923         1102 :       sl = &extra_specs[i];
    1924         1102 :       sl->name = extra_specs_1[i].name;
    1925         1102 :       sl->ptr = extra_specs_1[i].ptr;
    1926         1102 :       sl->next = next;
    1927         1102 :       sl->name_len = strlen (sl->name);
    1928         1102 :       sl->ptr_spec = &sl->ptr;
    1929         1102 :       gcc_assert (sl->ptr_spec != NULL);
    1930         1102 :       sl->default_ptr = sl->ptr;
    1931         1102 :       next = sl;
    1932              :     }
    1933              : #endif
    1934              : 
    1935        50692 :   for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    1936              :     {
    1937        49590 :       sl = &static_specs[i];
    1938        49590 :       sl->next = next;
    1939        49590 :       next = sl;
    1940              :     }
    1941              : 
    1942              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1943              :   /* ??? If neither -shared-libgcc nor --static-libgcc was
    1944              :      seen, then we should be making an educated guess.  Some proposed
    1945              :      heuristics for ELF include:
    1946              : 
    1947              :         (1) If "-Wl,--export-dynamic", then it's a fair bet that the
    1948              :             program will be doing dynamic loading, which will likely
    1949              :             need the shared libgcc.
    1950              : 
    1951              :         (2) If "-ldl", then it's also a fair bet that we're doing
    1952              :             dynamic loading.
    1953              : 
    1954              :         (3) For each ET_DYN we're linking against (either through -lfoo
    1955              :             or /some/path/foo.so), check to see whether it or one of
    1956              :             its dependencies depends on a shared libgcc.
    1957              : 
    1958              :         (4) If "-shared"
    1959              : 
    1960              :             If the runtime is fixed to look for program headers instead
    1961              :             of calling __register_frame_info at all, for each object,
    1962              :             use the shared libgcc if any EH symbol referenced.
    1963              : 
    1964              :             If crtstuff is fixed to not invoke __register_frame_info
    1965              :             automatically, for each object, use the shared libgcc if
    1966              :             any non-empty unwind section found.
    1967              : 
    1968              :      Doing any of this probably requires invoking an external program to
    1969              :      do the actual object file scanning.  */
    1970         1102 :   {
    1971         1102 :     const char *p = libgcc_spec;
    1972         1102 :     int in_sep = 1;
    1973              : 
    1974              :     /* Transform the extant libgcc_spec into one that uses the shared libgcc
    1975              :        when given the proper command line arguments.  */
    1976         2204 :     while (*p)
    1977              :       {
    1978         1102 :         if (in_sep && *p == '-' && startswith (p, "-lgcc"))
    1979              :           {
    1980         1102 :             init_gcc_specs (&obstack,
    1981              :                             "-lgcc_s"
    1982              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1983              :                             " -lunwind"
    1984              : #endif
    1985              :                             ,
    1986              :                             "-lgcc",
    1987              :                             "-lgcc_eh"
    1988              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1989              : # ifdef HAVE_LD_STATIC_DYNAMIC
    1990              :                             " %{!static:%{!static-pie:" LD_STATIC_OPTION "}} -lunwind"
    1991              :                             " %{!static:%{!static-pie:" LD_DYNAMIC_OPTION "}}"
    1992              : # else
    1993              :                             " -lunwind"
    1994              : # endif
    1995              : #endif
    1996              :                             );
    1997              : 
    1998         1102 :             p += 5;
    1999         1102 :             in_sep = 0;
    2000              :           }
    2001            0 :         else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
    2002              :           {
    2003              :             /* Ug.  We don't know shared library extensions.  Hope that
    2004              :                systems that use this form don't do shared libraries.  */
    2005            0 :             init_gcc_specs (&obstack,
    2006              :                             "-lgcc_s",
    2007              :                             "libgcc.a%s",
    2008              :                             "libgcc_eh.a%s"
    2009              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    2010              :                             " -lunwind"
    2011              : #endif
    2012              :                             );
    2013            0 :             p += 10;
    2014            0 :             in_sep = 0;
    2015              :           }
    2016              :         else
    2017              :           {
    2018            0 :             obstack_1grow (&obstack, *p);
    2019            0 :             in_sep = (*p == ' ');
    2020            0 :             p += 1;
    2021              :           }
    2022              :       }
    2023              : 
    2024         1102 :     obstack_1grow (&obstack, '\0');
    2025         1102 :     libgcc_spec = XOBFINISH (&obstack, const char *);
    2026              :   }
    2027              : #endif
    2028              : #ifdef USE_AS_TRADITIONAL_FORMAT
    2029              :   /* Prepend "--traditional-format" to whatever asm_spec we had before.  */
    2030              :   {
    2031              :     static const char tf[] = "--traditional-format ";
    2032              :     obstack_grow (&obstack, tf, sizeof (tf) - 1);
    2033              :     obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
    2034              :     asm_spec = XOBFINISH (&obstack, const char *);
    2035              :   }
    2036              : #endif
    2037              : 
    2038              : #if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC || \
    2039              :     defined LINKER_HASH_STYLE
    2040              : # ifdef LINK_BUILDID_SPEC
    2041              :   /* Prepend LINK_BUILDID_SPEC to whatever link_spec we had before.  */
    2042              :   obstack_grow (&obstack, LINK_BUILDID_SPEC, sizeof (LINK_BUILDID_SPEC) - 1);
    2043              : # endif
    2044              : # ifdef LINK_EH_SPEC
    2045              :   /* Prepend LINK_EH_SPEC to whatever link_spec we had before.  */
    2046         1102 :   obstack_grow (&obstack, LINK_EH_SPEC, sizeof (LINK_EH_SPEC) - 1);
    2047              : # endif
    2048              : # ifdef LINKER_HASH_STYLE
    2049              :   /* Prepend --hash-style=LINKER_HASH_STYLE to whatever link_spec we had
    2050              :      before.  */
    2051              :   {
    2052              :     static const char hash_style[] = "--hash-style=";
    2053              :     obstack_grow (&obstack, hash_style, sizeof (hash_style) - 1);
    2054              :     obstack_grow (&obstack, LINKER_HASH_STYLE, sizeof (LINKER_HASH_STYLE) - 1);
    2055              :     obstack_1grow (&obstack, ' ');
    2056              :   }
    2057              : # endif
    2058         1102 :   obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    2059         1102 :   link_spec = XOBFINISH (&obstack, const char *);
    2060              : #endif
    2061              : 
    2062         1102 :   specs = sl;
    2063              : }
    2064              : 
    2065              : /* Update the entry for SPEC in the static_specs table to point to VALUE,
    2066              :    ensuring that we free the previous value if necessary.  Set alloc_p for the
    2067              :    entry to ALLOC_P: this determines whether we take ownership of VALUE (i.e.
    2068              :    whether we need to free it later on).  */
    2069              : static void
    2070       210860 : set_static_spec (const char **spec, const char *value, bool alloc_p)
    2071              : {
    2072       210860 :   struct spec_list *sl = NULL;
    2073              : 
    2074      7280403 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
    2075              :     {
    2076      7280403 :       if (static_specs[i].ptr_spec == spec)
    2077              :         {
    2078       210860 :           sl = static_specs + i;
    2079       210860 :           break;
    2080              :         }
    2081              :     }
    2082              : 
    2083            0 :   gcc_assert (sl);
    2084              : 
    2085       210860 :   if (sl->alloc_p)
    2086              :     {
    2087       210860 :       const char *old = *spec;
    2088       210860 :       free (const_cast <char *> (old));
    2089              :     }
    2090              : 
    2091       210860 :   *spec = value;
    2092       210860 :   sl->alloc_p = alloc_p;
    2093       210860 : }
    2094              : 
    2095              : /* Update a static spec to a new string, taking ownership of that
    2096              :    string's memory.  */
    2097       110008 : static void set_static_spec_owned (const char **spec, const char *val)
    2098              : {
    2099            0 :   return set_static_spec (spec, val, true);
    2100              : }
    2101              : 
    2102              : /* Update a static spec to point to a new value, but don't take
    2103              :    ownership of (i.e. don't free) that string.  */
    2104       100852 : static void set_static_spec_shared (const char **spec, const char *val)
    2105              : {
    2106            0 :   return set_static_spec (spec, val, false);
    2107              : }
    2108              : 
    2109              : 
    2110              : /* Change the value of spec NAME to SPEC.  If SPEC is empty, then the spec is
    2111              :    removed; If the spec starts with a + then SPEC is added to the end of the
    2112              :    current spec.  */
    2113              : 
    2114              : static void
    2115     13975024 : set_spec (const char *name, const char *spec, bool user_p)
    2116              : {
    2117     13975024 :   struct spec_list *sl;
    2118     13975024 :   const char *old_spec;
    2119     13975024 :   int name_len = strlen (name);
    2120     13975024 :   int i;
    2121              : 
    2122              :   /* If this is the first call, initialize the statically allocated specs.  */
    2123     13975024 :   if (!specs)
    2124              :     {
    2125              :       struct spec_list *next = (struct spec_list *) 0;
    2126     13925856 :       for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    2127              :         {
    2128     13623120 :           sl = &static_specs[i];
    2129     13623120 :           sl->next = next;
    2130     13623120 :           next = sl;
    2131              :         }
    2132       302736 :       specs = sl;
    2133              :     }
    2134              : 
    2135              :   /* See if the spec already exists.  */
    2136    328851030 :   for (sl = specs; sl; sl = sl->next)
    2137    328526726 :     if (name_len == sl->name_len && !strcmp (sl->name, name))
    2138              :       break;
    2139              : 
    2140     13975024 :   if (!sl)
    2141              :     {
    2142              :       /* Not found - make it.  */
    2143       324304 :       sl = XNEW (struct spec_list);
    2144       324304 :       sl->name = xstrdup (name);
    2145       324304 :       sl->name_len = name_len;
    2146       324304 :       sl->ptr_spec = &sl->ptr;
    2147       324304 :       sl->alloc_p = 0;
    2148       324304 :       *(sl->ptr_spec) = "";
    2149       324304 :       sl->next = specs;
    2150       324304 :       sl->default_ptr = NULL;
    2151       324304 :       specs = sl;
    2152              :     }
    2153              : 
    2154     13975024 :   old_spec = *(sl->ptr_spec);
    2155     13975024 :   *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
    2156            1 :                      ? concat (old_spec, spec + 1, NULL)
    2157     13975023 :                      : xstrdup (spec));
    2158              : 
    2159              : #ifdef DEBUG_SPECS
    2160              :   if (verbose_flag)
    2161              :     fnotice (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
    2162              : #endif
    2163              : 
    2164              :   /* Free the old spec.  */
    2165     13975024 :   if (old_spec && sl->alloc_p)
    2166         6125 :     free (const_cast<char *> (old_spec));
    2167              : 
    2168     13975024 :   sl->user_p = user_p;
    2169     13975024 :   sl->alloc_p = true;
    2170     13975024 : }
    2171              : 
    2172              : /* Accumulate a command (program name and args), and run it.  */
    2173              : 
    2174              : typedef const char *const_char_p; /* For DEF_VEC_P.  */
    2175              : 
    2176              : /* Vector of pointers to arguments in the current line of specifications.  */
    2177              : static vec<const_char_p> argbuf;
    2178              : 
    2179              : /* Likewise, but for the current @file.  */
    2180              : static vec<const_char_p> at_file_argbuf;
    2181              : 
    2182              : /* Whether an @file is currently open.  */
    2183              : static bool in_at_file = false;
    2184              : 
    2185              : /* Were the options -c, -S or -E passed.  */
    2186              : static int have_c = 0;
    2187              : 
    2188              : /* Was the option -o passed.  */
    2189              : static int have_o = 0;
    2190              : 
    2191              : /* Was the option -E passed.  */
    2192              : static int have_E = 0;
    2193              : 
    2194              : /* Pointer to output file name passed in with -o. */
    2195              : static const char *output_file = 0;
    2196              : 
    2197              : /* Pointer to input file name passed in with -truncate.
    2198              :    This file should be truncated after linking. */
    2199              : static const char *totruncate_file = 0;
    2200              : 
    2201              : /* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
    2202              :    temp file.  If the HOST_BIT_BUCKET is used for %j, no entry is made for
    2203              :    it here.  */
    2204              : 
    2205              : static struct temp_name {
    2206              :   const char *suffix;   /* suffix associated with the code.  */
    2207              :   int length;           /* strlen (suffix).  */
    2208              :   int unique;           /* Indicates whether %g or %u/%U was used.  */
    2209              :   const char *filename; /* associated filename.  */
    2210              :   int filename_length;  /* strlen (filename).  */
    2211              :   struct temp_name *next;
    2212              : } *temp_names;
    2213              : 
    2214              : /* Number of commands executed so far.  */
    2215              : 
    2216              : static int execution_count;
    2217              : 
    2218              : /* Number of commands that exited with a signal.  */
    2219              : 
    2220              : static int signal_count;
    2221              : 
    2222              : /* Allocate the argument vector.  */
    2223              : 
    2224              : static void
    2225      2399347 : alloc_args (void)
    2226              : {
    2227      2399347 :   argbuf.create (10);
    2228      2399347 :   at_file_argbuf.create (10);
    2229      2399347 : }
    2230              : 
    2231              : /* Clear out the vector of arguments (after a command is executed).  */
    2232              : 
    2233              : static void
    2234      5667579 : clear_args (void)
    2235              : {
    2236      5667579 :   argbuf.truncate (0);
    2237      5667579 :   at_file_argbuf.truncate (0);
    2238      5667579 : }
    2239              : 
    2240              : /* Add one argument to the vector at the end.
    2241              :    This is done when a space is seen or at the end of the line.
    2242              :    If DELETE_ALWAYS is nonzero, the arg is a filename
    2243              :     and the file should be deleted eventually.
    2244              :    If DELETE_FAILURE is nonzero, the arg is a filename
    2245              :     and the file should be deleted if this compilation fails.  */
    2246              : 
    2247              : static void
    2248     19624197 : store_arg (const char *arg, int delete_always, int delete_failure)
    2249              : {
    2250     19624197 :   if (in_at_file)
    2251        13366 :     at_file_argbuf.safe_push (arg);
    2252              :   else
    2253     19610831 :     argbuf.safe_push (arg);
    2254              : 
    2255     19624197 :   if (delete_always || delete_failure)
    2256              :     {
    2257       524997 :       const char *p;
    2258              :       /* If the temporary file we should delete is specified as
    2259              :          part of a joined argument extract the filename.  */
    2260       524997 :       if (arg[0] == '-'
    2261       524997 :           && (p = strrchr (arg, '=')))
    2262        91645 :         arg = p + 1;
    2263       524997 :       record_temp_file (arg, delete_always, delete_failure);
    2264              :     }
    2265     19624197 : }
    2266              : 
    2267              : /* Open a temporary @file into which subsequent arguments will be stored.  */
    2268              : 
    2269              : static void
    2270        12360 : open_at_file (void)
    2271              : {
    2272        12360 :    if (in_at_file)
    2273            0 :      fatal_error (input_location, "cannot open nested response file");
    2274              :    else
    2275        12360 :      in_at_file = true;
    2276        12360 : }
    2277              : 
    2278              : /* Create a temporary @file name.  */
    2279              : 
    2280        12298 : static char *make_at_file (void)
    2281              : {
    2282        12298 :   static int fileno = 0;
    2283        12298 :   char filename[20];
    2284        12298 :   const char *base, *ext;
    2285              : 
    2286        12298 :   if (!save_temps_flag)
    2287        12260 :     return make_temp_file ("");
    2288              : 
    2289           38 :   base = dumpbase;
    2290           38 :   if (!(base && *base))
    2291           11 :     base = dumpdir;
    2292           38 :   if (!(base && *base))
    2293            0 :     base = "a";
    2294              : 
    2295           38 :   sprintf (filename, ".args.%d", fileno++);
    2296           38 :   ext = filename;
    2297              : 
    2298           38 :   if (base == dumpdir && dumpdir_trailing_dash_added)
    2299           38 :     ext++;
    2300              : 
    2301           38 :   return concat (base, ext, NULL);
    2302              : }
    2303              : 
    2304              : /* Close the temporary @file and add @file to the argument list.  */
    2305              : 
    2306              : static void
    2307        12360 : close_at_file (void)
    2308              : {
    2309        12360 :   if (!in_at_file)
    2310            0 :     fatal_error (input_location, "cannot close nonexistent response file");
    2311              : 
    2312        12360 :   in_at_file = false;
    2313              : 
    2314        12360 :   const unsigned int n_args = at_file_argbuf.length ();
    2315        12360 :   if (n_args == 0)
    2316              :     return;
    2317              : 
    2318        12298 :   char **argv = XALLOCAVEC (char *, n_args + 1);
    2319        12298 :   char *temp_file = make_at_file ();
    2320        12298 :   char *at_argument = concat ("@", temp_file, NULL);
    2321        12298 :   FILE *f = fopen (temp_file, "w");
    2322        12298 :   int status;
    2323        12298 :   unsigned int i;
    2324              : 
    2325              :   /* Copy the strings over.  */
    2326        37962 :   for (i = 0; i < n_args; i++)
    2327        13366 :     argv[i] = const_cast<char *> (at_file_argbuf[i]);
    2328        12298 :   argv[i] = NULL;
    2329              : 
    2330        12298 :   at_file_argbuf.truncate (0);
    2331              : 
    2332        12298 :   if (f == NULL)
    2333            0 :     fatal_error (input_location, "could not open temporary response file %s",
    2334              :                  temp_file);
    2335              : 
    2336        12298 :   status = writeargv (argv, f);
    2337              : 
    2338        12298 :   if (status)
    2339            0 :     fatal_error (input_location,
    2340              :                  "could not write to temporary response file %s",
    2341              :                  temp_file);
    2342              : 
    2343        12298 :   status = fclose (f);
    2344              : 
    2345        12298 :   if (status == EOF)
    2346            0 :     fatal_error (input_location, "could not close temporary response file %s",
    2347              :                  temp_file);
    2348              : 
    2349        12298 :   store_arg (at_argument, 0, 0);
    2350              : 
    2351        12298 :   record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
    2352              : }
    2353              : 
    2354              : /* Load specs from a file name named FILENAME, replacing occurrences of
    2355              :    various different types of line-endings, \r\n, \n\r and just \r, with
    2356              :    a single \n.  */
    2357              : 
    2358              : static char *
    2359       334140 : load_specs (const char *filename)
    2360              : {
    2361       334140 :   int desc;
    2362       334140 :   int readlen;
    2363       334140 :   struct stat statbuf;
    2364       334140 :   char *buffer;
    2365       334140 :   char *buffer_p;
    2366       334140 :   char *specs;
    2367       334140 :   char *specs_p;
    2368              : 
    2369       334140 :   if (verbose_flag)
    2370         1524 :     fnotice (stderr, "Reading specs from %s\n", filename);
    2371              : 
    2372              :   /* Open and stat the file.  */
    2373       334140 :   desc = open (filename, O_RDONLY, 0);
    2374       334140 :   if (desc < 0)
    2375              :     {
    2376            1 :     failed:
    2377              :       /* This leaves DESC open, but the OS will save us.  */
    2378            1 :       fatal_error (input_location, "cannot read spec file %qs: %m", filename);
    2379              :     }
    2380              : 
    2381       334139 :   if (stat (filename, &statbuf) < 0)
    2382            0 :     goto failed;
    2383              : 
    2384              :   /* Read contents of file into BUFFER.  */
    2385       334139 :   buffer = XNEWVEC (char, statbuf.st_size + 1);
    2386       334139 :   readlen = read (desc, buffer, (unsigned) statbuf.st_size);
    2387       334139 :   if (readlen < 0)
    2388            0 :     goto failed;
    2389       334139 :   buffer[readlen] = 0;
    2390       334139 :   close (desc);
    2391              : 
    2392       334139 :   specs = XNEWVEC (char, readlen + 1);
    2393       334139 :   specs_p = specs;
    2394   3044395591 :   for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
    2395              :     {
    2396   3044061452 :       int skip = 0;
    2397   3044061452 :       char c = *buffer_p;
    2398   3044061452 :       if (c == '\r')
    2399              :         {
    2400            0 :           if (buffer_p > buffer && *(buffer_p - 1) == '\n')  /* \n\r */
    2401              :             skip = 1;
    2402            0 :           else if (*(buffer_p + 1) == '\n')                     /* \r\n */
    2403              :             skip = 1;
    2404              :           else                                                  /* \r */
    2405              :             c = '\n';
    2406              :         }
    2407              :       if (! skip)
    2408   3044061452 :         *specs_p++ = c;
    2409              :     }
    2410       334139 :   *specs_p = '\0';
    2411              : 
    2412       334139 :   free (buffer);
    2413       334139 :   return (specs);
    2414              : }
    2415              : 
    2416              : /* Read compilation specs from a file named FILENAME,
    2417              :    replacing the default ones.
    2418              : 
    2419              :    A suffix which starts with `*' is a definition for
    2420              :    one of the machine-specific sub-specs.  The "suffix" should be
    2421              :    *asm, *cc1, *cpp, *link, *startfile, etc.
    2422              :    The corresponding spec is stored in asm_spec, etc.,
    2423              :    rather than in the `compilers' vector.
    2424              : 
    2425              :    Anything invalid in the file is a fatal error.  */
    2426              : 
    2427              : static void
    2428       334140 : read_specs (const char *filename, bool main_p, bool user_p)
    2429              : {
    2430       334140 :   char *buffer;
    2431       334140 :   char *p;
    2432              : 
    2433       334140 :   buffer = load_specs (filename);
    2434              : 
    2435              :   /* Scan BUFFER for specs, putting them in the vector.  */
    2436       334140 :   p = buffer;
    2437     14611899 :   while (1)
    2438              :     {
    2439     14611899 :       char *suffix;
    2440     14611899 :       char *spec;
    2441     14611899 :       char *in, *out, *p1, *p2, *p3;
    2442              : 
    2443              :       /* Advance P in BUFFER to the next nonblank nocomment line.  */
    2444     14611899 :       p = skip_whitespace (p);
    2445     14611899 :       if (*p == 0)
    2446              :         break;
    2447              : 
    2448              :       /* Is this a special command that starts with '%'? */
    2449              :       /* Don't allow this for the main specs file, since it would
    2450              :          encourage people to overwrite it.  */
    2451     14277760 :       if (*p == '%' && !main_p)
    2452              :         {
    2453       429500 :           p1 = p;
    2454       429500 :           while (*p && *p != '\n')
    2455       408025 :             p++;
    2456              : 
    2457              :           /* Skip '\n'.  */
    2458        21475 :           p++;
    2459              : 
    2460        21475 :           if (startswith (p1, "%include")
    2461        21475 :               && (p1[sizeof "%include" - 1] == ' '
    2462            0 :                   || p1[sizeof "%include" - 1] == '\t'))
    2463              :             {
    2464            0 :               char *new_filename;
    2465              : 
    2466            0 :               p1 += sizeof ("%include");
    2467            0 :               while (*p1 == ' ' || *p1 == '\t')
    2468            0 :                 p1++;
    2469              : 
    2470            0 :               if (*p1++ != '<' || p[-2] != '>')
    2471            0 :                 fatal_error (input_location,
    2472              :                              "specs %%include syntax malformed after "
    2473            0 :                              "%td characters", p1 - buffer + 1);
    2474              : 
    2475            0 :               p[-2] = '\0';
    2476            0 :               new_filename = find_a_file (&startfile_prefixes, p1, true);
    2477            0 :               read_specs (new_filename ? new_filename : p1, false, user_p);
    2478            0 :               continue;
    2479            0 :             }
    2480        21475 :           else if (startswith (p1, "%include_noerr")
    2481        21475 :                    && (p1[sizeof "%include_noerr" - 1] == ' '
    2482            0 :                        || p1[sizeof "%include_noerr" - 1] == '\t'))
    2483              :             {
    2484            0 :               char *new_filename;
    2485              : 
    2486            0 :               p1 += sizeof "%include_noerr";
    2487            0 :               while (*p1 == ' ' || *p1 == '\t')
    2488            0 :                 p1++;
    2489              : 
    2490            0 :               if (*p1++ != '<' || p[-2] != '>')
    2491            0 :                 fatal_error (input_location,
    2492              :                              "specs %%include syntax malformed after "
    2493            0 :                              "%td characters", p1 - buffer + 1);
    2494              : 
    2495            0 :               p[-2] = '\0';
    2496            0 :               new_filename = find_a_file (&startfile_prefixes, p1, true);
    2497            0 :               if (new_filename)
    2498            0 :                 read_specs (new_filename, false, user_p);
    2499            0 :               else if (verbose_flag)
    2500            0 :                 fnotice (stderr, "could not find specs file %s\n", p1);
    2501            0 :               continue;
    2502            0 :             }
    2503        21475 :           else if (startswith (p1, "%rename")
    2504        21475 :                    && (p1[sizeof "%rename" - 1] == ' '
    2505            0 :                        || p1[sizeof "%rename" - 1] == '\t'))
    2506              :             {
    2507        21475 :               int name_len;
    2508        21475 :               struct spec_list *sl;
    2509        21475 :               struct spec_list *newsl;
    2510              : 
    2511              :               /* Get original name.  */
    2512        21475 :               p1 += sizeof "%rename";
    2513        21475 :               while (*p1 == ' ' || *p1 == '\t')
    2514            0 :                 p1++;
    2515              : 
    2516        21475 :               if (! ISALPHA ((unsigned char) *p1))
    2517            0 :                 fatal_error (input_location,
    2518              :                              "specs %%rename syntax malformed after "
    2519              :                              "%td characters", p1 - buffer);
    2520              : 
    2521              :               p2 = p1;
    2522        85900 :               while (*p2 && !ISSPACE ((unsigned char) *p2))
    2523        64425 :                 p2++;
    2524              : 
    2525        21475 :               if (*p2 != ' ' && *p2 != '\t')
    2526            0 :                 fatal_error (input_location,
    2527              :                              "specs %%rename syntax malformed after "
    2528              :                              "%td characters", p2 - buffer);
    2529              : 
    2530        21475 :               name_len = p2 - p1;
    2531        21475 :               *p2++ = '\0';
    2532        21475 :               while (*p2 == ' ' || *p2 == '\t')
    2533            0 :                 p2++;
    2534              : 
    2535        21475 :               if (! ISALPHA ((unsigned char) *p2))
    2536            0 :                 fatal_error (input_location,
    2537              :                              "specs %%rename syntax malformed after "
    2538              :                              "%td characters", p2 - buffer);
    2539              : 
    2540              :               /* Get new spec name.  */
    2541              :               p3 = p2;
    2542       171800 :               while (*p3 && !ISSPACE ((unsigned char) *p3))
    2543       150325 :                 p3++;
    2544              : 
    2545        21475 :               if (p3 != p - 1)
    2546            0 :                 fatal_error (input_location,
    2547              :                              "specs %%rename syntax malformed after "
    2548              :                              "%td characters", p3 - buffer);
    2549        21475 :               *p3 = '\0';
    2550              : 
    2551       429500 :               for (sl = specs; sl; sl = sl->next)
    2552       429500 :                 if (name_len == sl->name_len && !strcmp (sl->name, p1))
    2553              :                   break;
    2554              : 
    2555        21475 :               if (!sl)
    2556            0 :                 fatal_error (input_location,
    2557              :                              "specs %s spec was not found to be renamed", p1);
    2558              : 
    2559        21475 :               if (strcmp (p1, p2) == 0)
    2560            0 :                 continue;
    2561              : 
    2562      1009325 :               for (newsl = specs; newsl; newsl = newsl->next)
    2563       987850 :                 if (strcmp (newsl->name, p2) == 0)
    2564            0 :                   fatal_error (input_location,
    2565              :                                "%s: attempt to rename spec %qs to "
    2566              :                                "already defined spec %qs",
    2567              :                     filename, p1, p2);
    2568              : 
    2569        21475 :               if (verbose_flag)
    2570              :                 {
    2571            0 :                   fnotice (stderr, "rename spec %s to %s\n", p1, p2);
    2572              : #ifdef DEBUG_SPECS
    2573              :                   fnotice (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
    2574              : #endif
    2575              :                 }
    2576              : 
    2577        21475 :               set_spec (p2, *(sl->ptr_spec), user_p);
    2578        21475 :               if (sl->alloc_p)
    2579        21475 :                 free (const_cast<char *> (*(sl->ptr_spec)));
    2580              : 
    2581        21475 :               *(sl->ptr_spec) = "";
    2582        21475 :               sl->alloc_p = 0;
    2583        21475 :               continue;
    2584        21475 :             }
    2585              :           else
    2586            0 :             fatal_error (input_location,
    2587              :                          "specs unknown %% command after %td characters",
    2588              :                          p1 - buffer);
    2589              :         }
    2590              : 
    2591              :       /* Find the colon that should end the suffix.  */
    2592              :       p1 = p;
    2593    195743469 :       while (*p1 && *p1 != ':' && *p1 != '\n')
    2594    181487184 :         p1++;
    2595              : 
    2596              :       /* The colon shouldn't be missing.  */
    2597     14256285 :       if (*p1 != ':')
    2598            0 :         fatal_error (input_location,
    2599              :                      "specs file malformed after %td characters",
    2600              :                      p1 - buffer);
    2601              : 
    2602              :       /* Skip back over trailing whitespace.  */
    2603              :       p2 = p1;
    2604     14256285 :       while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t'))
    2605            0 :         p2--;
    2606              : 
    2607              :       /* Copy the suffix to a string.  */
    2608     14256285 :       suffix = save_string (p, p2 - p);
    2609              :       /* Find the next line.  */
    2610     14256285 :       p = skip_whitespace (p1 + 1);
    2611     14256285 :       if (p[1] == 0)
    2612            0 :         fatal_error (input_location,
    2613              :                      "specs file malformed after %td characters",
    2614              :                      p - buffer);
    2615              : 
    2616              :       p1 = p;
    2617              :       /* Find next blank line or end of string.  */
    2618   2815663431 :       while (*p1 && !(*p1 == '\n' && (p1[1] == '\n' || p1[1] == '\0')))
    2619   2801407146 :         p1++;
    2620              : 
    2621              :       /* Specs end at the blank line and do not include the newline.  */
    2622     14256285 :       spec = save_string (p, p1 - p);
    2623     14256285 :       p = p1;
    2624              : 
    2625              :       /* Delete backslash-newline sequences from the spec.  */
    2626     14256285 :       in = spec;
    2627     14256285 :       out = spec;
    2628   2829919714 :       while (*in != 0)
    2629              :         {
    2630   2801407144 :           if (in[0] == '\\' && in[1] == '\n')
    2631            2 :             in += 2;
    2632   2801407142 :           else if (in[0] == '#')
    2633            0 :             while (*in && *in != '\n')
    2634            0 :               in++;
    2635              : 
    2636              :           else
    2637   2801407142 :             *out++ = *in++;
    2638              :         }
    2639     14256285 :       *out = 0;
    2640              : 
    2641     14256285 :       if (suffix[0] == '*')
    2642              :         {
    2643     14256285 :           if (! strcmp (suffix, "*link_command"))
    2644       302736 :             link_command_spec = spec;
    2645              :           else
    2646              :             {
    2647     13953549 :               set_spec (suffix + 1, spec, user_p);
    2648     13953549 :               free (spec);
    2649              :             }
    2650              :         }
    2651              :       else
    2652              :         {
    2653              :           /* Add this pair to the vector.  */
    2654            0 :           compilers
    2655            0 :             = XRESIZEVEC (struct compiler, compilers, n_compilers + 2);
    2656              : 
    2657            0 :           compilers[n_compilers].suffix = suffix;
    2658            0 :           compilers[n_compilers].spec = spec;
    2659            0 :           n_compilers++;
    2660            0 :           memset (&compilers[n_compilers], 0, sizeof compilers[n_compilers]);
    2661              :         }
    2662              : 
    2663     14256285 :       if (*suffix == 0)
    2664            0 :         link_command_spec = spec;
    2665              :     }
    2666              : 
    2667       334139 :   if (link_command_spec == 0)
    2668            0 :     fatal_error (input_location, "spec file has no spec for linking");
    2669              : 
    2670       334139 :   XDELETEVEC (buffer);
    2671       334139 : }
    2672              : 
    2673              : /* Record the names of temporary files we tell compilers to write,
    2674              :    and delete them at the end of the run.  */
    2675              : 
    2676              : /* This is the common prefix we use to make temp file names.
    2677              :    It is chosen once for each run of this program.
    2678              :    It is substituted into a spec by %g or %j.
    2679              :    Thus, all temp file names contain this prefix.
    2680              :    In practice, all temp file names start with this prefix.
    2681              : 
    2682              :    This prefix comes from the envvar TMPDIR if it is defined;
    2683              :    otherwise, from the P_tmpdir macro if that is defined;
    2684              :    otherwise, in /usr/tmp or /tmp;
    2685              :    or finally the current directory if all else fails.  */
    2686              : 
    2687              : static const char *temp_filename;
    2688              : 
    2689              : /* Length of the prefix.  */
    2690              : 
    2691              : static int temp_filename_length;
    2692              : 
    2693              : /* Define the list of temporary files to delete.  */
    2694              : 
    2695              : struct temp_file
    2696              : {
    2697              :   const char *name;
    2698              :   struct temp_file *next;
    2699              : };
    2700              : 
    2701              : /* Queue of files to delete on success or failure of compilation.  */
    2702              : static struct temp_file *always_delete_queue;
    2703              : /* Queue of files to delete on failure of compilation.  */
    2704              : static struct temp_file *failure_delete_queue;
    2705              : 
    2706              : /* Record FILENAME as a file to be deleted automatically.
    2707              :    ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
    2708              :    otherwise delete it in any case.
    2709              :    FAIL_DELETE nonzero means delete it if a compilation step fails;
    2710              :    otherwise delete it in any case.  */
    2711              : 
    2712              : void
    2713       915807 : record_temp_file (const char *filename, int always_delete, int fail_delete)
    2714              : {
    2715       915807 :   char *const name = xstrdup (filename);
    2716              : 
    2717       915807 :   if (always_delete)
    2718              :     {
    2719       737190 :       struct temp_file *temp;
    2720      1883679 :       for (temp = always_delete_queue; temp; temp = temp->next)
    2721      1312793 :         if (! filename_cmp (name, temp->name))
    2722              :           {
    2723       166304 :             free (name);
    2724       166304 :             goto already1;
    2725              :           }
    2726              : 
    2727       570886 :       temp = XNEW (struct temp_file);
    2728       570886 :       temp->next = always_delete_queue;
    2729       570886 :       temp->name = name;
    2730       570886 :       always_delete_queue = temp;
    2731              : 
    2732       915807 :     already1:;
    2733              :     }
    2734              : 
    2735       915807 :   if (fail_delete)
    2736              :     {
    2737       491139 :       struct temp_file *temp;
    2738       694531 :       for (temp = failure_delete_queue; temp; temp = temp->next)
    2739       203481 :         if (! filename_cmp (name, temp->name))
    2740              :           {
    2741           89 :             free (name);
    2742           89 :             goto already2;
    2743              :           }
    2744              : 
    2745       491050 :       temp = XNEW (struct temp_file);
    2746       491050 :       temp->next = failure_delete_queue;
    2747       491050 :       temp->name = name;
    2748       491050 :       failure_delete_queue = temp;
    2749              : 
    2750       915807 :     already2:;
    2751              :     }
    2752       915807 : }
    2753              : 
    2754              : /* Delete all the temporary files whose names we previously recorded.  */
    2755              : 
    2756              : #ifndef DELETE_IF_ORDINARY
    2757              : #define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG)        \
    2758              : do                                                      \
    2759              :   {                                                     \
    2760              :     if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode))  \
    2761              :       if (unlink (NAME) < 0)                            \
    2762              :         if (VERBOSE_FLAG)                               \
    2763              :           error ("%s: %m", (NAME));                   \
    2764              :   } while (0)
    2765              : #endif
    2766              : 
    2767              : static void
    2768       597597 : delete_if_ordinary (const char *name)
    2769              : {
    2770       597597 :   struct stat st;
    2771              : #ifdef DEBUG
    2772              :   int i, c;
    2773              : 
    2774              :   printf ("Delete %s? (y or n) ", name);
    2775              :   fflush (stdout);
    2776              :   i = getchar ();
    2777              :   if (i != '\n')
    2778              :     while ((c = getchar ()) != '\n' && c != EOF)
    2779              :       ;
    2780              : 
    2781              :   if (i == 'y' || i == 'Y')
    2782              : #endif /* DEBUG */
    2783       597597 :   DELETE_IF_ORDINARY (name, st, verbose_flag);
    2784       597597 : }
    2785              : 
    2786              : static void
    2787       591743 : delete_temp_files (void)
    2788              : {
    2789       591743 :   struct temp_file *temp;
    2790              : 
    2791      1162629 :   for (temp = always_delete_queue; temp; temp = temp->next)
    2792       570886 :     delete_if_ordinary (temp->name);
    2793       591743 :   always_delete_queue = 0;
    2794       591743 : }
    2795              : 
    2796              : /* Delete all the files to be deleted on error.  */
    2797              : 
    2798              : static void
    2799        60008 : delete_failure_queue (void)
    2800              : {
    2801        60008 :   struct temp_file *temp;
    2802              : 
    2803        86719 :   for (temp = failure_delete_queue; temp; temp = temp->next)
    2804        26711 :     delete_if_ordinary (temp->name);
    2805        60008 : }
    2806              : 
    2807              : static void
    2808       552809 : clear_failure_queue (void)
    2809              : {
    2810       552809 :   failure_delete_queue = 0;
    2811       552809 : }
    2812              : 
    2813              : /* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
    2814              :    returns non-NULL.
    2815              :    If DO_MULTI is true iterate over the paths twice, first with multilib
    2816              :    suffix then without, otherwise iterate over the paths once without
    2817              :    adding a multilib suffix.  When DO_MULTI is true, some attempt is made
    2818              :    to avoid visiting the same path twice, but we could do better.  For
    2819              :    instance, /usr/lib/../lib is considered different from /usr/lib.
    2820              :    At least EXTRA_SPACE chars past the end of the path passed to
    2821              :    CALLBACK are available for use by the callback.
    2822              :    CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
    2823              : 
    2824              :    Returns the value returned by CALLBACK.  */
    2825              : 
    2826              : template<typename fun>
    2827              : auto *
    2828      2873615 : for_each_path (const struct path_prefix *paths,
    2829              :                bool do_multi,
    2830              :                size_t extra_space,
    2831              :                fun && callback)
    2832              : {
    2833              :   struct prefix_list *pl;
    2834      2873615 :   const char *multi_dir = NULL;
    2835      2873615 :   const char *multi_os_dir = NULL;
    2836      2873615 :   const char *multiarch_suffix = NULL;
    2837              :   const char *multi_suffix;
    2838              :   const char *just_multi_suffix;
    2839      2873615 :   char *path = NULL;
    2840      2873615 :   decltype (callback (nullptr, false)) ret = nullptr;
    2841      2873615 :   bool skip_multi_dir = false;
    2842      2873615 :   bool skip_multi_os_dir = false;
    2843              : 
    2844      2873615 :   multi_suffix = machine_suffix;
    2845      2873615 :   just_multi_suffix = just_machine_suffix;
    2846      2873615 :   if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
    2847              :     {
    2848        15861 :       multi_dir = concat (multilib_dir, dir_separator_str, NULL);
    2849        15861 :       multi_suffix = concat (multi_suffix, multi_dir, NULL);
    2850        15861 :       just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
    2851              :     }
    2852      1248720 :   if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
    2853       944881 :     multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
    2854      2873615 :   if (multiarch_dir)
    2855            0 :     multiarch_suffix = concat (multiarch_dir, dir_separator_str, NULL);
    2856              : 
    2857              :   while (1)
    2858              :     {
    2859      3303274 :       size_t multi_dir_len = 0;
    2860      3303274 :       size_t multi_os_dir_len = 0;
    2861      3303274 :       size_t multiarch_len = 0;
    2862              :       size_t suffix_len;
    2863              :       size_t just_suffix_len;
    2864              :       size_t len;
    2865              : 
    2866      3303274 :       if (multi_dir)
    2867        15861 :         multi_dir_len = strlen (multi_dir);
    2868      3303274 :       if (multi_os_dir)
    2869       944881 :         multi_os_dir_len = strlen (multi_os_dir);
    2870      3303274 :       if (multiarch_suffix)
    2871            0 :         multiarch_len = strlen (multiarch_suffix);
    2872      3303274 :       suffix_len = strlen (multi_suffix);
    2873      3303274 :       just_suffix_len = strlen (just_multi_suffix);
    2874              : 
    2875      3303274 :       if (path == NULL)
    2876              :         {
    2877      2873615 :           len = paths->max_len + extra_space + 1;
    2878      2873615 :           len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len);
    2879      2873615 :           path = XNEWVEC (char, len);
    2880              :         }
    2881              : 
    2882     12900310 :       for (pl = paths->plist; pl != 0; pl = pl->next)
    2883              :         {
    2884     11292800 :           len = strlen (pl->prefix);
    2885     11292800 :           memcpy (path, pl->prefix, len);
    2886              : 
    2887              :           /* Look first in MACHINE/VERSION subdirectory.  */
    2888     11292800 :           if (!skip_multi_dir)
    2889              :             {
    2890      8263708 :               memcpy (path + len, multi_suffix, suffix_len + 1);
    2891      8263708 :               ret = callback (path, true);
    2892      5335125 :               if (ret)
    2893              :                 break;
    2894              :             }
    2895              : 
    2896              :           /* Some paths are tried with just the machine (ie. target)
    2897              :              subdir.  This is used for finding as, ld, etc.  */
    2898              :           if (!skip_multi_dir
    2899      8263708 :               && pl->require_machine_suffix == 2)
    2900              :             {
    2901            0 :               memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
    2902            0 :               ret = callback (path, true);
    2903            0 :               if (ret)
    2904              :                 break;
    2905              :             }
    2906              : 
    2907              :           /* Now try the multiarch path.  */
    2908              :           if (!skip_multi_dir
    2909      8263708 :               && !pl->require_machine_suffix && multiarch_dir)
    2910              :             {
    2911            0 :               memcpy (path + len, multiarch_suffix, multiarch_len + 1);
    2912            0 :               ret = callback (path, true);
    2913            0 :               if (ret)
    2914              :                 break;
    2915              :             }
    2916              : 
    2917              :           /* Now try the base path.  */
    2918     11292800 :           if (!pl->require_machine_suffix
    2919     17974104 :               && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
    2920              :             {
    2921              :               const char *this_multi;
    2922              :               size_t this_multi_len;
    2923              : 
    2924     10091719 :               if (pl->os_multilib)
    2925              :                 {
    2926              :                   this_multi = multi_os_dir;
    2927              :                   this_multi_len = multi_os_dir_len;
    2928              :                 }
    2929              :               else
    2930              :                 {
    2931      5480223 :                   this_multi = multi_dir;
    2932      5480223 :                   this_multi_len = multi_dir_len;
    2933              :                 }
    2934              : 
    2935     10091719 :               if (this_multi_len)
    2936      2803834 :                 memcpy (path + len, this_multi, this_multi_len + 1);
    2937              :               else
    2938      7287885 :                 path[len] = '\0';
    2939              : 
    2940     10091719 :               ret = callback (path, false);
    2941      6007277 :               if (ret)
    2942              :                 break;
    2943              :             }
    2944              :         }
    2945      2531611 :       if (pl)
    2946              :         break;
    2947              : 
    2948      1607510 :       if (multi_dir == NULL && multi_os_dir == NULL)
    2949              :         break;
    2950              : 
    2951              :       /* Run through the paths again, this time without multilibs.
    2952              :          Don't repeat any we have already seen.  */
    2953       429659 :       if (multi_dir)
    2954              :         {
    2955        10164 :           free (const_cast<char *> (multi_dir));
    2956        10164 :           multi_dir = NULL;
    2957        10164 :           free (const_cast<char *> (multi_suffix));
    2958        10164 :           multi_suffix = machine_suffix;
    2959        10164 :           free (const_cast<char *> (just_multi_suffix));
    2960        10164 :           just_multi_suffix = just_machine_suffix;
    2961              :         }
    2962              :       else
    2963              :         skip_multi_dir = true;
    2964       429659 :       if (multi_os_dir)
    2965              :         {
    2966       429659 :           free (const_cast<char *> (multi_os_dir));
    2967       429659 :           multi_os_dir = NULL;
    2968              :         }
    2969              :       else
    2970              :         skip_multi_os_dir = true;
    2971              :     }
    2972              : 
    2973      2873615 :   if (multi_dir)
    2974              :     {
    2975         5697 :       free (const_cast<char *> (multi_dir));
    2976         5697 :       free (const_cast<char *> (multi_suffix));
    2977         5697 :       free (const_cast<char *> (just_multi_suffix));
    2978              :     }
    2979      2873615 :   if (multi_os_dir)
    2980       515222 :     free (const_cast<char *> (multi_os_dir));
    2981      2359173 :   if (ret != path)
    2982      1177851 :     free (path);
    2983      2873615 :   return ret;
    2984              : }
    2985              : 
    2986              : /* Add or change the value of an environment variable, outputting the
    2987              :    change to standard error if in verbose mode.  */
    2988              : static void
    2989      1790442 : xputenv (const char *string)
    2990              : {
    2991            0 :   env.xput (string);
    2992       139501 : }
    2993              : 
    2994              : /* Build a list of search directories from PATHS.
    2995              :    PREFIX is a string to prepend to the list.
    2996              :    If CHECK_DIR_P is true we ensure the directory exists.
    2997              :    If DO_MULTI is true, multilib paths are output first, then
    2998              :    non-multilib paths.
    2999              :    This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
    3000              :    It is also used by the --print-search-dirs flag.  */
    3001              : 
    3002              : static char *
    3003       514442 : build_search_list (const struct path_prefix *paths, const char *prefix,
    3004              :                    bool check_dir, bool do_multi)
    3005              : {
    3006       514442 :   struct obstack *const ob = &collect_obstack;
    3007       514442 :   bool first_time = true;
    3008              : 
    3009       514442 :   obstack_grow (&collect_obstack, prefix, strlen (prefix));
    3010       514442 :   obstack_1grow (&collect_obstack, '=');
    3011              : 
    3012              :   /* Callback adds path to obstack being built.  */
    3013       514442 :   for_each_path (paths, do_multi, 0, [&](char *path, bool) -> void*
    3014              :     {
    3015      7013025 :       if (check_dir && !is_directory (path))
    3016              :         return NULL;
    3017              : 
    3018      2570073 :       if (!first_time)
    3019      2056775 :         obstack_1grow (ob, PATH_SEPARATOR);
    3020              : 
    3021      2570073 :       obstack_grow (ob, path, strlen (path));
    3022              : 
    3023      2570073 :       first_time = false;
    3024      2570073 :       return NULL;
    3025              :     });
    3026              : 
    3027       514442 :   obstack_1grow (&collect_obstack, '\0');
    3028       514442 :   return XOBFINISH (&collect_obstack, char *);
    3029              : }
    3030              : 
    3031              : /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    3032              :    for collect.  */
    3033              : 
    3034              : static void
    3035       514386 : putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
    3036              :                       bool do_multi)
    3037              : {
    3038       514386 :   xputenv (build_search_list (paths, env_var, true, do_multi));
    3039       514386 : }
    3040              : 
    3041              : /* Check whether NAME can be accessed in MODE.  This is like access,
    3042              :    except that it never considers directories to be executable.  */
    3043              : 
    3044              : static int
    3045      8725081 : access_check (const char *name, int mode)
    3046              : {
    3047      2297367 :   if (mode == X_OK)
    3048              :     {
    3049      2297367 :       struct stat st;
    3050              : 
    3051      2297367 :       if (stat (name, &st) < 0
    3052      2297367 :           || S_ISDIR (st.st_mode))
    3053      1544415 :         return -1;
    3054              :     }
    3055              : 
    3056       752952 :   return access (name, mode);
    3057              : }
    3058              : 
    3059              : 
    3060              : /* Search for NAME using the prefix list PREFIXES.  MODE is passed to
    3061              :    access to check permissions.  If DO_MULTI is true, search multilib
    3062              :    paths then non-multilib paths, otherwise do not search multilib paths.
    3063              :    Return 0 if not found, otherwise return its name, allocated with malloc.  */
    3064              : 
    3065              : static char *
    3066      1039509 : find_a_file (const struct path_prefix *pprefix, const char *name,
    3067              :              bool do_multi)
    3068              : {
    3069              :   /* Find the filename in question (special case for absolute paths).  */
    3070              : 
    3071      1039509 :   if (IS_ABSOLUTE_PATH (name))
    3072              :     {
    3073            1 :       if (access (name, R_OK) == 0)
    3074            1 :         return xstrdup (name);
    3075              : 
    3076              :       return NULL;
    3077              :     }
    3078              : 
    3079      1039508 :   const int name_len = strlen (name);
    3080              : 
    3081              : 
    3082              :   /* Callback appends the file name to the directory path.  If the
    3083              :      resulting file exists in the right mode, return the full pathname
    3084              :      to the file.  */
    3085      1039508 :   return for_each_path (pprefix, do_multi,
    3086              :                         name_len,
    3087      1039508 :                         [=](char *path, bool) -> char*
    3088              :     {
    3089      6427714 :       memcpy (path + strlen (path), name, name_len + 1);
    3090              : 
    3091      6427714 :       if (access_check (path, R_OK) == 0)
    3092       942812 :         return path;
    3093              : 
    3094              :       return NULL;
    3095              :     });
    3096              : }
    3097              : 
    3098              : /* Specialization of find_a_file for programs that also takes into account
    3099              :    configure-specified default programs. */
    3100              : 
    3101              : static char*
    3102       759059 : find_a_program (const char *name)
    3103              : {
    3104              :   /* Do not search if default matches query. */
    3105              : 
    3106              : #ifdef DEFAULT_ASSEMBLER
    3107              :   if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, X_OK) == 0)
    3108              :     return xstrdup (DEFAULT_ASSEMBLER);
    3109              : #endif
    3110              : 
    3111              : #ifdef DEFAULT_LINKER
    3112              :   if (! strcmp (name, "ld") && access (DEFAULT_LINKER, X_OK) == 0)
    3113              :     return xstrdup (DEFAULT_LINKER);
    3114              : #endif
    3115              : 
    3116              : #ifdef DEFAULT_DSYMUTIL
    3117              :   if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, X_OK) == 0)
    3118              :     return xstrdup (DEFAULT_DSYMUTIL);
    3119              : #endif
    3120              : 
    3121              : #ifdef DEFAULT_WINDRES
    3122              :   if (! strcmp (name, "windres") && access (DEFAULT_WINDRES, X_OK) == 0)
    3123              :     return xstrdup (DEFAULT_WINDRES);
    3124              : #endif
    3125              : 
    3126              :   /* Find the filename in question (special case for absolute paths).  */
    3127              : 
    3128       759059 :   if (IS_ABSOLUTE_PATH (name))
    3129              :     {
    3130            0 :       if (access (name, X_OK) == 0)
    3131            0 :         return xstrdup (name);
    3132              : 
    3133              :       return NULL;
    3134              :     }
    3135              : 
    3136       759059 :   const char *suffix = HOST_EXECUTABLE_SUFFIX;
    3137       759059 :   const int name_len = strlen (name);
    3138       759059 :   const int prefix_len = strlen (just_machine_prefix);
    3139       759059 :   const int suffix_len = strlen (suffix);
    3140              : 
    3141              :   /* Callback appends the file name to the directory path.  If the
    3142              :      resulting file exists in the right mode, return the full pathname
    3143              :      to the file.  */
    3144       759059 :   return for_each_path (&exec_prefixes, false,
    3145       759059 :                         prefix_len + name_len + suffix_len,
    3146       759059 :                         [=](char *path, bool machine_specific) -> char*
    3147              :     {
    3148      1531578 :       size_t path_len = strlen (path);
    3149              : 
    3150      3828945 :       auto search = [=](size_t len) -> char*
    3151              :         {
    3152      2297367 :           memcpy (path + len, name, name_len + 1);
    3153      2297367 :           len += name_len;
    3154              : 
    3155              :           /* Some systems have a suffix for executable files.
    3156              :              So try appending that first.  */
    3157      2297367 :           if (suffix_len)
    3158              :             {
    3159            0 :               memcpy (path + len, suffix, suffix_len + 1);
    3160            0 :               if (access_check (path, X_OK) == 0)
    3161            0 :                 return path;
    3162              :             }
    3163              : 
    3164      2297367 :           path[len] = '\0';
    3165      2297367 :           if (access_check (path, X_OK) == 0)
    3166       752952 :             return path;
    3167              : 
    3168              :           return NULL;
    3169      1531578 :         };
    3170              : 
    3171              :       /* Additionally search for $target-prog in machine-agnostic dirs,
    3172              :          as an additional way to disambiguate targets. Do not do this in
    3173              :          machine-specific dirs because so further disambiguation is
    3174              :          needed. */
    3175      1531578 :       if (!machine_specific)
    3176              :         {
    3177       765789 :           memcpy (path + path_len, just_machine_prefix, prefix_len);
    3178       765789 :           auto ret = search(path_len + prefix_len);
    3179       765789 :           if (ret)
    3180              :             return ret;
    3181              :         }
    3182              : 
    3183      1531578 :       return search(path_len);
    3184              :     });
    3185              : }
    3186              : 
    3187              : /* Ranking of prefixes in the sort list. -B prefixes are put before
    3188              :    all others.  */
    3189              : 
    3190              : enum path_prefix_priority
    3191              : {
    3192              :   PREFIX_PRIORITY_B_OPT,
    3193              :   PREFIX_PRIORITY_LAST
    3194              : };
    3195              : 
    3196              : /* Add an entry for PREFIX in PLIST.  The PLIST is kept in ascending
    3197              :    order according to PRIORITY.  Within each PRIORITY, new entries are
    3198              :    appended.
    3199              : 
    3200              :    If WARN is nonzero, we will warn if no file is found
    3201              :    through this prefix.  WARN should point to an int
    3202              :    which will be set to 1 if this entry is used.
    3203              : 
    3204              :    COMPONENT is the value to be passed to update_path.
    3205              : 
    3206              :    REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
    3207              :    the complete value of machine_suffix.
    3208              :    2 means try both machine_suffix and just_machine_suffix.  */
    3209              : 
    3210              : static void
    3211      3935323 : add_prefix (struct path_prefix *pprefix, const char *prefix,
    3212              :             const char *component, /* enum prefix_priority */ int priority,
    3213              :             int require_machine_suffix, int os_multilib)
    3214              : {
    3215      3935323 :   struct prefix_list *pl, **prev;
    3216      3935323 :   int len;
    3217              : 
    3218      3935323 :   for (prev = &pprefix->plist;
    3219     12355262 :        (*prev) != NULL && (*prev)->priority <= priority;
    3220      8419939 :        prev = &(*prev)->next)
    3221              :     ;
    3222              : 
    3223              :   /* Keep track of the longest prefix.  */
    3224              : 
    3225      3935323 :   prefix = update_path (prefix, component);
    3226      3935323 :   len = strlen (prefix);
    3227      3935323 :   if (len > pprefix->max_len)
    3228      2145939 :     pprefix->max_len = len;
    3229              : 
    3230      3935323 :   pl = XNEW (struct prefix_list);
    3231      3935323 :   pl->prefix = prefix;
    3232      3935323 :   pl->require_machine_suffix = require_machine_suffix;
    3233      3935323 :   pl->priority = priority;
    3234      3935323 :   pl->os_multilib = os_multilib;
    3235              : 
    3236              :   /* Insert after PREV.  */
    3237      3935323 :   pl->next = (*prev);
    3238      3935323 :   (*prev) = pl;
    3239      3935323 : }
    3240              : 
    3241              : /* Same as add_prefix, but prepending target_system_root to prefix.  */
    3242              : /* The target_system_root prefix has been relocated by gcc_exec_prefix.  */
    3243              : static void
    3244       607674 : add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
    3245              :                       const char *component,
    3246              :                       /* enum prefix_priority */ int priority,
    3247              :                       int require_machine_suffix, int os_multilib)
    3248              : {
    3249       607674 :   if (!IS_ABSOLUTE_PATH (prefix))
    3250            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3251              : 
    3252       607674 :   if (target_system_root)
    3253              :     {
    3254            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3255            0 :       size_t sysroot_len = strlen (target_system_root);
    3256              : 
    3257            0 :       if (sysroot_len > 0
    3258            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3259            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3260              : 
    3261            0 :       if (target_sysroot_suffix)
    3262            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3263              :                          target_sysroot_suffix, prefix, NULL);
    3264              :       else
    3265            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3266              : 
    3267            0 :       free (sysroot_no_trailing_dir_separator);
    3268              : 
    3269              :       /* We have to override this because GCC's notion of sysroot
    3270              :          moves along with GCC.  */
    3271            0 :       component = "GCC";
    3272              :     }
    3273              : 
    3274       607674 :   add_prefix (pprefix, prefix, component, priority,
    3275              :               require_machine_suffix, os_multilib);
    3276       607674 : }
    3277              : 
    3278              : /* Same as add_prefix, but prepending target_sysroot_hdrs_suffix to prefix.  */
    3279              : 
    3280              : static void
    3281        31860 : add_sysrooted_hdrs_prefix (struct path_prefix *pprefix, const char *prefix,
    3282              :                            const char *component,
    3283              :                            /* enum prefix_priority */ int priority,
    3284              :                            int require_machine_suffix, int os_multilib)
    3285              : {
    3286        31860 :   if (!IS_ABSOLUTE_PATH (prefix))
    3287            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3288              : 
    3289        31860 :   if (target_system_root)
    3290              :     {
    3291            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3292            0 :       size_t sysroot_len = strlen (target_system_root);
    3293              : 
    3294            0 :       if (sysroot_len > 0
    3295            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3296            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3297              : 
    3298            0 :       if (target_sysroot_hdrs_suffix)
    3299            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3300              :                          target_sysroot_hdrs_suffix, prefix, NULL);
    3301              :       else
    3302            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3303              : 
    3304            0 :       free (sysroot_no_trailing_dir_separator);
    3305              : 
    3306              :       /* We have to override this because GCC's notion of sysroot
    3307              :          moves along with GCC.  */
    3308            0 :       component = "GCC";
    3309              :     }
    3310              : 
    3311        31860 :   add_prefix (pprefix, prefix, component, priority,
    3312              :               require_machine_suffix, os_multilib);
    3313        31860 : }
    3314              : 
    3315              : 
    3316              : /* Execute the command specified by the arguments on the current line of spec.
    3317              :    When using pipes, this includes several piped-together commands
    3318              :    with `|' between them.
    3319              : 
    3320              :    Return 0 if successful, -1 if failed.  */
    3321              : 
    3322              : static int
    3323       550312 : execute (void)
    3324              : {
    3325       550312 :   int i;
    3326       550312 :   int n_commands;               /* # of command.  */
    3327       550312 :   char *string;
    3328       550312 :   struct pex_obj *pex;
    3329       550312 :   struct command
    3330              :   {
    3331              :     const char *prog;           /* program name.  */
    3332              :     const char **argv;          /* vector of args.  */
    3333              :   };
    3334       550312 :   const char *arg;
    3335              : 
    3336       550312 :   struct command *commands;     /* each command buffer with above info.  */
    3337              : 
    3338       550312 :   gcc_assert (!processing_spec_function);
    3339              : 
    3340       550312 :   if (wrapper_string)
    3341              :     {
    3342            0 :       string = find_a_program (argbuf[0]);
    3343            0 :       if (string)
    3344            0 :         argbuf[0] = string;
    3345            0 :       insert_wrapper (wrapper_string);
    3346              :     }
    3347              : 
    3348              :   /* Count # of piped commands.  */
    3349     16996092 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3350     16445780 :     if (strcmp (arg, "|") == 0)
    3351            0 :       n_commands++;
    3352              : 
    3353              :   /* Get storage for each command.  */
    3354       550312 :   commands = XALLOCAVEC (struct command, n_commands);
    3355              : 
    3356              :   /* Split argbuf into its separate piped processes,
    3357              :      and record info about each one.
    3358              :      Also search for the programs that are to be run.  */
    3359              : 
    3360       550312 :   argbuf.safe_push (0);
    3361              : 
    3362       550312 :   commands[0].prog = argbuf[0]; /* first command.  */
    3363       550312 :   commands[0].argv = argbuf.address ();
    3364              : 
    3365       550312 :   if (!wrapper_string)
    3366              :     {
    3367       550312 :       string = find_a_program(commands[0].prog);
    3368       550312 :       if (string)
    3369       547657 :         commands[0].argv[0] = string;
    3370              :     }
    3371              : 
    3372     17546404 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3373     16996092 :     if (arg && strcmp (arg, "|") == 0)
    3374              :       {                         /* each command.  */
    3375              : #if defined (__MSDOS__) || defined (OS2) || defined (VMS)
    3376              :         fatal_error (input_location, "%<-pipe%> not supported");
    3377              : #endif
    3378            0 :         argbuf[i] = 0; /* Termination of command args.  */
    3379            0 :         commands[n_commands].prog = argbuf[i + 1];
    3380            0 :         commands[n_commands].argv
    3381            0 :           = &(argbuf.address ())[i + 1];
    3382            0 :         string = find_a_program(commands[n_commands].prog);
    3383            0 :         if (string)
    3384            0 :           commands[n_commands].argv[0] = string;
    3385            0 :         n_commands++;
    3386              :       }
    3387              : 
    3388              :   /* If -v, print what we are about to do, and maybe query.  */
    3389              : 
    3390       550312 :   if (verbose_flag)
    3391              :     {
    3392              :       /* For help listings, put a blank line between sub-processes.  */
    3393         1454 :       if (print_help_list)
    3394            9 :         fputc ('\n', stderr);
    3395              : 
    3396              :       /* Print each piped command as a separate line.  */
    3397         2908 :       for (i = 0; i < n_commands; i++)
    3398              :         {
    3399         1454 :           const char *const *j;
    3400              : 
    3401         1454 :           if (verbose_only_flag)
    3402              :             {
    3403        17991 :               for (j = commands[i].argv; *j; j++)
    3404              :                 {
    3405              :                   const char *p;
    3406       429398 :                   for (p = *j; *p; ++p)
    3407       414930 :                     if (!ISALNUM ((unsigned char) *p)
    3408        98223 :                         && *p != '_' && *p != '/' && *p != '-' && *p != '.')
    3409              :                       break;
    3410        16968 :                   if (*p || !*j)
    3411              :                     {
    3412         2500 :                       fprintf (stderr, " \"");
    3413       130111 :                       for (p = *j; *p; ++p)
    3414              :                         {
    3415       127611 :                           if (*p == '"' || *p == '\\' || *p == '$')
    3416            0 :                             fputc ('\\', stderr);
    3417       127611 :                           fputc (*p, stderr);
    3418              :                         }
    3419         2500 :                       fputc ('"', stderr);
    3420              :                     }
    3421              :                   /* If it's empty, print "".  */
    3422        14468 :                   else if (!**j)
    3423            0 :                     fprintf (stderr, " \"\"");
    3424              :                   else
    3425        14468 :                     fprintf (stderr, " %s", *j);
    3426              :                 }
    3427              :             }
    3428              :           else
    3429        13605 :             for (j = commands[i].argv; *j; j++)
    3430              :               /* If it's empty, print "".  */
    3431        13174 :               if (!**j)
    3432            0 :                 fprintf (stderr, " \"\"");
    3433              :               else
    3434        13174 :                 fprintf (stderr, " %s", *j);
    3435              : 
    3436              :           /* Print a pipe symbol after all but the last command.  */
    3437         1454 :           if (i + 1 != n_commands)
    3438            0 :             fprintf (stderr, " |");
    3439         1454 :           fprintf (stderr, "\n");
    3440              :         }
    3441         1454 :       fflush (stderr);
    3442         1454 :       if (verbose_only_flag != 0)
    3443              :         {
    3444              :           /* verbose_only_flag should act as if the spec was
    3445              :              executed, so increment execution_count before
    3446              :              returning.  This prevents spurious warnings about
    3447              :              unused linker input files, etc.  */
    3448         1023 :           execution_count++;
    3449         1023 :           return 0;
    3450              :         }
    3451              : #ifdef DEBUG
    3452              :       fnotice (stderr, "\nGo ahead? (y or n) ");
    3453              :       fflush (stderr);
    3454              :       i = getchar ();
    3455              :       if (i != '\n')
    3456              :         while (getchar () != '\n')
    3457              :           ;
    3458              : 
    3459              :       if (i != 'y' && i != 'Y')
    3460              :         return 0;
    3461              : #endif /* DEBUG */
    3462              :     }
    3463              : 
    3464              : #ifdef ENABLE_VALGRIND_CHECKING
    3465              :   /* Run the each command through valgrind.  To simplify prepending the
    3466              :      path to valgrind and the option "-q" (for quiet operation unless
    3467              :      something triggers), we allocate a separate argv array.  */
    3468              : 
    3469              :   for (i = 0; i < n_commands; i++)
    3470              :     {
    3471              :       const char **argv;
    3472              :       int argc;
    3473              :       int j;
    3474              : 
    3475              :       for (argc = 0; commands[i].argv[argc] != NULL; argc++)
    3476              :         ;
    3477              : 
    3478              :       argv = XALLOCAVEC (const char *, argc + 3);
    3479              : 
    3480              :       argv[0] = VALGRIND_PATH;
    3481              :       argv[1] = "-q";
    3482              :       for (j = 2; j < argc + 2; j++)
    3483              :         argv[j] = commands[i].argv[j - 2];
    3484              :       argv[j] = NULL;
    3485              : 
    3486              :       commands[i].argv = argv;
    3487              :       commands[i].prog = argv[0];
    3488              :     }
    3489              : #endif
    3490              : 
    3491              :   /* Run each piped subprocess.  */
    3492              : 
    3493       549289 :   pex = pex_init (PEX_USE_PIPES | ((report_times || report_times_to_file)
    3494              :                                    ? PEX_RECORD_TIMES : 0),
    3495              :                   progname, temp_filename);
    3496       549289 :   if (pex == NULL)
    3497              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    3498              : 
    3499      1098578 :   for (i = 0; i < n_commands; i++)
    3500              :     {
    3501       549289 :       const char *errmsg;
    3502       549289 :       int err;
    3503       549289 :       const char *string = commands[i].argv[0];
    3504              : 
    3505       549289 :       errmsg = pex_run (pex,
    3506       549289 :                         ((i + 1 == n_commands ? PEX_LAST : 0)
    3507       549289 :                          | (string == commands[i].prog ? PEX_SEARCH : 0)),
    3508              :                         string, const_cast<char **> (commands[i].argv),
    3509              :                         NULL, NULL, &err);
    3510       549289 :       if (errmsg != NULL)
    3511              :         {
    3512            0 :           errno = err;
    3513            0 :           fatal_error (input_location,
    3514              :                        err ? G_("cannot execute %qs: %s: %m")
    3515              :                        : G_("cannot execute %qs: %s"),
    3516              :                        string, errmsg);
    3517              :         }
    3518              : 
    3519       549289 :       if (i && string != commands[i].prog)
    3520            0 :         free (const_cast<char *> (string));
    3521              :     }
    3522              : 
    3523       549289 :   execution_count++;
    3524              : 
    3525              :   /* Wait for all the subprocesses to finish.  */
    3526              : 
    3527       549289 :   {
    3528       549289 :     int *statuses;
    3529       549289 :     struct pex_time *times = NULL;
    3530       549289 :     int ret_code = 0;
    3531              : 
    3532       549289 :     statuses = XALLOCAVEC (int, n_commands);
    3533       549289 :     if (!pex_get_status (pex, n_commands, statuses))
    3534            0 :       fatal_error (input_location, "failed to get exit status: %m");
    3535              : 
    3536       549289 :     if (report_times || report_times_to_file)
    3537              :       {
    3538            0 :         times = XALLOCAVEC (struct pex_time, n_commands);
    3539            0 :         if (!pex_get_times (pex, n_commands, times))
    3540            0 :           fatal_error (input_location, "failed to get process times: %m");
    3541              :       }
    3542              : 
    3543       549289 :     pex_free (pex);
    3544              : 
    3545      1098578 :     for (i = 0; i < n_commands; ++i)
    3546              :       {
    3547       549289 :         int status = statuses[i];
    3548              : 
    3549       549289 :         if (WIFSIGNALED (status))
    3550            0 :           switch (WTERMSIG (status))
    3551              :             {
    3552            0 :             case SIGINT:
    3553            0 :             case SIGTERM:
    3554              :               /* SIGQUIT and SIGKILL are not available on MinGW.  */
    3555              : #ifdef SIGQUIT
    3556            0 :             case SIGQUIT:
    3557              : #endif
    3558              : #ifdef SIGKILL
    3559            0 :             case SIGKILL:
    3560              : #endif
    3561              :               /* The user (or environment) did something to the
    3562              :                  inferior.  Making this an ICE confuses the user into
    3563              :                  thinking there's a compiler bug.  Much more likely is
    3564              :                  the user or OOM killer nuked it.  */
    3565            0 :               fatal_error (input_location,
    3566              :                            "%s signal terminated program %s",
    3567              :                            strsignal (WTERMSIG (status)),
    3568            0 :                            commands[i].prog);
    3569            0 :               break;
    3570              : 
    3571              : #ifdef SIGPIPE
    3572            0 :             case SIGPIPE:
    3573              :               /* SIGPIPE is a special case.  It happens in -pipe mode
    3574              :                  when the compiler dies before the preprocessor is
    3575              :                  done, or the assembler dies before the compiler is
    3576              :                  done.  There's generally been an error already, and
    3577              :                  this is just fallout.  So don't generate another
    3578              :                  error unless we would otherwise have succeeded.  */
    3579            0 :               if (signal_count || greatest_status >= MIN_FATAL_STATUS)
    3580              :                 {
    3581            0 :                   signal_count++;
    3582            0 :                   ret_code = -1;
    3583            0 :                   break;
    3584              :                 }
    3585              : #endif
    3586              :               /* FALLTHROUGH */
    3587              : 
    3588            0 :             default:
    3589              :               /* The inferior failed to catch the signal.  */
    3590            0 :               internal_error_no_backtrace ("%s signal terminated program %s",
    3591              :                                            strsignal (WTERMSIG (status)),
    3592            0 :                                            commands[i].prog);
    3593              :             }
    3594       549289 :         else if (WIFEXITED (status)
    3595       549289 :                  && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
    3596              :           {
    3597              :             /* For ICEs in cc1, cc1obj, cc1plus see if it is
    3598              :                reproducible or not.  */
    3599        30055 :             const char *p;
    3600        30055 :             if (flag_report_bug
    3601            0 :                 && WEXITSTATUS (status) == ICE_EXIT_CODE
    3602            0 :                 && i == 0
    3603            0 :                 && (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
    3604        30055 :                 && startswith (p + 1, "cc1"))
    3605            0 :               try_generate_repro (commands[0].argv);
    3606        30055 :             if (WEXITSTATUS (status) > greatest_status)
    3607           24 :               greatest_status = WEXITSTATUS (status);
    3608              :             ret_code = -1;
    3609              :           }
    3610              : 
    3611       549289 :         if (report_times || report_times_to_file)
    3612              :           {
    3613            0 :             struct pex_time *pt = &times[i];
    3614            0 :             double ut, st;
    3615              : 
    3616            0 :             ut = ((double) pt->user_seconds
    3617            0 :                   + (double) pt->user_microseconds / 1.0e6);
    3618            0 :             st = ((double) pt->system_seconds
    3619            0 :                   + (double) pt->system_microseconds / 1.0e6);
    3620              : 
    3621            0 :             if (ut + st != 0)
    3622              :               {
    3623            0 :                 if (report_times)
    3624            0 :                   fnotice (stderr, "# %s %.2f %.2f\n",
    3625            0 :                            commands[i].prog, ut, st);
    3626              : 
    3627            0 :                 if (report_times_to_file)
    3628              :                   {
    3629            0 :                     int c = 0;
    3630            0 :                     const char *const *j;
    3631              : 
    3632            0 :                     fprintf (report_times_to_file, "%g %g", ut, st);
    3633              : 
    3634            0 :                     for (j = &commands[i].prog; *j; j = &commands[i].argv[++c])
    3635              :                       {
    3636              :                         const char *p;
    3637            0 :                         for (p = *j; *p; ++p)
    3638            0 :                           if (*p == '"' || *p == '\\' || *p == '$'
    3639            0 :                               || ISSPACE (*p))
    3640              :                             break;
    3641              : 
    3642            0 :                         if (*p)
    3643              :                           {
    3644            0 :                             fprintf (report_times_to_file, " \"");
    3645            0 :                             for (p = *j; *p; ++p)
    3646              :                               {
    3647            0 :                                 if (*p == '"' || *p == '\\' || *p == '$')
    3648            0 :                                   fputc ('\\', report_times_to_file);
    3649            0 :                                 fputc (*p, report_times_to_file);
    3650              :                               }
    3651            0 :                             fputc ('"', report_times_to_file);
    3652              :                           }
    3653              :                         else
    3654            0 :                           fprintf (report_times_to_file, " %s", *j);
    3655              :                       }
    3656              : 
    3657            0 :                     fputc ('\n', report_times_to_file);
    3658              :                   }
    3659              :               }
    3660              :           }
    3661              :       }
    3662              : 
    3663       549289 :    if (commands[0].argv[0] != commands[0].prog)
    3664       546634 :      free (const_cast<char *> (commands[0].argv[0]));
    3665              : 
    3666              :     return ret_code;
    3667              :   }
    3668              : }
    3669              : 
    3670              : static struct switchstr *switches;
    3671              : 
    3672              : static int n_switches;
    3673              : 
    3674              : static int n_switches_alloc;
    3675              : 
    3676              : /* Set to zero if -fcompare-debug is disabled, positive if it's
    3677              :    enabled and we're running the first compilation, negative if it's
    3678              :    enabled and we're running the second compilation.  For most of the
    3679              :    time, it's in the range -1..1, but it can be temporarily set to 2
    3680              :    or 3 to indicate that the -fcompare-debug flags didn't come from
    3681              :    the command-line, but rather from the GCC_COMPARE_DEBUG environment
    3682              :    variable, until a synthesized -fcompare-debug flag is added to the
    3683              :    command line.  */
    3684              : int compare_debug;
    3685              : 
    3686              : /* Set to nonzero if we've seen the -fcompare-debug-second flag.  */
    3687              : int compare_debug_second;
    3688              : 
    3689              : /* Set to the flags that should be passed to the second compilation in
    3690              :    a -fcompare-debug compilation.  */
    3691              : const char *compare_debug_opt;
    3692              : 
    3693              : static struct switchstr *switches_debug_check[2];
    3694              : 
    3695              : static int n_switches_debug_check[2];
    3696              : 
    3697              : static int n_switches_alloc_debug_check[2];
    3698              : 
    3699              : static char *debug_check_temp_file[2];
    3700              : 
    3701              : /* Language is one of three things:
    3702              : 
    3703              :    1) The name of a real programming language.
    3704              :    2) NULL, indicating that no one has figured out
    3705              :    what it is yet.
    3706              :    3) '*', indicating that the file should be passed
    3707              :    to the linker.  */
    3708              : struct infile
    3709              : {
    3710              :   const char *name;
    3711              :   const char *language;
    3712              :   struct compiler *incompiler;
    3713              :   bool compiled;
    3714              :   bool preprocessed;
    3715              :   bool artificial;
    3716              : };
    3717              : 
    3718              : /* Also a vector of input files specified.  */
    3719              : 
    3720              : static struct infile *infiles;
    3721              : 
    3722              : int n_infiles;
    3723              : 
    3724              : static int n_infiles_alloc;
    3725              : 
    3726              : /* True if undefined environment variables encountered during spec processing
    3727              :    are ok to ignore, typically when we're running for --help or --version.  */
    3728              : 
    3729              : static bool spec_undefvar_allowed;
    3730              : 
    3731              : /* True if multiple input files are being compiled to a single
    3732              :    assembly file.  */
    3733              : 
    3734              : static bool combine_inputs;
    3735              : 
    3736              : /* This counts the number of libraries added by lang_specific_driver, so that
    3737              :    we can tell if there were any user supplied any files or libraries.  */
    3738              : 
    3739              : static int added_libraries;
    3740              : 
    3741              : /* And a vector of corresponding output files is made up later.  */
    3742              : 
    3743              : const char **outfiles;
    3744              : 
    3745              : #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3746              : 
    3747              : /* Convert NAME to a new name if it is the standard suffix.  DO_EXE
    3748              :    is true if we should look for an executable suffix.  DO_OBJ
    3749              :    is true if we should look for an object suffix.  */
    3750              : 
    3751              : static const char *
    3752              : convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
    3753              :                   int do_obj ATTRIBUTE_UNUSED)
    3754              : {
    3755              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3756              :   int i;
    3757              : #endif
    3758              :   int len;
    3759              : 
    3760              :   if (name == NULL)
    3761              :     return NULL;
    3762              : 
    3763              :   len = strlen (name);
    3764              : 
    3765              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    3766              :   /* Convert x.o to x.obj if TARGET_OBJECT_SUFFIX is ".obj".  */
    3767              :   if (do_obj && len > 2
    3768              :       && name[len - 2] == '.'
    3769              :       && name[len - 1] == 'o')
    3770              :     {
    3771              :       obstack_grow (&obstack, name, len - 2);
    3772              :       obstack_grow0 (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    3773              :       name = XOBFINISH (&obstack, const char *);
    3774              :     }
    3775              : #endif
    3776              : 
    3777              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3778              :   /* If there is no filetype, make it the executable suffix (which includes
    3779              :      the ".").  But don't get confused if we have just "-o".  */
    3780              :   if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || not_actual_file_p (name))
    3781              :     return name;
    3782              : 
    3783              :   for (i = len - 1; i >= 0; i--)
    3784              :     if (IS_DIR_SEPARATOR (name[i]))
    3785              :       break;
    3786              : 
    3787              :   for (i++; i < len; i++)
    3788              :     if (name[i] == '.')
    3789              :       return name;
    3790              : 
    3791              :   obstack_grow (&obstack, name, len);
    3792              :   obstack_grow0 (&obstack, TARGET_EXECUTABLE_SUFFIX,
    3793              :                  strlen (TARGET_EXECUTABLE_SUFFIX));
    3794              :   name = XOBFINISH (&obstack, const char *);
    3795              : #endif
    3796              : 
    3797              :   return name;
    3798              : }
    3799              : #endif
    3800              : 
    3801              : /* Display the command line switches accepted by gcc.  */
    3802              : static void
    3803            4 : display_help (void)
    3804              : {
    3805            4 :   printf (_("Usage: %s [options] file...\n"), progname);
    3806            4 :   fputs (_("Options:\n"), stdout);
    3807              : 
    3808            4 :   fputs (_("  -pass-exit-codes         Exit with highest error code from a phase.\n"), stdout);
    3809            4 :   fputs (_("  --help                   Display this information.\n"), stdout);
    3810            4 :   fputs (_("  --target-help            Display target specific command line options "
    3811              :            "(including assembler and linker options).\n"), stdout);
    3812            4 :   fputs (_("  --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].\n"), stdout);
    3813            4 :   fputs (_("                           Display specific types of command line options.\n"), stdout);
    3814            4 :   if (! verbose_flag)
    3815            1 :     fputs (_("  (Use '-v --help' to display command line options of sub-processes).\n"), stdout);
    3816            4 :   fputs (_("  --version                Display compiler version information.\n"), stdout);
    3817            4 :   fputs (_("  -dumpspecs               Display all of the built in spec strings.\n"), stdout);
    3818            4 :   fputs (_("  -dumpversion             Display the version of the compiler.\n"), stdout);
    3819            4 :   fputs (_("  -dumpmachine             Display the compiler's target processor.\n"), stdout);
    3820            4 :   fputs (_("  -foffload=<targets>      Specify offloading targets.\n"), stdout);
    3821            4 :   fputs (_("  -print-search-dirs       Display the directories in the compiler's search path.\n"), stdout);
    3822            4 :   fputs (_("  -print-libgcc-file-name  Display the name of the compiler's companion library.\n"), stdout);
    3823            4 :   fputs (_("  -print-file-name=<lib>   Display the full path to library <lib>.\n"), stdout);
    3824            4 :   fputs (_("  -print-prog-name=<prog>  Display the full path to compiler component <prog>.\n"), stdout);
    3825            4 :   fputs (_("\
    3826              :   -print-multiarch         Display the target's normalized GNU triplet, used as\n\
    3827              :                            a component in the library path.\n"), stdout);
    3828            4 :   fputs (_("  -print-multi-directory   Display the root directory for versions of libgcc.\n"), stdout);
    3829            4 :   fputs (_("\
    3830              :   -print-multi-lib         Display the mapping between command line options and\n\
    3831              :                            multiple library search directories.\n"), stdout);
    3832            4 :   fputs (_("  -print-multi-os-directory Display the relative path to OS libraries.\n"), stdout);
    3833            4 :   fputs (_("  -print-sysroot           Display the target libraries directory.\n"), stdout);
    3834            4 :   fputs (_("  -print-sysroot-headers-suffix Display the sysroot suffix used to find headers.\n"), stdout);
    3835            4 :   fputs (_("  -Wa,<options>            Pass comma-separated <options> on to the assembler.\n"), stdout);
    3836            4 :   fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor.\n"), stdout);
    3837            4 :   fputs (_("  -Wl,<options>            Pass comma-separated <options> on to the linker.\n"), stdout);
    3838            4 :   fputs (_("  -Xassembler <arg>        Pass <arg> on to the assembler.\n"), stdout);
    3839            4 :   fputs (_("  -Xpreprocessor <arg>     Pass <arg> on to the preprocessor.\n"), stdout);
    3840            4 :   fputs (_("  -Xlinker <arg>           Pass <arg> on to the linker.\n"), stdout);
    3841            4 :   fputs (_("  -save-temps              Do not delete intermediate files.\n"), stdout);
    3842            4 :   fputs (_("  -save-temps=<arg>        Do not delete intermediate files.\n"), stdout);
    3843            4 :   fputs (_("\
    3844              :   -no-canonical-prefixes   Do not canonicalize paths when building relative\n\
    3845              :                            prefixes to other gcc components.\n"), stdout);
    3846            4 :   fputs (_("  -pipe                    Use pipes rather than intermediate files.\n"), stdout);
    3847            4 :   fputs (_("  -time                    Time the execution of each subprocess.\n"), stdout);
    3848            4 :   fputs (_("  -specs=<file>            Override built-in specs with the contents of <file>.\n"), stdout);
    3849            4 :   fputs (_("  -std=<standard>          Assume that the input sources are for <standard>.\n"), stdout);
    3850            4 :   fputs (_("\
    3851              :   --sysroot=<directory>    Use <directory> as the root directory for headers\n\
    3852              :                            and libraries.\n"), stdout);
    3853            4 :   fputs (_("  -B <directory>           Add <directory> to the compiler's search paths.\n"), stdout);
    3854            4 :   fputs (_("  -v                       Display the programs invoked by the compiler.\n"), stdout);
    3855            4 :   fputs (_("  -###                     Like -v but options quoted and commands not executed.\n"), stdout);
    3856            4 :   fputs (_("  -E                       Preprocess only; do not compile, assemble or link.\n"), stdout);
    3857            4 :   fputs (_("  -S                       Compile only; do not assemble or link.\n"), stdout);
    3858            4 :   fputs (_("  -c                       Compile and assemble, but do not link.\n"), stdout);
    3859            4 :   fputs (_("  -o <file>                Place the output into <file>.\n"), stdout);
    3860            4 :   fputs (_("  -pie                     Create a dynamically linked position independent\n\
    3861              :                            executable.\n"), stdout);
    3862            4 :   fputs (_("  -shared                  Create a shared library.\n"), stdout);
    3863            4 :   fputs (_("\
    3864              :   -x <language>            Specify the language of the following input files.\n\
    3865              :                            Permissible languages include: c c++ assembler none\n\
    3866              :                            'none' means revert to the default behavior of\n\
    3867              :                            guessing the language based on the file's extension.\n\
    3868              : "), stdout);
    3869              : 
    3870            4 :   printf (_("\
    3871              : \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
    3872              :  passed on to the various sub-processes invoked by %s.  In order to pass\n\
    3873              :  other options on to these processes the -W<letter> options must be used.\n\
    3874              : "), progname);
    3875              : 
    3876              :   /* The rest of the options are displayed by invocations of the various
    3877              :      sub-processes.  */
    3878            4 : }
    3879              : 
    3880              : static void
    3881            0 : add_preprocessor_option (const char *option, int len)
    3882              : {
    3883            0 :   preprocessor_options.safe_push (save_string (option, len));
    3884            0 : }
    3885              : 
    3886              : static void
    3887          196 : add_assembler_option (const char *option, int len)
    3888              : {
    3889          196 :   assembler_options.safe_push (save_string (option, len));
    3890          196 : }
    3891              : 
    3892              : static void
    3893           82 : add_linker_option (const char *option, int len)
    3894              : {
    3895           82 :   linker_options.safe_push (save_string (option, len));
    3896           82 : }
    3897              : 
    3898              : /* Allocate space for an input file in infiles.  */
    3899              : 
    3900              : static void
    3901       913435 : alloc_infile (void)
    3902              : {
    3903       913435 :   if (n_infiles_alloc == 0)
    3904              :     {
    3905       303838 :       n_infiles_alloc = 16;
    3906       303838 :       infiles = XNEWVEC (struct infile, n_infiles_alloc);
    3907              :     }
    3908       609597 :   else if (n_infiles_alloc == n_infiles)
    3909              :     {
    3910          247 :       n_infiles_alloc *= 2;
    3911          247 :       infiles = XRESIZEVEC (struct infile, infiles, n_infiles_alloc);
    3912              :     }
    3913       913435 : }
    3914              : 
    3915              : /* Store an input file with the given NAME and LANGUAGE in
    3916              :    infiles.  */
    3917              : 
    3918              : static void
    3919       609598 : add_infile (const char *name, const char *language, bool art = false)
    3920              : {
    3921       609598 :   alloc_infile ();
    3922       609598 :   infiles[n_infiles].name = name;
    3923       609598 :   infiles[n_infiles].artificial = art;
    3924       609598 :   infiles[n_infiles++].language = language;
    3925       609598 : }
    3926              : 
    3927              : /* Allocate space for a switch in switches.  */
    3928              : 
    3929              : static void
    3930      7786931 : alloc_switch (void)
    3931              : {
    3932      7786931 :   if (n_switches_alloc == 0)
    3933              :     {
    3934       304152 :       n_switches_alloc = 16;
    3935       304152 :       switches = XNEWVEC (struct switchstr, n_switches_alloc);
    3936              :     }
    3937      7482779 :   else if (n_switches_alloc == n_switches)
    3938              :     {
    3939       276546 :       n_switches_alloc *= 2;
    3940       276546 :       switches = XRESIZEVEC (struct switchstr, switches, n_switches_alloc);
    3941              :     }
    3942      7786931 : }
    3943              : 
    3944              : /* Save an option OPT with N_ARGS arguments in array ARGS, marking it
    3945              :    as validated if VALIDATED and KNOWN if it is an internal switch.  */
    3946              : 
    3947              : static void
    3948      6904599 : save_switch (const char *opt, size_t n_args, const char *const *args,
    3949              :              bool validated, bool known)
    3950              : {
    3951      6904599 :   alloc_switch ();
    3952      6904599 :   switches[n_switches].part1 = opt + 1;
    3953      6904599 :   if (n_args == 0)
    3954      5340834 :     switches[n_switches].args = 0;
    3955              :   else
    3956              :     {
    3957      1563765 :       switches[n_switches].args = XNEWVEC (const char *, n_args + 1);
    3958      1563765 :       memcpy (switches[n_switches].args, args, n_args * sizeof (const char *));
    3959      1563765 :       switches[n_switches].args[n_args] = NULL;
    3960              :     }
    3961              : 
    3962      6904599 :   switches[n_switches].live_cond = 0;
    3963      6904599 :   switches[n_switches].validated = validated;
    3964      6904599 :   switches[n_switches].known = known;
    3965      6904599 :   switches[n_switches].ordering = 0;
    3966      6904599 :   n_switches++;
    3967      6904599 : }
    3968              : 
    3969              : /* Set the SOURCE_DATE_EPOCH environment variable to the current time if it is
    3970              :    not set already.  */
    3971              : 
    3972              : static void
    3973          635 : set_source_date_epoch_envvar ()
    3974              : {
    3975              :   /* Array size is 21 = ceil(log_10(2^64)) + 1 to hold string representations
    3976              :      of 64 bit integers.  */
    3977          635 :   char source_date_epoch[21];
    3978          635 :   time_t tt;
    3979              : 
    3980          635 :   errno = 0;
    3981          635 :   tt = time (NULL);
    3982          635 :   if (tt < (time_t) 0 || errno != 0)
    3983            0 :     tt = (time_t) 0;
    3984              : 
    3985          635 :   snprintf (source_date_epoch, 21, "%llu", (unsigned long long) tt);
    3986              :   /* Using setenv instead of xputenv because we want the variable to remain
    3987              :      after finalizing so that it's still set in the second run when using
    3988              :      -fcompare-debug.  */
    3989          635 :   setenv ("SOURCE_DATE_EPOCH", source_date_epoch, 0);
    3990          635 : }
    3991              : 
    3992              : /* Handle an option DECODED that is unknown to the option-processing
    3993              :    machinery.  */
    3994              : 
    3995              : static bool
    3996          699 : driver_unknown_option_callback (const struct cl_decoded_option *decoded)
    3997              : {
    3998          699 :   const char *opt = decoded->arg;
    3999          699 :   if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
    4000           95 :       && !(decoded->errors & CL_ERR_NEGATIVE))
    4001              :     {
    4002              :       /* Leave unknown -Wno-* options for the compiler proper, to be
    4003              :          diagnosed only if there are warnings.  */
    4004           94 :       save_switch (decoded->canonical_option[0],
    4005           94 :                    decoded->canonical_option_num_elements - 1,
    4006              :                    &decoded->canonical_option[1], false, true);
    4007           94 :       return false;
    4008              :     }
    4009          605 :   if (decoded->opt_index == OPT_SPECIAL_unknown)
    4010              :     {
    4011              :       /* Give it a chance to define it a spec file.  */
    4012          605 :       save_switch (decoded->canonical_option[0],
    4013          605 :                    decoded->canonical_option_num_elements - 1,
    4014              :                    &decoded->canonical_option[1], false, false);
    4015          605 :       return false;
    4016              :     }
    4017              :   else
    4018              :     return true;
    4019              : }
    4020              : 
    4021              : /* Handle an option DECODED that is not marked as CL_DRIVER.
    4022              :    LANG_MASK will always be CL_DRIVER.  */
    4023              : 
    4024              : static void
    4025      4475397 : driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
    4026              :                             unsigned int lang_mask ATTRIBUTE_UNUSED)
    4027              : {
    4028              :   /* At this point, non-driver options are accepted (and expected to
    4029              :      be passed down by specs) unless marked to be rejected by the
    4030              :      driver.  Options to be rejected by the driver but accepted by the
    4031              :      compilers proper are treated just like completely unknown
    4032              :      options.  */
    4033      4475397 :   const struct cl_option *option = &cl_options[decoded->opt_index];
    4034              : 
    4035      4475397 :   if (option->cl_reject_driver)
    4036            0 :     error ("unrecognized command-line option %qs",
    4037            0 :            decoded->orig_option_with_args_text);
    4038              :   else
    4039      4475397 :     save_switch (decoded->canonical_option[0],
    4040      4475397 :                  decoded->canonical_option_num_elements - 1,
    4041              :                  &decoded->canonical_option[1], false, true);
    4042      4475397 : }
    4043              : 
    4044              : static const char *spec_lang = 0;
    4045              : static int last_language_n_infiles;
    4046              : 
    4047              : 
    4048              : /* Check that GCC is configured to support the offload target.  */
    4049              : 
    4050              : static bool
    4051           99 : check_offload_target_name (const char *target, ptrdiff_t len)
    4052              : {
    4053           99 :   const char *n, *c = OFFLOAD_TARGETS;
    4054          198 :   while (c)
    4055              :     {
    4056           99 :       n = strchr (c, ',');
    4057           99 :       if (n == NULL)
    4058           99 :         n = strchr (c, '\0');
    4059           99 :       if (len == n - c && strncmp (target, c, n - c) == 0)
    4060              :         break;
    4061           99 :       c = *n ? n + 1 : NULL;
    4062              :     }
    4063           99 :   if (!c)
    4064              :     {
    4065           99 :       auto_vec<const char*> candidates;
    4066           99 :       size_t olen = strlen (OFFLOAD_TARGETS) + 1;
    4067           99 :       char *cand = XALLOCAVEC (char, olen);
    4068           99 :       memcpy (cand, OFFLOAD_TARGETS, olen);
    4069           99 :       for (c = strtok (cand, ","); c; c = strtok (NULL, ","))
    4070            0 :         candidates.safe_push (c);
    4071           99 :       candidates.safe_push ("default");
    4072           99 :       candidates.safe_push ("disable");
    4073              : 
    4074           99 :       char *target2 = XALLOCAVEC (char, len + 1);
    4075           99 :       memcpy (target2, target, len);
    4076           99 :       target2[len] = '\0';
    4077              : 
    4078           99 :       error ("GCC is not configured to support %qs as %<-foffload=%> argument",
    4079              :              target2);
    4080              : 
    4081           99 :       char *s;
    4082           99 :       const char *hint = candidates_list_and_hint (target2, s, candidates);
    4083           99 :       if (hint)
    4084            0 :         inform (UNKNOWN_LOCATION,
    4085              :                 "valid %<-foffload=%> arguments are: %s; "
    4086              :                 "did you mean %qs?", s, hint);
    4087              :       else
    4088           99 :         inform (UNKNOWN_LOCATION, "valid %<-foffload=%> arguments are: %s", s);
    4089           99 :       XDELETEVEC (s);
    4090           99 :       return false;
    4091           99 :     }
    4092              :   return true;
    4093              : }
    4094              : 
    4095              : /* Sanity check for -foffload-options.  */
    4096              : 
    4097              : static void
    4098           27 : check_foffload_target_names (const char *arg)
    4099              : {
    4100           27 :   const char *cur, *next, *end;
    4101              :   /* If option argument starts with '-' then no target is specified and we
    4102              :      do not need to parse it.  */
    4103           27 :   if (arg[0] == '-')
    4104              :     return;
    4105            0 :   end = strchr (arg, '=');
    4106            0 :   if (end == NULL)
    4107              :     {
    4108            0 :       error ("%<=%>options missing after %<-foffload-options=%>target");
    4109            0 :       return;
    4110              :     }
    4111              : 
    4112              :   cur = arg;
    4113            0 :   while (cur < end)
    4114              :     {
    4115            0 :       next = strchr (cur, ',');
    4116            0 :       if (next == NULL)
    4117            0 :         next = end;
    4118            0 :       next = (next > end) ? end : next;
    4119              : 
    4120              :       /* Retain non-supported targets after printing an error as those will not
    4121              :          be processed; each enabled target only processes its triplet.  */
    4122            0 :       check_offload_target_name (cur, next - cur);
    4123            0 :       cur = next + 1;
    4124              :    }
    4125              : }
    4126              : 
    4127              : /* Parse -foffload option argument.  */
    4128              : 
    4129              : static void
    4130         2833 : handle_foffload_option (const char *arg)
    4131              : {
    4132         2833 :   const char *c, *cur, *n, *next, *end;
    4133         2833 :   char *target;
    4134              : 
    4135              :   /* If option argument starts with '-' then no target is specified and we
    4136              :      do not need to parse it.  */
    4137         2833 :   if (arg[0] == '-')
    4138              :     return;
    4139              : 
    4140         1994 :   end = strchr (arg, '=');
    4141         1994 :   if (end == NULL)
    4142         1994 :     end = strchr (arg, '\0');
    4143         1994 :   cur = arg;
    4144              : 
    4145         1994 :   while (cur < end)
    4146              :     {
    4147         1994 :       next = strchr (cur, ',');
    4148         1994 :       if (next == NULL)
    4149         1994 :         next = end;
    4150         1994 :       next = (next > end) ? end : next;
    4151              : 
    4152         1994 :       target = XNEWVEC (char, next - cur + 1);
    4153         1994 :       memcpy (target, cur, next - cur);
    4154         1994 :       target[next - cur] = '\0';
    4155              : 
    4156              :       /* Reset offloading list and continue.  */
    4157         1994 :       if (strcmp (target, "default") == 0)
    4158              :         {
    4159            0 :           free (offload_targets);
    4160            0 :           offload_targets = NULL;
    4161            0 :           goto next_item;
    4162              :         }
    4163              : 
    4164              :       /* If 'disable' is passed to the option, clean the list of
    4165              :          offload targets and return, even if more targets follow.
    4166              :          Likewise if GCC is not configured to support that offload target.  */
    4167         1994 :       if (strcmp (target, "disable") == 0
    4168         1994 :           || !check_offload_target_name (target, next - cur))
    4169              :         {
    4170         1994 :           free (offload_targets);
    4171         1994 :           offload_targets = xstrdup ("");
    4172         1994 :           return;
    4173              :         }
    4174              : 
    4175            0 :       if (!offload_targets)
    4176              :         {
    4177            0 :           offload_targets = target;
    4178            0 :           target = NULL;
    4179              :         }
    4180              :       else
    4181              :         {
    4182              :           /* Check that the target hasn't already presented in the list.  */
    4183              :           c = offload_targets;
    4184            0 :           do
    4185              :             {
    4186            0 :               n = strchr (c, ':');
    4187            0 :               if (n == NULL)
    4188            0 :                 n = strchr (c, '\0');
    4189              : 
    4190            0 :               if (next - cur == n - c && strncmp (c, target, n - c) == 0)
    4191              :                 break;
    4192              : 
    4193            0 :               c = n + 1;
    4194              :             }
    4195            0 :           while (*n);
    4196              : 
    4197              :           /* If duplicate is not found, append the target to the list.  */
    4198            0 :           if (c > n)
    4199              :             {
    4200            0 :               size_t offload_targets_len = strlen (offload_targets);
    4201            0 :               offload_targets
    4202            0 :                 = XRESIZEVEC (char, offload_targets,
    4203              :                               offload_targets_len + 1 + next - cur + 1);
    4204            0 :               offload_targets[offload_targets_len++] = ':';
    4205            0 :               memcpy (offload_targets + offload_targets_len, target, next - cur + 1);
    4206              :             }
    4207              :         }
    4208            0 : next_item:
    4209            0 :       cur = next + 1;
    4210            0 :       XDELETEVEC (target);
    4211              :     }
    4212              : }
    4213              : 
    4214              : /* Forward certain options to offloading compilation.  */
    4215              : 
    4216              : static void
    4217            0 : forward_offload_option (size_t opt_index, const char *arg, bool validated)
    4218              : {
    4219            0 :   switch (opt_index)
    4220              :     {
    4221            0 :     case OPT_l:
    4222              :       /* Use a '_GCC_' prefix and standard name ('-l_GCC_m' irrespective of the
    4223              :          host's 'MATH_LIBRARY', for example), so that the 'mkoffload's can tell
    4224              :          this has been synthesized here, and translate/drop as necessary.  */
    4225              :       /* Note that certain libraries ('-lc', '-lgcc', '-lgomp', for example)
    4226              :          are injected by default in offloading compilation, and therefore not
    4227              :          forwarded here.  */
    4228              :       /* GCC libraries.  */
    4229            0 :       if (/* '-lgfortran' */ strcmp (arg, "gfortran") == 0
    4230            0 :           || /* '-lstdc++' */ strcmp (arg, "stdc++") == 0)
    4231            0 :         save_switch (concat ("-foffload-options=-l_GCC_", arg, NULL),
    4232              :                      0, NULL, validated, true);
    4233              :       /* Other libraries.  */
    4234              :       else
    4235              :         {
    4236              :           /* The case will need special consideration where on the host
    4237              :              '!need_math', but for offloading compilation still need
    4238              :              '-foffload-options=-l_GCC_m'.  The problem is that we don't get
    4239              :              here anything like '-lm', because it's not synthesized in
    4240              :              'gcc/fortran/gfortranspec.cc:lang_specific_driver', for example.
    4241              :              Generally synthesizing '-foffload-options=-l_GCC_m' etc. in the
    4242              :              language specific drivers is non-trivial, needs very careful
    4243              :              review of their options handling.  However, this issue is not
    4244              :              actually relevant for the current set of supported host/offloading
    4245              :              configurations.  */
    4246            0 :           int need_math = (MATH_LIBRARY[0] != '\0');
    4247            0 :           if (/* '-lm' */ (need_math && strcmp (arg, MATH_LIBRARY) == 0))
    4248            0 :             save_switch ("-foffload-options=-l_GCC_m",
    4249              :                          0, NULL, validated, true);
    4250              :         }
    4251            0 :       break;
    4252            0 :     default:
    4253            0 :       gcc_unreachable ();
    4254              :     }
    4255            0 : }
    4256              : 
    4257              : /* Handle a driver option; arguments and return value as for
    4258              :    handle_option.  */
    4259              : 
    4260              : static bool
    4261      2783916 : driver_handle_option (struct gcc_options *opts,
    4262              :                       struct gcc_options *opts_set,
    4263              :                       const struct cl_decoded_option *decoded,
    4264              :                       unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
    4265              :                       location_t loc,
    4266              :                       const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
    4267              :                       diagnostics::context *dc,
    4268              :                       void (*) (void))
    4269              : {
    4270      2783916 :   size_t opt_index = decoded->opt_index;
    4271      2783916 :   const char *arg = decoded->arg;
    4272      2783916 :   const char *compare_debug_replacement_opt;
    4273      2783916 :   int value = decoded->value;
    4274      2783916 :   bool validated = false;
    4275      2783916 :   bool do_save = true;
    4276              : 
    4277      2783916 :   gcc_assert (opts == &global_options);
    4278      2783916 :   gcc_assert (opts_set == &global_options_set);
    4279      2783916 :   gcc_assert (static_cast<diagnostics::kind> (kind)
    4280              :               == diagnostics::kind::unspecified);
    4281      2783916 :   gcc_assert (loc == UNKNOWN_LOCATION);
    4282      2783916 :   gcc_assert (dc == global_dc);
    4283              : 
    4284      2783916 :   switch (opt_index)
    4285              :     {
    4286            1 :     case OPT_dumpspecs:
    4287            1 :       {
    4288            1 :         struct spec_list *sl;
    4289            1 :         init_spec ();
    4290           47 :         for (sl = specs; sl; sl = sl->next)
    4291           46 :           printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
    4292            1 :         if (link_command_spec)
    4293            1 :           printf ("*link_command:\n%s\n\n", link_command_spec);
    4294            1 :         exit (0);
    4295              :       }
    4296              : 
    4297          280 :     case OPT_dumpversion:
    4298          280 :       printf ("%s\n", spec_version);
    4299          280 :       exit (0);
    4300              : 
    4301            0 :     case OPT_dumpmachine:
    4302            0 :       printf ("%s\n", spec_machine);
    4303            0 :       exit (0);
    4304              : 
    4305            0 :     case OPT_dumpfullversion:
    4306            0 :       printf ("%s\n", BASEVER);
    4307            0 :       exit (0);
    4308              : 
    4309           78 :     case OPT__version:
    4310           78 :       print_version = 1;
    4311              : 
    4312              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4313           78 :       if (is_cpp_driver)
    4314            0 :         add_preprocessor_option ("--version", strlen ("--version"));
    4315           78 :       add_assembler_option ("--version", strlen ("--version"));
    4316           78 :       add_linker_option ("--version", strlen ("--version"));
    4317           78 :       break;
    4318              : 
    4319            5 :     case OPT__completion_:
    4320            5 :       validated = true;
    4321            5 :       completion = decoded->arg;
    4322            5 :       break;
    4323              : 
    4324            4 :     case OPT__help:
    4325            4 :       print_help_list = 1;
    4326              : 
    4327              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4328            4 :       if (is_cpp_driver)
    4329            0 :         add_preprocessor_option ("--help", 6);
    4330            4 :       add_assembler_option ("--help", 6);
    4331            4 :       add_linker_option ("--help", 6);
    4332            4 :       break;
    4333              : 
    4334           74 :     case OPT__help_:
    4335           74 :       print_subprocess_help = 2;
    4336           74 :       break;
    4337              : 
    4338            0 :     case OPT__target_help:
    4339            0 :       print_subprocess_help = 1;
    4340              : 
    4341              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4342            0 :       if (is_cpp_driver)
    4343            0 :         add_preprocessor_option ("--target-help", 13);
    4344            0 :       add_assembler_option ("--target-help", 13);
    4345            0 :       add_linker_option ("--target-help", 13);
    4346            0 :       break;
    4347              : 
    4348              :     case OPT__no_sysroot_suffix:
    4349              :     case OPT_pass_exit_codes:
    4350              :     case OPT_print_search_dirs:
    4351              :     case OPT_print_autofdo_gcov_version:
    4352              :     case OPT_print_file_name_:
    4353              :     case OPT_print_prog_name_:
    4354              :     case OPT_print_multi_lib:
    4355              :     case OPT_print_multi_directory:
    4356              :     case OPT_print_sysroot:
    4357              :     case OPT_print_multi_os_directory:
    4358              :     case OPT_print_multiarch:
    4359              :     case OPT_print_sysroot_headers_suffix:
    4360              :     case OPT_time:
    4361              :     case OPT_wrapper:
    4362              :       /* These options set the variables specified in common.opt
    4363              :          automatically, and do not need to be saved for spec
    4364              :          processing.  */
    4365              :       do_save = false;
    4366              :       break;
    4367              : 
    4368          392 :     case OPT_print_libgcc_file_name:
    4369          392 :       print_file_name = "libgcc.a";
    4370          392 :       do_save = false;
    4371          392 :       break;
    4372              : 
    4373            0 :     case OPT_fuse_ld_bfd:
    4374            0 :        use_ld = ".bfd";
    4375            0 :        break;
    4376              : 
    4377            0 :     case OPT_fuse_ld_gold:
    4378            0 :        use_ld = ".gold";
    4379            0 :        break;
    4380              : 
    4381            0 :     case OPT_fuse_ld_mold:
    4382            0 :        use_ld = ".mold";
    4383            0 :        break;
    4384              : 
    4385            0 :     case OPT_fuse_ld_wild:
    4386            0 :        use_ld = ".wild";
    4387            0 :        break;
    4388              : 
    4389            0 :     case OPT_fcompare_debug_second:
    4390            0 :       compare_debug_second = 1;
    4391            0 :       break;
    4392              : 
    4393          629 :     case OPT_fcompare_debug:
    4394          629 :       switch (value)
    4395              :         {
    4396            0 :         case 0:
    4397            0 :           compare_debug_replacement_opt = "-fcompare-debug=";
    4398            0 :           arg = "";
    4399            0 :           goto compare_debug_with_arg;
    4400              : 
    4401          629 :         case 1:
    4402          629 :           compare_debug_replacement_opt = "-fcompare-debug=-gtoggle";
    4403          629 :           arg = "-gtoggle";
    4404          629 :           goto compare_debug_with_arg;
    4405              : 
    4406            0 :         default:
    4407            0 :           gcc_unreachable ();
    4408              :         }
    4409            6 :       break;
    4410              : 
    4411            6 :     case OPT_fcompare_debug_:
    4412            6 :       compare_debug_replacement_opt = decoded->canonical_option[0];
    4413          635 :     compare_debug_with_arg:
    4414          635 :       gcc_assert (decoded->canonical_option_num_elements == 1);
    4415          635 :       gcc_assert (arg != NULL);
    4416          635 :       if (*arg)
    4417          635 :         compare_debug = 1;
    4418              :       else
    4419            0 :         compare_debug = -1;
    4420          635 :       if (compare_debug < 0)
    4421            0 :         compare_debug_opt = NULL;
    4422              :       else
    4423          635 :         compare_debug_opt = arg;
    4424          635 :       save_switch (compare_debug_replacement_opt, 0, NULL, validated, true);
    4425          635 :       set_source_date_epoch_envvar ();
    4426          635 :       return true;
    4427              : 
    4428       277861 :     case OPT_fdiagnostics_color_:
    4429       277861 :       diagnostic_color_init (dc, value);
    4430       277861 :       break;
    4431              : 
    4432       268159 :     case OPT_fdiagnostics_urls_:
    4433       268159 :       diagnostic_urls_init (dc, value);
    4434       268159 :       break;
    4435              : 
    4436            0 :     case OPT_fdiagnostics_show_highlight_colors:
    4437            0 :       dc->set_show_highlight_colors (value);
    4438            0 :       break;
    4439              : 
    4440            0 :     case OPT_fdiagnostics_format_:
    4441            0 :         {
    4442            0 :           const char *basename = get_diagnostic_file_output_basename (*opts);
    4443            0 :           gcc_assert (dc);
    4444            0 :           diagnostics::output_format_init (*dc,
    4445              :                                            opts->x_main_input_filename, basename,
    4446              :                                            (enum diagnostics_output_format)value,
    4447            0 :                                            opts->x_flag_diagnostics_json_formatting);
    4448            0 :           break;
    4449              :         }
    4450              : 
    4451            0 :     case OPT_fdiagnostics_add_output_:
    4452            0 :       handle_OPT_fdiagnostics_add_output_ (*opts, *dc, arg, loc);
    4453            0 :       break;
    4454              : 
    4455            0 :     case OPT_fdiagnostics_set_output_:
    4456            0 :       handle_OPT_fdiagnostics_set_output_ (*opts, *dc, arg, loc);
    4457            0 :       break;
    4458              : 
    4459       296893 :     case OPT_fdiagnostics_text_art_charset_:
    4460       296893 :       dc->set_text_art_charset ((enum diagnostic_text_art_charset)value);
    4461       296893 :       break;
    4462              : 
    4463              :     case OPT_Wa_:
    4464              :       {
    4465              :         int prev, j;
    4466              :         /* Pass the rest of this option to the assembler.  */
    4467              : 
    4468              :         /* Split the argument at commas.  */
    4469              :         prev = 0;
    4470          653 :         for (j = 0; arg[j]; j++)
    4471          604 :           if (arg[j] == ',')
    4472              :             {
    4473            0 :               add_assembler_option (arg + prev, j - prev);
    4474            0 :               prev = j + 1;
    4475              :             }
    4476              : 
    4477              :         /* Record the part after the last comma.  */
    4478           49 :         add_assembler_option (arg + prev, j - prev);
    4479              :       }
    4480           49 :       do_save = false;
    4481           49 :       break;
    4482              : 
    4483              :     case OPT_Wp_:
    4484              :       {
    4485              :         int prev, j;
    4486              :         /* Pass the rest of this option to the preprocessor.  */
    4487              : 
    4488              :         /* Split the argument at commas.  */
    4489              :         prev = 0;
    4490            0 :         for (j = 0; arg[j]; j++)
    4491            0 :           if (arg[j] == ',')
    4492              :             {
    4493            0 :               add_preprocessor_option (arg + prev, j - prev);
    4494            0 :               prev = j + 1;
    4495              :             }
    4496              : 
    4497              :         /* Record the part after the last comma.  */
    4498            0 :         add_preprocessor_option (arg + prev, j - prev);
    4499              :       }
    4500            0 :       do_save = false;
    4501            0 :       break;
    4502              : 
    4503              :     case OPT_Wl_:
    4504              :       {
    4505              :         int prev, j;
    4506              :         /* Split the argument at commas.  */
    4507              :         prev = 0;
    4508       128515 :         for (j = 0; arg[j]; j++)
    4509       120785 :           if (arg[j] == ',')
    4510              :             {
    4511           54 :               add_infile (save_string (arg + prev, j - prev), "*");
    4512           54 :               prev = j + 1;
    4513              :             }
    4514              :         /* Record the part after the last comma.  */
    4515         7730 :         add_infile (arg + prev, "*");
    4516         7730 :         if (strcmp (arg, "-z,lazy") == 0 || strcmp (arg, "-z,norelro") == 0)
    4517           12 :           avoid_linker_hardening_p = true;
    4518              :       }
    4519              :       do_save = false;
    4520              :       break;
    4521              : 
    4522           12 :     case OPT_z:
    4523           12 :       if (strcmp (arg, "lazy") == 0 || strcmp (arg, "norelro") == 0)
    4524           12 :         avoid_linker_hardening_p = true;
    4525              :       break;
    4526              : 
    4527            0 :     case OPT_Xlinker:
    4528            0 :       add_infile (arg, "*");
    4529            0 :       do_save = false;
    4530            0 :       break;
    4531              : 
    4532            0 :     case OPT_Xpreprocessor:
    4533            0 :       add_preprocessor_option (arg, strlen (arg));
    4534            0 :       do_save = false;
    4535            0 :       break;
    4536              : 
    4537           65 :     case OPT_Xassembler:
    4538           65 :       add_assembler_option (arg, strlen (arg));
    4539           65 :       do_save = false;
    4540           65 :       break;
    4541              : 
    4542       273898 :     case OPT_l:
    4543              :       /* POSIX allows separation of -l and the lib arg; canonicalize
    4544              :          by concatenating -l with its arg */
    4545       273898 :       add_infile (concat ("-l", arg, NULL), "*");
    4546              : 
    4547              :       /* Forward to offloading compilation '-l[...]' flags for standard,
    4548              :          well-known libraries.  */
    4549              :       /* Doing this processing here means that we don't get to see libraries
    4550              :          injected via specs, such as '-lquadmath' injected via
    4551              :          '[build]/[target]/libgfortran/libgfortran.spec'.  However, this issue
    4552              :          is not actually relevant for the current set of host/offloading
    4553              :          configurations.  */
    4554       273898 :       if (ENABLE_OFFLOADING)
    4555              :         forward_offload_option (opt_index, arg, validated);
    4556              : 
    4557       273898 :       do_save = false;
    4558       273898 :       break;
    4559              : 
    4560       271538 :     case OPT_L:
    4561              :       /* Similarly, canonicalize -L for linkers that may not accept
    4562              :          separate arguments.  */
    4563       271538 :       save_switch (concat ("-L", arg, NULL), 0, NULL, validated, true);
    4564       271538 :       return true;
    4565              : 
    4566            0 :     case OPT_F:
    4567              :       /* Likewise -F.  */
    4568            0 :       save_switch (concat ("-F", arg, NULL), 0, NULL, validated, true);
    4569            0 :       return true;
    4570              : 
    4571          416 :     case OPT_save_temps:
    4572          416 :       if (!save_temps_flag)
    4573          410 :         save_temps_flag = SAVE_TEMPS_DUMP;
    4574              :       validated = true;
    4575              :       break;
    4576              : 
    4577           58 :     case OPT_save_temps_:
    4578           58 :       if (strcmp (arg, "cwd") == 0)
    4579           29 :         save_temps_flag = SAVE_TEMPS_CWD;
    4580           29 :       else if (strcmp (arg, "obj") == 0
    4581            0 :                || strcmp (arg, "object") == 0)
    4582           29 :         save_temps_flag = SAVE_TEMPS_OBJ;
    4583              :       else
    4584            0 :         fatal_error (input_location, "%qs is an unknown %<-save-temps%> option",
    4585            0 :                      decoded->orig_option_with_args_text);
    4586           58 :       save_temps_overrides_dumpdir = true;
    4587           58 :       break;
    4588              : 
    4589        20520 :     case OPT_dumpdir:
    4590        20520 :       free (dumpdir);
    4591        20520 :       dumpdir = xstrdup (arg);
    4592        20520 :       save_temps_overrides_dumpdir = false;
    4593        20520 :       break;
    4594              : 
    4595        21977 :     case OPT_dumpbase:
    4596        21977 :       free (dumpbase);
    4597        21977 :       dumpbase = xstrdup (arg);
    4598        21977 :       break;
    4599              : 
    4600          256 :     case OPT_dumpbase_ext:
    4601          256 :       free (dumpbase_ext);
    4602          256 :       dumpbase_ext = xstrdup (arg);
    4603          256 :       break;
    4604              : 
    4605              :     case OPT_no_canonical_prefixes:
    4606              :       /* Already handled as a special case, so ignored here.  */
    4607              :       do_save = false;
    4608              :       break;
    4609              : 
    4610              :     case OPT_pipe:
    4611              :       validated = true;
    4612              :       /* These options set the variables specified in common.opt
    4613              :          automatically, but do need to be saved for spec
    4614              :          processing.  */
    4615              :       break;
    4616              : 
    4617            3 :     case OPT_specs_:
    4618            3 :       {
    4619            3 :         struct user_specs *user = XNEW (struct user_specs);
    4620              : 
    4621            3 :         user->next = (struct user_specs *) 0;
    4622            3 :         user->filename = arg;
    4623            3 :         if (user_specs_tail)
    4624            0 :           user_specs_tail->next = user;
    4625              :         else
    4626            3 :           user_specs_head = user;
    4627            3 :         user_specs_tail = user;
    4628              :       }
    4629            3 :       validated = true;
    4630            3 :       break;
    4631              : 
    4632            0 :     case OPT__sysroot_:
    4633            0 :       target_system_root = arg;
    4634            0 :       target_system_root_changed = 1;
    4635              :       /* Saving this option is useful to let self-specs decide to
    4636              :          provide a default one.  */
    4637            0 :       do_save = true;
    4638            0 :       validated = true;
    4639            0 :       break;
    4640              : 
    4641            0 :     case OPT_time_:
    4642            0 :       if (report_times_to_file)
    4643            0 :         fclose (report_times_to_file);
    4644            0 :       report_times_to_file = fopen (arg, "a");
    4645            0 :       do_save = false;
    4646            0 :       break;
    4647              : 
    4648         8068 :     case OPT_truncate:
    4649         8068 :       totruncate_file = arg;
    4650         8068 :       do_save = false;
    4651         8068 :       break;
    4652              : 
    4653          641 :     case OPT____:
    4654              :       /* "-###"
    4655              :          This is similar to -v except that there is no execution
    4656              :          of the commands and the echoed arguments are quoted.  It
    4657              :          is intended for use in shell scripts to capture the
    4658              :          driver-generated command line.  */
    4659          641 :       verbose_only_flag++;
    4660          641 :       verbose_flag = 1;
    4661          641 :       do_save = false;
    4662          641 :       break;
    4663              : 
    4664       496998 :     case OPT_B:
    4665       496998 :       {
    4666       496998 :         size_t len = strlen (arg);
    4667              : 
    4668              :         /* Catch the case where the user has forgotten to append a
    4669              :            directory separator to the path.  Note, they may be using
    4670              :            -B to add an executable name prefix, eg "i386-elf-", in
    4671              :            order to distinguish between multiple installations of
    4672              :            GCC in the same directory.  Hence we must check to see
    4673              :            if appending a directory separator actually makes a
    4674              :            valid directory name.  */
    4675       496998 :         if (!IS_DIR_SEPARATOR (arg[len - 1])
    4676       496998 :             && is_directory (arg))
    4677              :           {
    4678       102357 :             char *tmp = XNEWVEC (char, len + 2);
    4679       102357 :             strcpy (tmp, arg);
    4680       102357 :             tmp[len] = DIR_SEPARATOR;
    4681       102357 :             tmp[++len] = 0;
    4682       102357 :             arg = tmp;
    4683              :           }
    4684              : 
    4685       496998 :         add_prefix (&exec_prefixes, arg, NULL,
    4686              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4687       496998 :         add_prefix (&startfile_prefixes, arg, NULL,
    4688              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4689       496998 :         add_prefix (&include_prefixes, arg, NULL,
    4690              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4691              :       }
    4692       496998 :       validated = true;
    4693       496998 :       break;
    4694              : 
    4695         2958 :     case OPT_E:
    4696         2958 :       have_E = true;
    4697         2958 :       break;
    4698              : 
    4699        49267 :     case OPT_x:
    4700        49267 :       spec_lang = arg;
    4701        49267 :       if (!strcmp (spec_lang, "none"))
    4702              :         /* Suppress the warning if -xnone comes after the last input
    4703              :            file, because alternate command interfaces like g++ might
    4704              :            find it useful to place -xnone after each input file.  */
    4705        13630 :         spec_lang = 0;
    4706              :       else
    4707        35637 :         last_language_n_infiles = n_infiles;
    4708              :       do_save = false;
    4709              :       break;
    4710              : 
    4711       276630 :     case OPT_o:
    4712       276630 :       have_o = 1;
    4713              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
    4714              :       arg = convert_filename (arg, ! have_c, 0);
    4715              : #endif
    4716       276630 :       output_file = arg;
    4717              :       /* On some systems, ld cannot handle "-o" without a space.  So
    4718              :          split the option from its argument.  */
    4719       276630 :       save_switch ("-o", 1, &arg, validated, true);
    4720       276630 :       return true;
    4721              : 
    4722         2209 :     case OPT_pie:
    4723              : #ifdef ENABLE_DEFAULT_PIE
    4724              :       /* -pie is turned on by default.  */
    4725              :       validated = true;
    4726              : #endif
    4727              :       /* FALLTHROUGH */
    4728         2209 :     case OPT_r:
    4729         2209 :     case OPT_shared:
    4730         2209 :     case OPT_no_pie:
    4731         2209 :       avoid_linker_hardening_p = true;
    4732         2209 :       break;
    4733              : 
    4734          101 :     case OPT_static:
    4735          101 :       static_p = true;
    4736          101 :       break;
    4737              : 
    4738              :     case OPT_static_libgcc:
    4739              :     case OPT_shared_libgcc:
    4740              :     case OPT_static_libgfortran:
    4741              :     case OPT_static_libquadmath:
    4742              :     case OPT_static_libphobos:
    4743              :     case OPT_static_libga68:
    4744              :     case OPT_static_libgm2:
    4745              :     case OPT_static_libstdc__:
    4746              :       /* These are always valid; gcc.cc itself understands the first two
    4747              :          gfortranspec.cc understands -static-libgfortran,
    4748              :          libgfortran.spec handles -static-libquadmath,
    4749              :          a68spec.cc understands -static-libga68,
    4750              :          d-spec.cc understands -static-libphobos,
    4751              :          gm2spec.cc understands -static-libgm2,
    4752              :          and g++spec.cc understands -static-libstdc++.  */
    4753              :       validated = true;
    4754              :       break;
    4755              : 
    4756           78 :     case OPT_fwpa:
    4757           78 :       flag_wpa = "";
    4758           78 :       break;
    4759              : 
    4760           27 :     case OPT_foffload_options_:
    4761           27 :       check_foffload_target_names (arg);
    4762           27 :       break;
    4763              : 
    4764         2833 :     case OPT_foffload_:
    4765         2833 :       handle_foffload_option (arg);
    4766         2833 :       if (arg[0] == '-' || NULL != strchr (arg, '='))
    4767          839 :         save_switch (concat ("-foffload-options=", arg, NULL),
    4768              :                      0, NULL, validated, true);
    4769              :       do_save = false;
    4770              :       break;
    4771              : 
    4772            0 :     case OPT_gcodeview:
    4773            0 :       add_infile ("--pdb=", "*");
    4774            0 :       break;
    4775              : 
    4776              :     default:
    4777              :       /* Various driver options need no special processing at this
    4778              :          point, having been handled in a prescan above or being
    4779              :          handled by specs.  */
    4780              :       break;
    4781              :     }
    4782              : 
    4783      1671384 :   if (do_save)
    4784      1877523 :     save_switch (decoded->canonical_option[0],
    4785      1877523 :                  decoded->canonical_option_num_elements - 1,
    4786              :                  &decoded->canonical_option[1], validated, true);
    4787              :   return true;
    4788              : }
    4789              : 
    4790              : /* Return true if F2 is F1 followed by a single suffix, i.e., by a
    4791              :    period and additional characters other than a period.  */
    4792              : 
    4793              : static inline bool
    4794        86950 : adds_single_suffix_p (const char *f2, const char *f1)
    4795              : {
    4796        86950 :   size_t len = strlen (f1);
    4797              : 
    4798        86950 :   return (strncmp (f1, f2, len) == 0
    4799        77798 :           && f2[len] == '.'
    4800       164275 :           && strchr (f2 + len + 1, '.') == NULL);
    4801              : }
    4802              : 
    4803              : /* Put the driver's standard set of option handlers in *HANDLERS.  */
    4804              : 
    4805              : static void
    4806       882614 : set_option_handlers (struct cl_option_handlers *handlers)
    4807              : {
    4808       882614 :   handlers->unknown_option_callback = driver_unknown_option_callback;
    4809       882614 :   handlers->wrong_lang_callback = driver_wrong_lang_callback;
    4810       882614 :   handlers->num_handlers = 3;
    4811       882614 :   handlers->handlers[0].handler = driver_handle_option;
    4812       882614 :   handlers->handlers[0].mask = CL_DRIVER;
    4813       882614 :   handlers->handlers[1].handler = common_handle_option;
    4814       882614 :   handlers->handlers[1].mask = CL_COMMON;
    4815       882614 :   handlers->handlers[2].handler = target_handle_option;
    4816       882614 :   handlers->handlers[2].mask = CL_TARGET;
    4817            0 : }
    4818              : 
    4819              : 
    4820              : /* Return the index into infiles for the single non-library
    4821              :    non-lto-wpa input file, -1 if there isn't any, or -2 if there is
    4822              :    more than one.  */
    4823              : static inline int
    4824       151387 : single_input_file_index ()
    4825              : {
    4826       151387 :   int ret = -1;
    4827              : 
    4828       508031 :   for (int i = 0; i < n_infiles; i++)
    4829              :     {
    4830       369154 :       if (infiles[i].language
    4831       260888 :           && (infiles[i].language[0] == '*'
    4832        45596 :               || (flag_wpa
    4833        17010 :                   && strcmp (infiles[i].language, "lto") == 0)))
    4834       232302 :         continue;
    4835              : 
    4836       136852 :       if (ret != -1)
    4837              :         return -2;
    4838              : 
    4839              :       ret = i;
    4840              :     }
    4841              : 
    4842              :   return ret;
    4843              : }
    4844              : 
    4845              : /* Create the vector `switches' and its contents.
    4846              :    Store its length in `n_switches'.  */
    4847              : 
    4848              : static void
    4849       304123 : process_command (unsigned int decoded_options_count,
    4850              :                  struct cl_decoded_option *decoded_options)
    4851              : {
    4852       304123 :   const char *temp;
    4853       304123 :   char *temp1;
    4854       304123 :   char *tooldir_prefix, *tooldir_prefix2;
    4855       304123 :   char *(*get_relative_prefix) (const char *, const char *,
    4856              :                                 const char *) = NULL;
    4857       304123 :   struct cl_option_handlers handlers;
    4858       304123 :   unsigned int j;
    4859              : 
    4860       304123 :   gcc_exec_prefix = env.get ("GCC_EXEC_PREFIX");
    4861              : 
    4862       304123 :   n_switches = 0;
    4863       304123 :   n_infiles = 0;
    4864       304123 :   added_libraries = 0;
    4865              : 
    4866              :   /* Figure compiler version from version string.  */
    4867              : 
    4868       304123 :   compiler_version = temp1 = xstrdup (version_string);
    4869              : 
    4870      2128861 :   for (; *temp1; ++temp1)
    4871              :     {
    4872      2128861 :       if (*temp1 == ' ')
    4873              :         {
    4874       304123 :           *temp1 = '\0';
    4875       304123 :           break;
    4876              :         }
    4877              :     }
    4878              : 
    4879              :   /* Handle any -no-canonical-prefixes flag early, to assign the function
    4880              :      that builds relative prefixes.  This function creates default search
    4881              :      paths that are needed later in normal option handling.  */
    4882              : 
    4883      6900004 :   for (j = 1; j < decoded_options_count; j++)
    4884              :     {
    4885      6595881 :       if (decoded_options[j].opt_index == OPT_no_canonical_prefixes)
    4886              :         {
    4887              :           get_relative_prefix = make_relative_prefix_ignore_links;
    4888              :           break;
    4889              :         }
    4890              :     }
    4891       304123 :   if (! get_relative_prefix)
    4892       304123 :     get_relative_prefix = make_relative_prefix;
    4893              : 
    4894              :   /* Set up the default search paths.  If there is no GCC_EXEC_PREFIX,
    4895              :      see if we can create it from the pathname specified in
    4896              :      decoded_options[0].arg.  */
    4897              : 
    4898       304123 :   gcc_libexec_prefix = standard_libexec_prefix;
    4899              : #ifndef VMS
    4900              :   /* FIXME: make_relative_prefix doesn't yet work for VMS.  */
    4901       304123 :   if (!gcc_exec_prefix)
    4902              :     {
    4903        29493 :       gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg,
    4904              :                                              standard_bindir_prefix,
    4905              :                                              standard_exec_prefix);
    4906        29493 :       gcc_libexec_prefix = get_relative_prefix (decoded_options[0].arg,
    4907              :                                              standard_bindir_prefix,
    4908              :                                              standard_libexec_prefix);
    4909        29493 :       if (gcc_exec_prefix)
    4910        29493 :         xputenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
    4911              :     }
    4912              :   else
    4913              :     {
    4914              :       /* make_relative_prefix requires a program name, but
    4915              :          GCC_EXEC_PREFIX is typically a directory name with a trailing
    4916              :          / (which is ignored by make_relative_prefix), so append a
    4917              :          program name.  */
    4918       274630 :       char *tmp_prefix = concat (gcc_exec_prefix, "gcc", NULL);
    4919       274630 :       gcc_libexec_prefix = get_relative_prefix (tmp_prefix,
    4920              :                                                 standard_exec_prefix,
    4921              :                                                 standard_libexec_prefix);
    4922              : 
    4923              :       /* The path is unrelocated, so fallback to the original setting.  */
    4924       274630 :       if (!gcc_libexec_prefix)
    4925       274285 :         gcc_libexec_prefix = standard_libexec_prefix;
    4926              : 
    4927       274630 :       free (tmp_prefix);
    4928              :     }
    4929              : #else
    4930              : #endif
    4931              :   /* From this point onward, gcc_exec_prefix is non-null if the toolchain
    4932              :      is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX
    4933              :      or an automatically created GCC_EXEC_PREFIX from
    4934              :      decoded_options[0].arg.  */
    4935              : 
    4936              :   /* Do language-specific adjustment/addition of flags.  */
    4937       304123 :   lang_specific_driver (&decoded_options, &decoded_options_count,
    4938              :                         &added_libraries);
    4939              : 
    4940       304119 :   if (gcc_exec_prefix)
    4941              :     {
    4942       304119 :       int len = strlen (gcc_exec_prefix);
    4943              : 
    4944       304119 :       if (len > (int) sizeof ("/lib/gcc/") - 1
    4945       304119 :           && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
    4946              :         {
    4947       304119 :           temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
    4948       304119 :           if (IS_DIR_SEPARATOR (*temp)
    4949       304119 :               && filename_ncmp (temp + 1, "lib", 3) == 0
    4950       304119 :               && IS_DIR_SEPARATOR (temp[4])
    4951       608238 :               && filename_ncmp (temp + 5, "gcc", 3) == 0)
    4952       304119 :             len -= sizeof ("/lib/gcc/") - 1;
    4953              :         }
    4954              : 
    4955       304119 :       set_std_prefix (gcc_exec_prefix, len);
    4956       304119 :       add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
    4957              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4958       304119 :       add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
    4959              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4960              :     }
    4961              : 
    4962              :   /* COMPILER_PATH and LIBRARY_PATH have values
    4963              :      that are lists of directory names with colons.  */
    4964              : 
    4965       304119 :   temp = env.get ("COMPILER_PATH");
    4966       304119 :   if (temp)
    4967              :     {
    4968        20356 :       const char *startp, *endp;
    4969        20356 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4970              : 
    4971        20356 :       startp = endp = temp;
    4972      1839544 :       while (1)
    4973              :         {
    4974      1839544 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4975              :             {
    4976        32839 :               strncpy (nstore, startp, endp - startp);
    4977        32839 :               if (endp == startp)
    4978            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4979        32839 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4980              :                 {
    4981            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4982            0 :                   nstore[endp - startp + 1] = 0;
    4983              :                 }
    4984              :               else
    4985        32839 :                 nstore[endp - startp] = 0;
    4986        32839 :               add_prefix (&exec_prefixes, nstore, 0,
    4987              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4988        32839 :               add_prefix (&include_prefixes, nstore, 0,
    4989              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4990        32839 :               if (*endp == 0)
    4991              :                 break;
    4992        12483 :               endp = startp = endp + 1;
    4993              :             }
    4994              :           else
    4995      1806705 :             endp++;
    4996              :         }
    4997              :     }
    4998              : 
    4999       304119 :   temp = env.get (LIBRARY_PATH_ENV);
    5000       304119 :   if (temp && *cross_compile == '0')
    5001              :     {
    5002        21719 :       const char *startp, *endp;
    5003        21719 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    5004              : 
    5005        21719 :       startp = endp = temp;
    5006      3737084 :       while (1)
    5007              :         {
    5008      3737084 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    5009              :             {
    5010       155648 :               strncpy (nstore, startp, endp - startp);
    5011       155648 :               if (endp == startp)
    5012            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    5013       155648 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    5014              :                 {
    5015         1363 :                   nstore[endp - startp] = DIR_SEPARATOR;
    5016         1363 :                   nstore[endp - startp + 1] = 0;
    5017              :                 }
    5018              :               else
    5019       154285 :                 nstore[endp - startp] = 0;
    5020       155648 :               add_prefix (&startfile_prefixes, nstore, NULL,
    5021              :                           PREFIX_PRIORITY_LAST, 0, 1);
    5022       155648 :               if (*endp == 0)
    5023              :                 break;
    5024       133929 :               endp = startp = endp + 1;
    5025              :             }
    5026              :           else
    5027      3581436 :             endp++;
    5028              :         }
    5029              :     }
    5030              : 
    5031              :   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
    5032       304119 :   temp = env.get ("LPATH");
    5033       304119 :   if (temp && *cross_compile == '0')
    5034              :     {
    5035            0 :       const char *startp, *endp;
    5036            0 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    5037              : 
    5038            0 :       startp = endp = temp;
    5039            0 :       while (1)
    5040              :         {
    5041            0 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    5042              :             {
    5043            0 :               strncpy (nstore, startp, endp - startp);
    5044            0 :               if (endp == startp)
    5045            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    5046            0 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    5047              :                 {
    5048            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    5049            0 :                   nstore[endp - startp + 1] = 0;
    5050              :                 }
    5051              :               else
    5052            0 :                 nstore[endp - startp] = 0;
    5053            0 :               add_prefix (&startfile_prefixes, nstore, NULL,
    5054              :                           PREFIX_PRIORITY_LAST, 0, 1);
    5055            0 :               if (*endp == 0)
    5056              :                 break;
    5057            0 :               endp = startp = endp + 1;
    5058              :             }
    5059              :           else
    5060            0 :             endp++;
    5061              :         }
    5062              :     }
    5063              : 
    5064              :   /* Process the options and store input files and switches in their
    5065              :      vectors.  */
    5066              : 
    5067       304119 :   last_language_n_infiles = -1;
    5068              : 
    5069       304119 :   set_option_handlers (&handlers);
    5070              : 
    5071      5981274 :   for (j = 1; j < decoded_options_count; j++)
    5072              :     {
    5073      5868743 :       switch (decoded_options[j].opt_index)
    5074              :         {
    5075       191588 :         case OPT_S:
    5076       191588 :         case OPT_c:
    5077       191588 :         case OPT_E:
    5078       191588 :           have_c = 1;
    5079       191588 :           break;
    5080              :         }
    5081      5868743 :       if (have_c)
    5082              :         break;
    5083              :     }
    5084              : 
    5085      7311699 :   for (j = 1; j < decoded_options_count; j++)
    5086              :     {
    5087      7007861 :       if (decoded_options[j].opt_index == OPT_SPECIAL_input_file)
    5088              :         {
    5089       327566 :           const char *arg = decoded_options[j].arg;
    5090              : 
    5091              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    5092              :           arg = convert_filename (arg, 0, access (arg, F_OK));
    5093              : #endif
    5094       327566 :           add_infile (arg, spec_lang,
    5095       327566 :                       decoded_options[j].mask == CL_DRIVER);
    5096              : 
    5097       327566 :           continue;
    5098       327566 :         }
    5099              : 
    5100      6680295 :       read_cmdline_option (&global_options, &global_options_set,
    5101              :                            decoded_options + j, UNKNOWN_LOCATION,
    5102              :                            CL_DRIVER, &handlers, global_dc);
    5103              :     }
    5104              : 
    5105              :   /* If the user didn't specify any, default to all configured offload
    5106              :      targets.  */
    5107       303838 :   if (ENABLE_OFFLOADING && offload_targets == NULL)
    5108              :     {
    5109              :       handle_foffload_option (OFFLOAD_TARGETS);
    5110              : #if OFFLOAD_DEFAULTED
    5111              :       offload_targets_default = true;
    5112              : #endif
    5113              :     }
    5114              : 
    5115              :   /* TODO: check if -static -pie works and maybe use it.  */
    5116       303838 :   if (flag_hardened)
    5117              :     {
    5118           92 :       if (!avoid_linker_hardening_p && !static_p)
    5119              :         {
    5120              : #if defined HAVE_LD_PIE && defined LD_PIE_SPEC
    5121           68 :           save_switch (LD_PIE_SPEC, 0, NULL, /*validated=*/true, /*known=*/false);
    5122              : #endif
    5123              :           /* These are passed straight down to collect2 so we have to break
    5124              :              it up like this.  */
    5125           68 :           if (HAVE_LD_NOW_SUPPORT)
    5126              :             {
    5127           68 :               add_infile ("-z", "*");
    5128           68 :               add_infile ("now", "*");
    5129              :             }
    5130           68 :           if (HAVE_LD_RELRO_SUPPORT)
    5131              :             {
    5132           68 :               add_infile ("-z", "*");
    5133           68 :               add_infile ("relro", "*");
    5134              :             }
    5135              :         }
    5136              :       /* We can't use OPT_Whardened yet.  Sigh.  */
    5137              :       else
    5138           24 :         warning_at (UNKNOWN_LOCATION, 0,
    5139              :                     "linker hardening options not enabled by %<-fhardened%> "
    5140              :                     "because other link options were specified on the command "
    5141              :                     "line");
    5142              :     }
    5143              : 
    5144              :   /* Handle -gtoggle as it would later in toplev.cc:process_options to
    5145              :      make the debug-level-gt spec function work as expected.  */
    5146       303838 :   if (flag_gtoggle)
    5147              :     {
    5148            4 :       if (debug_info_level == DINFO_LEVEL_NONE)
    5149            0 :         debug_info_level = DINFO_LEVEL_NORMAL;
    5150              :       else
    5151            4 :         debug_info_level = DINFO_LEVEL_NONE;
    5152              :     }
    5153              : 
    5154       303838 :   if (output_file
    5155       276629 :       && strcmp (output_file, "-") != 0
    5156       276466 :       && strcmp (output_file, HOST_BIT_BUCKET) != 0)
    5157              :     {
    5158              :       int i;
    5159       822469 :       for (i = 0; i < n_infiles; i++)
    5160       264947 :         if ((!infiles[i].language || infiles[i].language[0] != '*')
    5161       574284 :             && canonical_filename_eq (infiles[i].name, output_file))
    5162            1 :           fatal_error (input_location,
    5163              :                        "input file %qs is the same as output file",
    5164              :                        output_file);
    5165              :     }
    5166              : 
    5167       303837 :   if (output_file != NULL && output_file[0] == '\0')
    5168            0 :     fatal_error (input_location, "output filename may not be empty");
    5169              : 
    5170              :   /* -dumpdir and -save-temps=* both specify the location of aux/dump
    5171              :      outputs; the one that appears last prevails.  When compiling
    5172              :      multiple sources, an explicit dumpbase (minus -ext) may be
    5173              :      combined with an explicit or implicit dumpdir, whereas when
    5174              :      linking, a specified or implied link output name (minus
    5175              :      extension) may be combined with a prevailing -save-temps=* or an
    5176              :      otherwise implied dumpdir, but not override a prevailing
    5177              :      -dumpdir.  Primary outputs (e.g., linker output when linking
    5178              :      without -o, or .i, .s or .o outputs when processing multiple
    5179              :      inputs with -E, -S or -c, respectively) are NOT affected by these
    5180              :      -save-temps=/-dump* options, always landing in the current
    5181              :      directory and with the same basename as the input when an output
    5182              :      name is not given, but when they're intermediate outputs, they
    5183              :      are named like other aux outputs, so the options affect their
    5184              :      location and name.
    5185              : 
    5186              :      Here are some examples.  There are several more in the
    5187              :      documentation of -o and -dump*, and some quite exhaustive tests
    5188              :      in gcc.misc-tests/outputs.exp.
    5189              : 
    5190              :      When compiling any number of sources, no -dump* nor
    5191              :      -save-temps=*, all outputs in cwd without prefix:
    5192              : 
    5193              :      # gcc -c b.c -gsplit-dwarf
    5194              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5195              : 
    5196              :      # gcc -c b.c d.c -gsplit-dwarf
    5197              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5198              :      && cc1 [-dumpdir ./] -dumpbase d.c -dumpbase-ext .c # d.o d.dwo
    5199              : 
    5200              :      When compiling and linking, no -dump* nor -save-temps=*, .o
    5201              :      outputs are temporary, aux outputs land in the dir of the output,
    5202              :      prefixed with the basename of the linker output:
    5203              : 
    5204              :      # gcc b.c d.c -o ab -gsplit-dwarf
    5205              :      -> cc1 -dumpdir ab- -dumpbase b.c -dumpbase-ext .c # ab-b.dwo
    5206              :      && cc1 -dumpdir ab- -dumpbase d.c -dumpbase-ext .c # ab-d.dwo
    5207              :      && link ... -o ab
    5208              : 
    5209              :      # gcc b.c d.c [-o a.out] -gsplit-dwarf
    5210              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.dwo
    5211              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.dwo
    5212              :      && link ... [-o a.out]
    5213              : 
    5214              :      When compiling and linking, a prevailing -dumpdir fully overrides
    5215              :      the prefix of aux outputs given by the output name:
    5216              : 
    5217              :      # gcc -dumpdir f b.c d.c -gsplit-dwarf [-o [dir/]whatever]
    5218              :      -> cc1 -dumpdir f -dumpbase b.c -dumpbase-ext .c # fb.dwo
    5219              :      && cc1 -dumpdir f -dumpbase d.c -dumpbase-ext .c # fd.dwo
    5220              :      && link ... [-o whatever]
    5221              : 
    5222              :      When compiling multiple inputs, an explicit -dumpbase is combined
    5223              :      with -dumpdir, affecting aux outputs, but not the .o outputs:
    5224              : 
    5225              :      # gcc -dumpdir f -dumpbase g- b.c d.c -gsplit-dwarf -c
    5226              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # b.o fg-b.dwo
    5227              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # d.o fg-d.dwo
    5228              : 
    5229              :      When compiling and linking with -save-temps, the .o outputs that
    5230              :      would have been temporary become aux outputs, so they get
    5231              :      affected by -dump* flags:
    5232              : 
    5233              :      # gcc -dumpdir f -dumpbase g- -save-temps b.c d.c
    5234              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # fg-b.o
    5235              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # fg-d.o
    5236              :      && link
    5237              : 
    5238              :      If -save-temps=* prevails over -dumpdir, however, the explicit
    5239              :      -dumpdir is discarded, as if it wasn't there.  The basename of
    5240              :      the implicit linker output, a.out or a.exe, becomes a- as the aux
    5241              :      output prefix for all compilations:
    5242              : 
    5243              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c
    5244              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.o
    5245              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.o
    5246              :      && link
    5247              : 
    5248              :      A single -dumpbase, applying to multiple inputs, overrides the
    5249              :      linker output name, implied or explicit, as the aux output prefix:
    5250              : 
    5251              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c
    5252              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5253              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5254              :      && link
    5255              : 
    5256              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c -o dir/h.out
    5257              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5258              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5259              :      && link -o dir/h.out
    5260              : 
    5261              :      Now, if the linker output is NOT overridden as a prefix, but
    5262              :      -save-temps=* overrides implicit or explicit -dumpdir, the
    5263              :      effective dump dir combines the dir selected by the -save-temps=*
    5264              :      option with the basename of the specified or implied link output:
    5265              : 
    5266              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c -o dir/h.out
    5267              :      -> cc1 -dumpdir h- -dumpbase b.c -dumpbase-ext .c # h-b.o
    5268              :      && cc1 -dumpdir h- -dumpbase d.c -dumpbase-ext .c # h-d.o
    5269              :      && link -o dir/h.out
    5270              : 
    5271              :      # gcc [-dumpdir f] -save-temps=obj b.c d.c -o dir/h.out
    5272              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5273              :      && cc1 -dumpdir dir/h- -dumpbase d.c -dumpbase-ext .c # dir/h-d.o
    5274              :      && link -o dir/h.out
    5275              : 
    5276              :      But then again, a single -dumpbase applying to multiple inputs
    5277              :      gets used instead of the linker output basename in the combined
    5278              :      dumpdir:
    5279              : 
    5280              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=obj b.c d.c -o dir/h.out
    5281              :      -> cc1 -dumpdir dir/g- -dumpbase b.c -dumpbase-ext .c # dir/g-b.o
    5282              :      && cc1 -dumpdir dir/g- -dumpbase d.c -dumpbase-ext .c # dir/g-d.o
    5283              :      && link -o dir/h.out
    5284              : 
    5285              :      With a single input being compiled, the output basename does NOT
    5286              :      affect the dumpdir prefix.
    5287              : 
    5288              :      # gcc -save-temps=obj b.c -gsplit-dwarf -c -o dir/b.o
    5289              :      -> cc1 -dumpdir dir/ -dumpbase b.c -dumpbase-ext .c # dir/b.o dir/b.dwo
    5290              : 
    5291              :      but when compiling and linking even a single file, it does:
    5292              : 
    5293              :      # gcc -save-temps=obj b.c -o dir/h.out
    5294              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5295              : 
    5296              :      unless an explicit -dumpdir prevails:
    5297              : 
    5298              :      # gcc -save-temps[=obj] -dumpdir g- b.c -o dir/h.out
    5299              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5300              : 
    5301              :   */
    5302              : 
    5303       303837 :   bool explicit_dumpdir = dumpdir;
    5304              : 
    5305       303785 :   if ((!save_temps_overrides_dumpdir && explicit_dumpdir)
    5306       587110 :       || (output_file && not_actual_file_p (output_file)))
    5307              :     {
    5308              :       /* Do nothing.  */
    5309              :     }
    5310              : 
    5311              :   /* If -save-temps=obj and -o name, create the prefix to use for %b.
    5312              :      Otherwise just make -save-temps=obj the same as -save-temps=cwd.  */
    5313       282240 :   else if (save_temps_flag != SAVE_TEMPS_CWD && output_file != NULL)
    5314              :     {
    5315       262554 :       free (dumpdir);
    5316       262554 :       dumpdir = NULL;
    5317       262554 :       temp = lbasename (output_file);
    5318       262554 :       if (temp != output_file)
    5319       105205 :         dumpdir = xstrndup (output_file,
    5320       105205 :                             strlen (output_file) - strlen (temp));
    5321              :     }
    5322        19686 :   else if (dumpdir)
    5323              :     {
    5324            5 :       free (dumpdir);
    5325            5 :       dumpdir = NULL;
    5326              :     }
    5327              : 
    5328       303837 :   if (save_temps_flag)
    5329          468 :     save_temps_flag = SAVE_TEMPS_DUMP;
    5330              : 
    5331              :   /* If there is any pathname component in an explicit -dumpbase, it
    5332              :      overrides dumpdir entirely, so discard it right away.  Although
    5333              :      the presence of an explicit -dumpdir matters for the driver, it
    5334              :      shouldn't matter for other processes, that get all that's needed
    5335              :      from the -dumpdir and -dumpbase always passed to them.  */
    5336       303837 :   if (dumpdir && dumpbase && lbasename (dumpbase) != dumpbase)
    5337              :     {
    5338        20425 :       free (dumpdir);
    5339        20425 :       dumpdir = NULL;
    5340              :     }
    5341              : 
    5342              :   /* Check that dumpbase_ext matches the end of dumpbase, drop it
    5343              :      otherwise.  */
    5344       303837 :   if (dumpbase_ext && dumpbase && *dumpbase)
    5345              :     {
    5346           20 :       int lendb = strlen (dumpbase);
    5347           20 :       int lendbx = strlen (dumpbase_ext);
    5348              : 
    5349              :       /* -dumpbase-ext must be a suffix proper; discard it if it
    5350              :           matches all of -dumpbase, as that would make for an empty
    5351              :           basename.  */
    5352           20 :       if (lendbx >= lendb
    5353           19 :           || strcmp (dumpbase + lendb - lendbx, dumpbase_ext) != 0)
    5354              :         {
    5355            1 :           free (dumpbase_ext);
    5356            1 :           dumpbase_ext = NULL;
    5357              :         }
    5358              :     }
    5359              : 
    5360              :   /* -dumpbase with multiple sources goes into dumpdir.  With a single
    5361              :      source, it does only if linking and if dumpdir was not explicitly
    5362              :      specified.  */
    5363        21977 :   if (dumpbase && *dumpbase
    5364       324340 :       && (single_input_file_index () == -2
    5365        20217 :           || (!have_c && !explicit_dumpdir)))
    5366              :     {
    5367          298 :       char *prefix;
    5368              : 
    5369          298 :       if (dumpbase_ext)
    5370              :         /* We checked that they match above.  */
    5371            6 :         dumpbase[strlen (dumpbase) - strlen (dumpbase_ext)] = '\0';
    5372              : 
    5373          298 :       if (dumpdir)
    5374           13 :         prefix = concat (dumpdir, dumpbase, "-", NULL);
    5375              :       else
    5376          285 :         prefix = concat (dumpbase, "-", NULL);
    5377              : 
    5378          298 :       free (dumpdir);
    5379          298 :       free (dumpbase);
    5380          298 :       free (dumpbase_ext);
    5381          298 :       dumpbase = dumpbase_ext = NULL;
    5382          298 :       dumpdir = prefix;
    5383          298 :       dumpdir_trailing_dash_added = true;
    5384              :     }
    5385              : 
    5386              :   /* If dumpbase was not brought into dumpdir but we're linking, bring
    5387              :      output_file into dumpdir unless dumpdir was explicitly specified.
    5388              :      The test for !explicit_dumpdir is further below, because we want
    5389              :      to use the obase computation for a ghost outbase, passed to
    5390              :      GCC_COLLECT_OPTIONS.  */
    5391       303539 :   else if (!have_c && (!explicit_dumpdir || (dumpbase && !*dumpbase)))
    5392              :     {
    5393              :       /* If we get here, we know dumpbase was not specified, or it was
    5394              :          specified as an empty string.  If it was anything else, it
    5395              :          would have combined with dumpdir above, because the condition
    5396              :          for dumpbase to be used when present is broader than the
    5397              :          condition that gets us here.  */
    5398       112148 :       gcc_assert (!dumpbase || !*dumpbase);
    5399              : 
    5400       112148 :       const char *obase;
    5401       112148 :       char *tofree = NULL;
    5402       112148 :       if (!output_file || not_actual_file_p (output_file))
    5403              :         obase = "a";
    5404              :       else
    5405              :         {
    5406        95860 :           obase = lbasename (output_file);
    5407        95860 :           size_t blen = strlen (obase), xlen;
    5408              :           /* Drop the suffix if it's dumpbase_ext, if given,
    5409              :              otherwise .exe or the target executable suffix, or if the
    5410              :              output was explicitly named a.out, but not otherwise.  */
    5411        95860 :           if (dumpbase_ext
    5412        95860 :               ? (blen > (xlen = strlen (dumpbase_ext))
    5413          227 :                  && strcmp ((temp = (obase + blen - xlen)),
    5414              :                             dumpbase_ext) == 0)
    5415        95633 :               : ((temp = strrchr (obase + 1, '.'))
    5416        93779 :                  && (xlen = strlen (temp))
    5417       189412 :                  && (strcmp (temp, ".exe") == 0
    5418              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    5419              :                      || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
    5420              : #endif
    5421         8589 :                      || strcmp (obase, "a.out") == 0)))
    5422              :             {
    5423        85443 :               tofree = xstrndup (obase, blen - xlen);
    5424        85443 :               obase = tofree;
    5425              :             }
    5426              :         }
    5427              : 
    5428              :       /* We wish to save this basename to the -dumpdir passed through
    5429              :          GCC_COLLECT_OPTIONS within maybe_run_linker, for e.g. LTO,
    5430              :          but we do NOT wish to add it to e.g. %b, so we keep
    5431              :          outbase_length as zero.  */
    5432       112148 :       gcc_assert (!outbase);
    5433       112148 :       outbase_length = 0;
    5434              : 
    5435              :       /* If we're building [dir1/]foo[.exe] out of a single input
    5436              :          [dir2/]foo.c that shares the same basename, dump to
    5437              :          [dir2/]foo.c.* rather than duplicating the basename into
    5438              :          [dir2/]foo-foo.c.*.  */
    5439       112148 :       int idxin;
    5440       112148 :       if (dumpbase
    5441       112148 :           || ((idxin = single_input_file_index ()) >= 0
    5442        86950 :               && adds_single_suffix_p (lbasename (infiles[idxin].name),
    5443              :                                        obase)))
    5444              :         {
    5445        78794 :           if (obase == tofree)
    5446        77034 :             outbase = tofree;
    5447              :           else
    5448              :             {
    5449         1760 :               outbase = xstrdup (obase);
    5450         1760 :               free (tofree);
    5451              :             }
    5452       112148 :           obase = tofree = NULL;
    5453              :         }
    5454              :       else
    5455              :         {
    5456        33354 :           if (dumpdir)
    5457              :             {
    5458        14566 :               char *p = concat (dumpdir, obase, "-", NULL);
    5459        14566 :               free (dumpdir);
    5460        14566 :               dumpdir = p;
    5461              :             }
    5462              :           else
    5463        18788 :             dumpdir = concat (obase, "-", NULL);
    5464              : 
    5465        33354 :           dumpdir_trailing_dash_added = true;
    5466              : 
    5467        33354 :           free (tofree);
    5468        33354 :           obase = tofree = NULL;
    5469              :         }
    5470              : 
    5471       112148 :       if (!explicit_dumpdir || dumpbase)
    5472              :         {
    5473              :           /* Absent -dumpbase and present -dumpbase-ext have been applied
    5474              :              to the linker output name, so compute fresh defaults for each
    5475              :              compilation.  */
    5476       112148 :           free (dumpbase_ext);
    5477       112148 :           dumpbase_ext = NULL;
    5478              :         }
    5479              :     }
    5480              : 
    5481              :   /* Now, if we're compiling, or if we haven't used the dumpbase
    5482              :      above, then outbase (%B) is derived from dumpbase, if given, or
    5483              :      from the output name, given or implied.  We can't precompute
    5484              :      implied output names, but that's ok, since they're derived from
    5485              :      input names.  Just make sure we skip this if dumpbase is the
    5486              :      empty string: we want to use input names then, so don't set
    5487              :      outbase.  */
    5488       303837 :   if ((dumpbase || have_c)
    5489       193079 :       && !(dumpbase && !*dumpbase))
    5490              :     {
    5491       191605 :       gcc_assert (!outbase);
    5492              : 
    5493       191605 :       if (dumpbase)
    5494              :         {
    5495        20205 :           gcc_assert (single_input_file_index () != -2);
    5496              :           /* We do not want lbasename here; dumpbase with dirnames
    5497              :              overrides dumpdir entirely, even if dumpdir is
    5498              :              specified.  */
    5499        20205 :           if (dumpbase_ext)
    5500              :             /* We've already checked above that the suffix matches.  */
    5501           13 :             outbase = xstrndup (dumpbase,
    5502           13 :                                 strlen (dumpbase) - strlen (dumpbase_ext));
    5503              :           else
    5504        20192 :             outbase = xstrdup (dumpbase);
    5505              :         }
    5506       171400 :       else if (output_file && !not_actual_file_p (output_file))
    5507              :         {
    5508       166933 :           outbase = xstrdup (lbasename (output_file));
    5509       166933 :           char *p = strrchr (outbase + 1, '.');
    5510       166933 :           if (p)
    5511       166933 :             *p = '\0';
    5512              :         }
    5513              : 
    5514       191605 :       if (outbase)
    5515       187138 :         outbase_length = strlen (outbase);
    5516              :     }
    5517              : 
    5518              :   /* If there is any pathname component in an explicit -dumpbase, do
    5519              :      not use dumpdir, but retain it to pass it on to the compiler.  */
    5520       303837 :   if (dumpdir)
    5521       124365 :     dumpdir_length = strlen (dumpdir);
    5522              :   else
    5523       179472 :     dumpdir_length = 0;
    5524              : 
    5525              :   /* Check that dumpbase_ext, if still present, still matches the end
    5526              :      of dumpbase, if present, and drop it otherwise.  We only retained
    5527              :      it above when dumpbase was absent to maybe use it to drop the
    5528              :      extension from output_name before combining it with dumpdir.  We
    5529              :      won't deal with -dumpbase-ext when -dumpbase is not explicitly
    5530              :      given, even if just to activate backward-compatible dumpbase:
    5531              :      dropping it on the floor is correct, expected and documented
    5532              :      behavior.  Attempting to deal with a -dumpbase-ext that might
    5533              :      match the end of some input filename, or of the combination of
    5534              :      the output basename with the suffix of the input filename,
    5535              :      possible with an intermediate .gk extension for -fcompare-debug,
    5536              :      is just calling for trouble.  */
    5537       303837 :   if (dumpbase_ext)
    5538              :     {
    5539           22 :       if (!dumpbase || !*dumpbase)
    5540              :         {
    5541            9 :           free (dumpbase_ext);
    5542            9 :           dumpbase_ext = NULL;
    5543              :         }
    5544              :       else
    5545           13 :         gcc_assert (strcmp (dumpbase + strlen (dumpbase)
    5546              :                             - strlen (dumpbase_ext), dumpbase_ext) == 0);
    5547              :     }
    5548              : 
    5549       303837 :   if (save_temps_flag && use_pipes)
    5550              :     {
    5551              :       /* -save-temps overrides -pipe, so that temp files are produced */
    5552            0 :       if (save_temps_flag)
    5553            0 :         warning (0, "%<-pipe%> ignored because %<-save-temps%> specified");
    5554            0 :       use_pipes = 0;
    5555              :     }
    5556              : 
    5557       303837 :   if (!compare_debug)
    5558              :     {
    5559       303202 :       const char *gcd = env.get ("GCC_COMPARE_DEBUG");
    5560              : 
    5561       303202 :       if (gcd && gcd[0] == '-')
    5562              :         {
    5563            0 :           compare_debug = 2;
    5564            0 :           compare_debug_opt = gcd;
    5565              :         }
    5566            0 :       else if (gcd && *gcd && strcmp (gcd, "0"))
    5567              :         {
    5568            0 :           compare_debug = 3;
    5569            0 :           compare_debug_opt = "-gtoggle";
    5570              :         }
    5571              :     }
    5572          635 :   else if (compare_debug < 0)
    5573              :     {
    5574            0 :       compare_debug = 0;
    5575            0 :       gcc_assert (!compare_debug_opt);
    5576              :     }
    5577              : 
    5578              :   /* Set up the search paths.  We add directories that we expect to
    5579              :      contain GNU Toolchain components before directories specified by
    5580              :      the machine description so that we will find GNU components (like
    5581              :      the GNU assembler) before those of the host system.  */
    5582              : 
    5583              :   /* If we don't know where the toolchain has been installed, use the
    5584              :      configured-in locations.  */
    5585       303837 :   if (!gcc_exec_prefix)
    5586              :     {
    5587              : #ifndef OS2
    5588            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
    5589              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5590            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
    5591              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5592            0 :       add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
    5593              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5594              : #endif
    5595            0 :       add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
    5596              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5597              :     }
    5598              : 
    5599       303837 :   gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
    5600       303837 :   tooldir_prefix2 = concat (tooldir_base_prefix, spec_machine,
    5601              :                             dir_separator_str, NULL);
    5602              : 
    5603              :   /* Look for tools relative to the location from which the driver is
    5604              :      running, or, if that is not available, the configured prefix.  */
    5605       303837 :   tooldir_prefix
    5606       607674 :     = concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    5607              :               spec_host_machine, dir_separator_str, spec_version,
    5608              :               accel_dir_suffix, dir_separator_str, tooldir_prefix2, NULL);
    5609       303837 :   free (tooldir_prefix2);
    5610              : 
    5611       303837 :   add_prefix (&exec_prefixes,
    5612       303837 :               concat (tooldir_prefix, "bin", dir_separator_str, NULL),
    5613              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 0);
    5614       303837 :   add_prefix (&startfile_prefixes,
    5615       303837 :               concat (tooldir_prefix, "lib", dir_separator_str, NULL),
    5616              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
    5617       303837 :   free (tooldir_prefix);
    5618              : 
    5619              : #if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
    5620              :   /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
    5621              :      then consider it to relocate with the rest of the GCC installation
    5622              :      if GCC_EXEC_PREFIX is set.
    5623              :      ``make_relative_prefix'' is not compiled for VMS, so don't call it.  */
    5624              :   if (target_system_root && !target_system_root_changed && gcc_exec_prefix)
    5625              :     {
    5626              :       char *tmp_prefix = get_relative_prefix (decoded_options[0].arg,
    5627              :                                               standard_bindir_prefix,
    5628              :                                               target_system_root);
    5629              :       if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
    5630              :         {
    5631              :           target_system_root = tmp_prefix;
    5632              :           target_system_root_changed = 1;
    5633              :         }
    5634              :     }
    5635              : #endif
    5636              : 
    5637              :   /* More prefixes are enabled in main, after we read the specs file
    5638              :      and determine whether this is cross-compilation or not.  */
    5639              : 
    5640       303837 :   if (n_infiles != 0 && n_infiles == last_language_n_infiles && spec_lang != 0)
    5641            0 :     warning (0, "%<-x %s%> after last input file has no effect", spec_lang);
    5642              : 
    5643              :   /* Synthesize -fcompare-debug flag from the GCC_COMPARE_DEBUG
    5644              :      environment variable.  */
    5645       303837 :   if (compare_debug == 2 || compare_debug == 3)
    5646              :     {
    5647            0 :       const char *opt = concat ("-fcompare-debug=", compare_debug_opt, NULL);
    5648            0 :       save_switch (opt, 0, NULL, false, true);
    5649            0 :       compare_debug = 1;
    5650              :     }
    5651              : 
    5652              :   /* Ensure we only invoke each subprocess once.  */
    5653       303837 :   if (n_infiles == 0
    5654         7291 :       && (print_subprocess_help || print_help_list || print_version))
    5655              :     {
    5656              :       /* Create a dummy input file, so that we can pass
    5657              :          the help option on to the various sub-processes.  */
    5658           78 :       add_infile ("help-dummy", "c");
    5659              :     }
    5660              : 
    5661              :   /* Decide if undefined variable references are allowed in specs.  */
    5662              : 
    5663              :   /* -v alone is safe. --version and --help alone or together are safe.  Note
    5664              :      that -v would make them unsafe, as they'd then be run for subprocesses as
    5665              :      well, the location of which might depend on variables possibly coming
    5666              :      from self-specs.  Note also that the command name is counted in
    5667              :      decoded_options_count.  */
    5668              : 
    5669       303837 :   unsigned help_version_count = 0;
    5670              : 
    5671       303837 :   if (print_version)
    5672           78 :     help_version_count++;
    5673              : 
    5674       303837 :   if (print_help_list)
    5675            4 :     help_version_count++;
    5676              : 
    5677       607674 :   spec_undefvar_allowed =
    5678         1577 :     ((verbose_flag && decoded_options_count == 2)
    5679       305380 :      || help_version_count == decoded_options_count - 1);
    5680              : 
    5681       303837 :   alloc_switch ();
    5682       303837 :   switches[n_switches].part1 = 0;
    5683       303837 :   alloc_infile ();
    5684       303837 :   infiles[n_infiles].name = 0;
    5685       303837 : }
    5686              : 
    5687              : /* Set COLLECT_GCC_OPTIONS in the environment.  If the value would
    5688              :    exceed COLLECT2_OPTIONS_MAX_LENGTH, spill it to a temporary
    5689              :    response file and set the variable to @<path> instead.  */
    5690              : 
    5691              : static void
    5692       832615 : xsetenv_collect_gcc_options (char *string)
    5693              : {
    5694       832615 :   if (strlen (string) <= COLLECT2_OPTIONS_MAX_LENGTH)
    5695              :     {
    5696       629490 :       xputenv (string);
    5697       629490 :       return;
    5698              :     }
    5699              : 
    5700       203125 :   static const char prefix[] = "COLLECT_GCC_OPTIONS=";
    5701       203125 :   gcc_assert (startswith (string, prefix));
    5702              : 
    5703              :   /* parse_options_from_collect_gcc_options expects argc to start
    5704              :      at 1, so push a placeholder argv[0].  */
    5705       203125 :   struct obstack argv_obstack;
    5706       203125 :   obstack_init (&argv_obstack);
    5707       203125 :   obstack_ptr_grow (&argv_obstack, const_cast<char *> (progname));
    5708       203125 :   int argc;
    5709       203125 :   parse_options_from_collect_gcc_options (string + sizeof (prefix) - 1,
    5710              :                                           &argv_obstack, &argc);
    5711       203125 :   char **argv = XOBFINISH (&argv_obstack, char **);
    5712              : 
    5713       203125 :   char *temp_file = make_temp_file ("");
    5714       203125 :   FILE *f = fopen (temp_file, "wb");
    5715       203125 :   if (f == nullptr)
    5716            0 :     fatal_error (input_location,
    5717              :                  "cannot open response file %qs: %m", temp_file);
    5718              :   /* writeargv walks until NULL; skip our placeholder argv[0].  */
    5719       203125 :   if (writeargv (argv + 1, f) != 0)
    5720            0 :     fatal_error (input_location,
    5721              :                  "cannot write response file %qs: %m", temp_file);
    5722       203125 :   if (fclose (f) != 0)
    5723            0 :     fatal_error (input_location,
    5724              :                  "cannot close response file %qs: %m", temp_file);
    5725              : 
    5726       203125 :   char *env_val = concat (prefix, "@", temp_file, nullptr);
    5727              :   /* Delete on both success and failure unless -save-temps.  */
    5728       203125 :   record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
    5729       203125 :   obstack_free (&argv_obstack, nullptr);
    5730       203125 :   xputenv (env_val);
    5731              : }
    5732              : 
    5733              : /* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
    5734              :    and place that in the environment.  */
    5735              : 
    5736              : static void
    5737       832615 : set_collect_gcc_options (void)
    5738              : {
    5739       832615 :   int i;
    5740       832615 :   int first_time;
    5741              : 
    5742              :   /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
    5743              :      the compiler.  */
    5744       832615 :   obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
    5745              :                 sizeof ("COLLECT_GCC_OPTIONS=") - 1);
    5746              : 
    5747       832615 :   first_time = true;
    5748     20213405 :   for (i = 0; (int) i < n_switches; i++)
    5749              :     {
    5750     19380790 :       const char *const *args;
    5751     19380790 :       const char *p, *q;
    5752     19380790 :       if (!first_time)
    5753     18548175 :         obstack_grow (&collect_obstack, " ", 1);
    5754              : 
    5755     19380790 :       first_time = false;
    5756              : 
    5757              :       /* Ignore elided switches.  */
    5758     19501279 :       if ((switches[i].live_cond
    5759     19380790 :            & (SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC))
    5760              :           == SWITCH_IGNORE)
    5761       120489 :         continue;
    5762              : 
    5763     19260301 :       obstack_grow (&collect_obstack, "'-", 2);
    5764     19260301 :       q = switches[i].part1;
    5765     19260301 :       while ((p = strchr (q, '\'')))
    5766              :         {
    5767            0 :           obstack_grow (&collect_obstack, q, p - q);
    5768            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5769            0 :           q = ++p;
    5770              :         }
    5771     19260301 :       obstack_grow (&collect_obstack, q, strlen (q));
    5772     19260301 :       obstack_grow (&collect_obstack, "'", 1);
    5773              : 
    5774     23501272 :       for (args = switches[i].args; args && *args; args++)
    5775              :         {
    5776      4240971 :           obstack_grow (&collect_obstack, " '", 2);
    5777      4240971 :           q = *args;
    5778      4240971 :           while ((p = strchr (q, '\'')))
    5779              :             {
    5780            0 :               obstack_grow (&collect_obstack, q, p - q);
    5781            0 :               obstack_grow (&collect_obstack, "'\\''", 4);
    5782            0 :               q = ++p;
    5783              :             }
    5784      4240971 :           obstack_grow (&collect_obstack, q, strlen (q));
    5785      4240971 :           obstack_grow (&collect_obstack, "'", 1);
    5786              :         }
    5787              :     }
    5788              : 
    5789       832615 :   if (dumpdir)
    5790              :     {
    5791       591506 :       if (!first_time)
    5792       591506 :         obstack_grow (&collect_obstack, " ", 1);
    5793       591506 :       first_time = false;
    5794              : 
    5795       591506 :       obstack_grow (&collect_obstack, "'-dumpdir' '", 12);
    5796       591506 :       const char *p, *q;
    5797              : 
    5798       591506 :       q = dumpdir;
    5799       591506 :       while ((p = strchr (q, '\'')))
    5800              :         {
    5801            0 :           obstack_grow (&collect_obstack, q, p - q);
    5802            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5803            0 :           q = ++p;
    5804              :         }
    5805       591506 :       obstack_grow (&collect_obstack, q, strlen (q));
    5806              : 
    5807       591506 :       obstack_grow (&collect_obstack, "'", 1);
    5808              :     }
    5809              : 
    5810       832615 :   obstack_grow (&collect_obstack, "\0", 1);
    5811       832615 :   xsetenv_collect_gcc_options (XOBFINISH (&collect_obstack, char *));
    5812       832615 : }
    5813              : 
    5814              : /* Process a spec string, accumulating and running commands.  */
    5815              : 
    5816              : /* These variables describe the input file name.
    5817              :    input_file_number is the index on outfiles of this file,
    5818              :    so that the output file name can be stored for later use by %o.
    5819              :    input_basename is the start of the part of the input file
    5820              :    sans all directory names, and basename_length is the number
    5821              :    of characters starting there excluding the suffix .c or whatever.  */
    5822              : 
    5823              : static const char *gcc_input_filename;
    5824              : static int input_file_number;
    5825              : size_t input_filename_length;
    5826              : static int basename_length;
    5827              : static int suffixed_basename_length;
    5828              : static const char *input_basename;
    5829              : static const char *input_suffix;
    5830              : #ifndef HOST_LACKS_INODE_NUMBERS
    5831              : static struct stat input_stat;
    5832              : #endif
    5833              : static int input_stat_set;
    5834              : 
    5835              : /* The compiler used to process the current input file.  */
    5836              : static struct compiler *input_file_compiler;
    5837              : 
    5838              : /* These are variables used within do_spec and do_spec_1.  */
    5839              : 
    5840              : /* Nonzero if an arg has been started and not yet terminated
    5841              :    (with space, tab or newline).  */
    5842              : static int arg_going;
    5843              : 
    5844              : /* Nonzero means %d or %g has been seen; the next arg to be terminated
    5845              :    is a temporary file name.  */
    5846              : static int delete_this_arg;
    5847              : 
    5848              : /* Nonzero means %w has been seen; the next arg to be terminated
    5849              :    is the output file name of this compilation.  */
    5850              : static int this_is_output_file;
    5851              : 
    5852              : /* Nonzero means %s has been seen; the next arg to be terminated
    5853              :    is the name of a library file and we should try the standard
    5854              :    search dirs for it.  */
    5855              : static int this_is_library_file;
    5856              : 
    5857              : /* Nonzero means %T has been seen; the next arg to be terminated
    5858              :    is the name of a linker script and we should try all of the
    5859              :    standard search dirs for it.  If it is found insert a --script
    5860              :    command line switch and then substitute the full path in place,
    5861              :    otherwise generate an error message.  */
    5862              : static int this_is_linker_script;
    5863              : 
    5864              : /* Nonzero means that the input of this command is coming from a pipe.  */
    5865              : static int input_from_pipe;
    5866              : 
    5867              : /* Nonnull means substitute this for any suffix when outputting a switches
    5868              :    arguments.  */
    5869              : static const char *suffix_subst;
    5870              : 
    5871              : /* If there is an argument being accumulated, terminate it and store it.  */
    5872              : 
    5873              : static void
    5874     81380132 : end_going_arg (void)
    5875              : {
    5876     81380132 :   if (arg_going)
    5877              :     {
    5878     19240399 :       const char *string;
    5879              : 
    5880     19240399 :       obstack_1grow (&obstack, 0);
    5881     19240399 :       string = XOBFINISH (&obstack, const char *);
    5882     19240399 :       if (this_is_library_file)
    5883       544763 :         string = find_file (string);
    5884     19240399 :       if (this_is_linker_script)
    5885              :         {
    5886            0 :           char * full_script_path = find_a_file (&startfile_prefixes, string, true);
    5887              : 
    5888            0 :           if (full_script_path == NULL)
    5889              :             {
    5890            0 :               error ("unable to locate default linker script %qs in the library search paths", string);
    5891              :               /* Script was not found on search path.  */
    5892            0 :               return;
    5893              :             }
    5894            0 :           store_arg ("--script", false, false);
    5895            0 :           string = full_script_path;
    5896              :         }
    5897     19240399 :       store_arg (string, delete_this_arg, this_is_output_file);
    5898     19240399 :       if (this_is_output_file)
    5899       100751 :         outfiles[input_file_number] = string;
    5900     19240399 :       arg_going = 0;
    5901              :     }
    5902              : }
    5903              : 
    5904              : 
    5905              : /* Parse the WRAPPER string which is a comma separated list of the command line
    5906              :    and insert them into the beginning of argbuf.  */
    5907              : 
    5908              : static void
    5909            0 : insert_wrapper (const char *wrapper)
    5910              : {
    5911            0 :   int n = 0;
    5912            0 :   int i;
    5913            0 :   char *buf = xstrdup (wrapper);
    5914            0 :   char *p = buf;
    5915            0 :   unsigned int old_length = argbuf.length ();
    5916              : 
    5917            0 :   do
    5918              :     {
    5919            0 :       n++;
    5920            0 :       while (*p == ',')
    5921            0 :         p++;
    5922              :     }
    5923            0 :   while ((p = strchr (p, ',')) != NULL);
    5924              : 
    5925            0 :   argbuf.safe_grow (old_length + n, true);
    5926            0 :   memmove (argbuf.address () + n,
    5927            0 :            argbuf.address (),
    5928            0 :            old_length * sizeof (const_char_p));
    5929              : 
    5930            0 :   i = 0;
    5931            0 :   p = buf;
    5932              :   do
    5933              :     {
    5934            0 :       while (*p == ',')
    5935              :         {
    5936            0 :           *p = 0;
    5937            0 :           p++;
    5938              :         }
    5939            0 :       argbuf[i] = p;
    5940            0 :       i++;
    5941              :     }
    5942            0 :   while ((p = strchr (p, ',')) != NULL);
    5943            0 :   gcc_assert (i == n);
    5944            0 : }
    5945              : 
    5946              : /* Process the spec SPEC and run the commands specified therein.
    5947              :    Returns 0 if the spec is successfully processed; -1 if failed.  */
    5948              : 
    5949              : int
    5950       572600 : do_spec (const char *spec)
    5951              : {
    5952       572600 :   int value;
    5953              : 
    5954       572600 :   value = do_spec_2 (spec, NULL);
    5955              : 
    5956              :   /* Force out any unfinished command.
    5957              :      If -pipe, this forces out the last command if it ended in `|'.  */
    5958       572600 :   if (value == 0)
    5959              :     {
    5960       567132 :       if (argbuf.length () > 0
    5961       851961 :           && !strcmp (argbuf.last (), "|"))
    5962            0 :         argbuf.pop ();
    5963              : 
    5964       567132 :       set_collect_gcc_options ();
    5965              : 
    5966       567132 :       if (argbuf.length () > 0)
    5967       284829 :         value = execute ();
    5968              :     }
    5969              : 
    5970       572600 :   return value;
    5971              : }
    5972              : 
    5973              : /* Process the spec SPEC, with SOFT_MATCHED_PART designating the current value
    5974              :    of a matched * pattern which may be re-injected by way of %*.  */
    5975              : 
    5976              : static int
    5977      5406420 : do_spec_2 (const char *spec, const char *soft_matched_part)
    5978              : {
    5979      5406420 :   int result;
    5980              : 
    5981      5406420 :   clear_args ();
    5982      5406420 :   arg_going = 0;
    5983      5406420 :   delete_this_arg = 0;
    5984      5406420 :   this_is_output_file = 0;
    5985      5406420 :   this_is_library_file = 0;
    5986      5406420 :   this_is_linker_script = 0;
    5987      5406420 :   input_from_pipe = 0;
    5988      5406420 :   suffix_subst = NULL;
    5989              : 
    5990      5406420 :   result = do_spec_1 (spec, 0, soft_matched_part);
    5991              : 
    5992      5406420 :   end_going_arg ();
    5993              : 
    5994      5406420 :   return result;
    5995              : }
    5996              : 
    5997              : /* Process the given spec string and add any new options to the end
    5998              :    of the switches/n_switches array.  */
    5999              : 
    6000              : static void
    6001      3039690 : do_option_spec (const char *name, const char *spec)
    6002              : {
    6003      3039690 :   unsigned int i, value_count, value_len;
    6004      3039690 :   const char *p, *q, *value;
    6005      3039690 :   char *tmp_spec, *tmp_spec_p;
    6006              : 
    6007      3039690 :   if (configure_default_options[0].name == NULL)
    6008              :     return;
    6009              : 
    6010      8207163 :   for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
    6011      5775411 :     if (strcmp (configure_default_options[i].name, name) == 0)
    6012              :       break;
    6013      3039690 :   if (i == ARRAY_SIZE (configure_default_options))
    6014              :     return;
    6015              : 
    6016       607938 :   value = configure_default_options[i].value;
    6017       607938 :   value_len = strlen (value);
    6018              : 
    6019              :   /* Compute the size of the final spec.  */
    6020       607938 :   value_count = 0;
    6021       607938 :   p = spec;
    6022      1215876 :   while ((p = strstr (p, "%(VALUE)")) != NULL)
    6023              :     {
    6024       607938 :       p ++;
    6025       607938 :       value_count ++;
    6026              :     }
    6027              : 
    6028              :   /* Replace each %(VALUE) by the specified value.  */
    6029       607938 :   tmp_spec = (char *) alloca (strlen (spec) + 1
    6030              :                      + value_count * (value_len - strlen ("%(VALUE)")));
    6031       607938 :   tmp_spec_p = tmp_spec;
    6032       607938 :   q = spec;
    6033      1215876 :   while ((p = strstr (q, "%(VALUE)")) != NULL)
    6034              :     {
    6035       607938 :       memcpy (tmp_spec_p, q, p - q);
    6036       607938 :       tmp_spec_p = tmp_spec_p + (p - q);
    6037       607938 :       memcpy (tmp_spec_p, value, value_len);
    6038       607938 :       tmp_spec_p += value_len;
    6039       607938 :       q = p + strlen ("%(VALUE)");
    6040              :     }
    6041       607938 :   strcpy (tmp_spec_p, q);
    6042              : 
    6043       607938 :   do_self_spec (tmp_spec);
    6044              : }
    6045              : 
    6046              : /* Process the given spec string and add any new options to the end
    6047              :    of the switches/n_switches array.  */
    6048              : 
    6049              : static void
    6050      2736066 : do_self_spec (const char *spec)
    6051              : {
    6052      2736066 :   int i;
    6053              : 
    6054      2736066 :   do_spec_2 (spec, NULL);
    6055      2736066 :   do_spec_1 (" ", 0, NULL);
    6056              : 
    6057              :   /* Mark %<S switches processed by do_self_spec to be ignored permanently.
    6058              :      do_self_specs adds the replacements to switches array, so it shouldn't
    6059              :      be processed afterwards.  */
    6060     66661497 :   for (i = 0; i < n_switches; i++)
    6061     61189365 :     if ((switches[i].live_cond & SWITCH_IGNORE))
    6062          683 :       switches[i].live_cond |= SWITCH_IGNORE_PERMANENTLY;
    6063              : 
    6064      2736066 :   if (argbuf.length () > 0)
    6065              :     {
    6066       578495 :       const char **argbuf_copy;
    6067       578495 :       struct cl_decoded_option *decoded_options;
    6068       578495 :       struct cl_option_handlers handlers;
    6069       578495 :       unsigned int decoded_options_count;
    6070       578495 :       unsigned int j;
    6071              : 
    6072              :       /* Create a copy of argbuf with a dummy argv[0] entry for
    6073              :          decode_cmdline_options_to_array.  */
    6074       578495 :       argbuf_copy = XNEWVEC (const char *,
    6075              :                              argbuf.length () + 1);
    6076       578495 :       argbuf_copy[0] = "";
    6077       578495 :       memcpy (argbuf_copy + 1, argbuf.address (),
    6078       578495 :               argbuf.length () * sizeof (const char *));
    6079              : 
    6080      1156990 :       decode_cmdline_options_to_array (argbuf.length () + 1,
    6081              :                                        argbuf_copy,
    6082              :                                        CL_DRIVER, &decoded_options,
    6083              :                                        &decoded_options_count);
    6084       578495 :       free (argbuf_copy);
    6085              : 
    6086       578495 :       set_option_handlers (&handlers);
    6087              : 
    6088      1159530 :       for (j = 1; j < decoded_options_count; j++)
    6089              :         {
    6090       581035 :           switch (decoded_options[j].opt_index)
    6091              :             {
    6092            0 :             case OPT_SPECIAL_input_file:
    6093              :               /* Specs should only generate options, not input
    6094              :                  files.  */
    6095            0 :               if (strcmp (decoded_options[j].arg, "-") != 0)
    6096            0 :                 fatal_error (input_location,
    6097              :                              "switch %qs does not start with %<-%>",
    6098              :                              decoded_options[j].arg);
    6099              :               else
    6100            0 :                 fatal_error (input_location,
    6101              :                              "spec-generated switch is just %<-%>");
    6102         1270 :               break;
    6103              : 
    6104         1270 :             case OPT_fcompare_debug_second:
    6105         1270 :             case OPT_fcompare_debug:
    6106         1270 :             case OPT_fcompare_debug_:
    6107         1270 :             case OPT_o:
    6108              :               /* Avoid duplicate processing of some options from
    6109              :                  compare-debug specs; just save them here.  */
    6110         1270 :               save_switch (decoded_options[j].canonical_option[0],
    6111         1270 :                            (decoded_options[j].canonical_option_num_elements
    6112              :                             - 1),
    6113         1270 :                            &decoded_options[j].canonical_option[1], false, true);
    6114         1270 :               break;
    6115              : 
    6116       579765 :             default:
    6117       579765 :               read_cmdline_option (&global_options, &global_options_set,
    6118              :                                    decoded_options + j, UNKNOWN_LOCATION,
    6119              :                                    CL_DRIVER, &handlers, global_dc);
    6120       579765 :               break;
    6121              :             }
    6122              :         }
    6123              : 
    6124       578495 :       free (decoded_options);
    6125              : 
    6126       578495 :       alloc_switch ();
    6127       578495 :       switches[n_switches].part1 = 0;
    6128              :     }
    6129      2736066 : }
    6130              : 
    6131              : /* Callback for processing %D and %I specs.  */
    6132              : 
    6133              : struct spec_path {
    6134              :   const char *option;
    6135              :   const char *append;
    6136              :   size_t append_len;
    6137              :   bool omit_relative;
    6138              :   bool separate_options;
    6139              :   bool realpaths;
    6140              : 
    6141              :   void *operator() (char *path, bool);
    6142              : };
    6143              : 
    6144              : void *
    6145      3383110 : spec_path::operator() (char *path, bool)
    6146              : {
    6147      3383110 :   size_t len = 0;
    6148      3383110 :   char save = 0;
    6149              : 
    6150              :   /* The path must exist; we want to resolve it to the realpath so that this
    6151              :      can be embedded as a runpath.  */
    6152      3383110 :   if (realpaths)
    6153            0 :      path = lrealpath (path);
    6154              : 
    6155              :   /* However, if we failed to resolve it - perhaps because there was a bogus
    6156              :      -B option on the command line, then punt on this entry.  */
    6157      3383110 :   if (!path)
    6158              :     return NULL;
    6159              : 
    6160      3383110 :   if (omit_relative && !IS_ABSOLUTE_PATH (path))
    6161              :     return NULL;
    6162              : 
    6163      3383110 :   if (append_len != 0)
    6164              :     {
    6165      1412244 :       len = strlen (path);
    6166      1412244 :       memcpy (path + len, append, append_len + 1);
    6167              :     }
    6168              : 
    6169      3383110 :   if (!is_directory (path))
    6170              :     return NULL;
    6171              : 
    6172      1269986 :   do_spec_1 (option, 1, NULL);
    6173      1269986 :   if (separate_options)
    6174       456162 :     do_spec_1 (" ", 0, NULL);
    6175              : 
    6176      1269986 :   if (append_len == 0)
    6177              :     {
    6178       813824 :       len = strlen (path);
    6179       813824 :       save = path[len - 1];
    6180       813824 :       if (IS_DIR_SEPARATOR (path[len - 1]))
    6181       813824 :         path[len - 1] = '\0';
    6182              :     }
    6183              : 
    6184      1269986 :   do_spec_1 (path, 1, NULL);
    6185      1269986 :   do_spec_1 (" ", 0, NULL);
    6186              : 
    6187              :   /* Must not damage the original path.  */
    6188      1269986 :   if (append_len == 0)
    6189       813824 :     path[len - 1] = save;
    6190              : 
    6191              :   return NULL;
    6192              : }
    6193              : 
    6194              : /* True if we should compile INFILE. */
    6195              : 
    6196              : static bool
    6197        43878 : compile_input_file_p (struct infile *infile)
    6198              : {
    6199        26202 :   if ((!infile->language) || (infile->language[0] != '*'))
    6200        39094 :     if (infile->incompiler == input_file_compiler)
    6201            0 :       return true;
    6202              :   return false;
    6203              : }
    6204              : 
    6205              : /* Process each member of VEC as a spec.  */
    6206              : 
    6207              : static void
    6208       471922 : do_specs_vec (vec<char_p> vec)
    6209              : {
    6210       472043 :   for (char *opt : vec)
    6211              :     {
    6212           71 :       do_spec_1 (opt, 1, NULL);
    6213              :       /* Make each accumulated option a separate argument.  */
    6214           71 :       do_spec_1 (" ", 0, NULL);
    6215              :     }
    6216       471922 : }
    6217              : 
    6218              : /* Add options passed via -Xassembler or -Wa to COLLECT_AS_OPTIONS.  */
    6219              : 
    6220              : static void
    6221       303836 : putenv_COLLECT_AS_OPTIONS (vec<char_p> vec)
    6222              : {
    6223       303836 :   if (vec.is_empty ())
    6224       303836 :      return;
    6225              : 
    6226          104 :   obstack_init (&collect_obstack);
    6227          104 :   obstack_grow (&collect_obstack, "COLLECT_AS_OPTIONS=",
    6228              :                 strlen ("COLLECT_AS_OPTIONS="));
    6229              : 
    6230          104 :   char *opt;
    6231          104 :   unsigned ix;
    6232              : 
    6233          300 :   FOR_EACH_VEC_ELT (vec, ix, opt)
    6234              :     {
    6235          196 :       obstack_1grow (&collect_obstack, '\'');
    6236          196 :       obstack_grow (&collect_obstack, opt, strlen (opt));
    6237          196 :       obstack_1grow (&collect_obstack, '\'');
    6238          196 :       if (ix < vec.length () - 1)
    6239           92 :         obstack_1grow(&collect_obstack, ' ');
    6240              :     }
    6241              : 
    6242          104 :   obstack_1grow (&collect_obstack, '\0');
    6243          104 :   xputenv (XOBFINISH (&collect_obstack, char *));
    6244              : }
    6245              : 
    6246              : /* Process the sub-spec SPEC as a portion of a larger spec.
    6247              :    This is like processing a whole spec except that we do
    6248              :    not initialize at the beginning and we do not supply a
    6249              :    newline by default at the end.
    6250              :    INSWITCH nonzero means don't process %-sequences in SPEC;
    6251              :    in this case, % is treated as an ordinary character.
    6252              :    This is used while substituting switches.
    6253              :    INSWITCH nonzero also causes SPC not to terminate an argument.
    6254              : 
    6255              :    Value is zero unless a line was finished
    6256              :    and the command on that line reported an error.  */
    6257              : 
    6258              : static int
    6259     53510383 : do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
    6260              : {
    6261     53510383 :   const char *p = spec;
    6262     53510383 :   int c;
    6263     53510383 :   int i;
    6264     53510383 :   int value;
    6265              : 
    6266              :   /* If it's an empty string argument to a switch, keep it as is.  */
    6267     53510383 :   if (inswitch && !*p)
    6268            1 :     arg_going = 1;
    6269              : 
    6270    541219557 :   while ((c = *p++))
    6271              :     /* If substituting a switch, treat all chars like letters.
    6272              :        Otherwise, NL, SPC, TAB and % are special.  */
    6273    487755266 :     switch (inswitch ? 'a' : c)
    6274              :       {
    6275       265483 :       case '\n':
    6276       265483 :         end_going_arg ();
    6277              : 
    6278       265483 :         if (argbuf.length () > 0
    6279       530966 :             && !strcmp (argbuf.last (), "|"))
    6280              :           {
    6281              :             /* A `|' before the newline means use a pipe here,
    6282              :                but only if -pipe was specified.
    6283              :                Otherwise, execute now and don't pass the `|' as an arg.  */
    6284       168353 :             if (use_pipes)
    6285              :               {
    6286            0 :                 input_from_pipe = 1;
    6287            0 :                 break;
    6288              :               }
    6289              :             else
    6290       168353 :               argbuf.pop ();
    6291              :           }
    6292              : 
    6293       265483 :         set_collect_gcc_options ();
    6294              : 
    6295       265483 :         if (argbuf.length () > 0)
    6296              :           {
    6297       265483 :             value = execute ();
    6298       265483 :             if (value)
    6299              :               return value;
    6300              :           }
    6301              :         /* Reinitialize for a new command, and for a new argument.  */
    6302       260015 :         clear_args ();
    6303       260015 :         arg_going = 0;
    6304       260015 :         delete_this_arg = 0;
    6305       260015 :         this_is_output_file = 0;
    6306       260015 :         this_is_library_file = 0;
    6307       260015 :         this_is_linker_script = 0;
    6308       260015 :         input_from_pipe = 0;
    6309       260015 :         break;
    6310              : 
    6311       168353 :       case '|':
    6312       168353 :         end_going_arg ();
    6313              : 
    6314              :         /* Use pipe */
    6315       168353 :         obstack_1grow (&obstack, c);
    6316       168353 :         arg_going = 1;
    6317       168353 :         break;
    6318              : 
    6319     70812688 :       case '\t':
    6320     70812688 :       case ' ':
    6321     70812688 :         end_going_arg ();
    6322              : 
    6323              :         /* Reinitialize for a new argument.  */
    6324     70812688 :         delete_this_arg = 0;
    6325     70812688 :         this_is_output_file = 0;
    6326     70812688 :         this_is_library_file = 0;
    6327     70812688 :         this_is_linker_script = 0;
    6328     70812688 :         break;
    6329              : 
    6330     49850667 :       case '%':
    6331     49850667 :         switch (c = *p++)
    6332              :           {
    6333            0 :           case 0:
    6334            0 :             fatal_error (input_location, "spec %qs invalid", spec);
    6335              : 
    6336         3621 :           case 'b':
    6337              :             /* Don't use %b in the linker command.  */
    6338         3621 :             gcc_assert (suffixed_basename_length);
    6339         3621 :             if (!this_is_output_file && dumpdir_length)
    6340          709 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6341         3621 :             if (this_is_output_file || !outbase_length)
    6342         3279 :               obstack_grow (&obstack, input_basename, basename_length);
    6343              :             else
    6344          342 :               obstack_grow (&obstack, outbase, outbase_length);
    6345         3621 :             if (compare_debug < 0)
    6346            6 :               obstack_grow (&obstack, ".gk", 3);
    6347         3621 :             arg_going = 1;
    6348         3621 :             break;
    6349              : 
    6350           10 :           case 'B':
    6351              :             /* Don't use %B in the linker command.  */
    6352           10 :             gcc_assert (suffixed_basename_length);
    6353           10 :             if (!this_is_output_file && dumpdir_length)
    6354            0 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6355           10 :             if (this_is_output_file || !outbase_length)
    6356            5 :               obstack_grow (&obstack, input_basename, basename_length);
    6357              :             else
    6358            5 :               obstack_grow (&obstack, outbase, outbase_length);
    6359           10 :             if (compare_debug < 0)
    6360            3 :               obstack_grow (&obstack, ".gk", 3);
    6361           10 :             obstack_grow (&obstack, input_basename + basename_length,
    6362              :                           suffixed_basename_length - basename_length);
    6363              : 
    6364           10 :             arg_going = 1;
    6365           10 :             break;
    6366              : 
    6367        98235 :           case 'd':
    6368        98235 :             delete_this_arg = 2;
    6369        98235 :             break;
    6370              : 
    6371              :           /* Dump out the directories specified with LIBRARY_PATH,
    6372              :              followed by the absolute directories
    6373              :              that we search for startfiles.  */
    6374       106436 :           case 'D':
    6375       106436 :             {
    6376       106436 :               struct spec_path info;
    6377              : 
    6378       106436 :               info.option = "-L";
    6379       106436 :               info.append_len = 0;
    6380              : #ifdef RELATIVE_PREFIX_NOT_LINKDIR
    6381              :               /* Used on systems which record the specified -L dirs
    6382              :                  and use them to search for dynamic linking.
    6383              :                  Relative directories always come from -B,
    6384              :                  and it is better not to use them for searching
    6385              :                  at run time.  In particular, stage1 loses.  */
    6386              :               info.omit_relative = true;
    6387              : #else
    6388       106436 :               info.omit_relative = false;
    6389              : #endif
    6390       106436 :               info.separate_options = false;
    6391       106436 :               info.realpaths = false;
    6392              : 
    6393       106436 :               for_each_path (&startfile_prefixes, true, 0, info);
    6394              :             }
    6395       106436 :             break;
    6396              : 
    6397            0 :           case 'P':
    6398            0 :             {
    6399            0 :               struct spec_path info;
    6400              : 
    6401            0 :               info.option = RUNPATH_OPTION;
    6402            0 :               info.append_len = 0;
    6403            0 :               info.omit_relative = false;
    6404            0 :               info.separate_options = true;
    6405              :               /* We want to embed the actual paths that have the libraries.  */
    6406            0 :               info.realpaths = true;
    6407              : 
    6408            0 :               for_each_path (&startfile_prefixes, true, 0, info);
    6409              :             }
    6410            0 :             break;
    6411              : 
    6412              :           case 'e':
    6413              :             /* %efoo means report an error with `foo' as error message
    6414              :                and don't execute any more commands for this file.  */
    6415              :             {
    6416              :               const char *q = p;
    6417              :               char *buf;
    6418            0 :               while (*p != 0 && *p != '\n')
    6419            0 :                 p++;
    6420            0 :               buf = (char *) alloca (p - q + 1);
    6421            0 :               strncpy (buf, q, p - q);
    6422            0 :               buf[p - q] = 0;
    6423            0 :               error ("%s", _(buf));
    6424            0 :               return -1;
    6425              :             }
    6426              :             break;
    6427              :           case 'n':
    6428              :             /* %nfoo means report a notice with `foo' on stderr.  */
    6429              :             {
    6430              :               const char *q = p;
    6431              :               char *buf;
    6432            0 :               while (*p != 0 && *p != '\n')
    6433            0 :                 p++;
    6434            0 :               buf = (char *) alloca (p - q + 1);
    6435            0 :               strncpy (buf, q, p - q);
    6436            0 :               buf[p - q] = 0;
    6437            0 :               inform (UNKNOWN_LOCATION, "%s", _(buf));
    6438            0 :               if (*p)
    6439            0 :                 p++;
    6440              :             }
    6441              :             break;
    6442              : 
    6443          900 :           case 'j':
    6444          900 :             {
    6445          900 :               struct stat st;
    6446              : 
    6447              :               /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
    6448              :                  defined, and it is not a directory, and it is
    6449              :                  writable, use it.  Otherwise, treat this like any
    6450              :                  other temporary file.  */
    6451              : 
    6452          900 :               if ((!save_temps_flag)
    6453          900 :                   && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
    6454         1800 :                   && (access (HOST_BIT_BUCKET, W_OK) == 0))
    6455              :                 {
    6456          900 :                   obstack_grow (&obstack, HOST_BIT_BUCKET,
    6457              :                                 strlen (HOST_BIT_BUCKET));
    6458          900 :                   delete_this_arg = 0;
    6459          900 :                   arg_going = 1;
    6460          900 :                   break;
    6461              :                 }
    6462              :             }
    6463            0 :             goto create_temp_file;
    6464       168353 :           case '|':
    6465       168353 :             if (use_pipes)
    6466              :               {
    6467            0 :                 obstack_1grow (&obstack, '-');
    6468            0 :                 delete_this_arg = 0;
    6469            0 :                 arg_going = 1;
    6470              : 
    6471              :                 /* consume suffix */
    6472            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6473            0 :                   p++;
    6474            0 :                 if (p[0] == '%' && p[1] == 'O')
    6475            0 :                   p += 2;
    6476              : 
    6477              :                 break;
    6478              :               }
    6479       168353 :             goto create_temp_file;
    6480       163024 :           case 'm':
    6481       163024 :             if (use_pipes)
    6482              :               {
    6483              :                 /* consume suffix */
    6484            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6485            0 :                   p++;
    6486            0 :                 if (p[0] == '%' && p[1] == 'O')
    6487            0 :                   p += 2;
    6488              : 
    6489              :                 break;
    6490              :               }
    6491       163024 :             goto create_temp_file;
    6492       523422 :           case 'g':
    6493       523422 :           case 'u':
    6494       523422 :           case 'U':
    6495       523422 :           create_temp_file:
    6496       523422 :               {
    6497       523422 :                 struct temp_name *t;
    6498       523422 :                 int suffix_length;
    6499       523422 :                 const char *suffix = p;
    6500       523422 :                 char *saved_suffix = NULL;
    6501              : 
    6502      1559552 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6503      1036130 :                   p++;
    6504       523422 :                 suffix_length = p - suffix;
    6505       523422 :                 if (p[0] == '%' && p[1] == 'O')
    6506              :                   {
    6507        98457 :                     p += 2;
    6508              :                     /* We don't support extra suffix characters after %O.  */
    6509        98457 :                     if (*p == '.' || ISALNUM ((unsigned char) *p))
    6510            0 :                       fatal_error (input_location,
    6511              :                                    "spec %qs has invalid %<%%0%c%>", spec, *p);
    6512        98457 :                     if (suffix_length == 0)
    6513              :                       suffix = TARGET_OBJECT_SUFFIX;
    6514              :                     else
    6515              :                       {
    6516            0 :                         saved_suffix
    6517            0 :                           = XNEWVEC (char, suffix_length
    6518              :                                      + strlen (TARGET_OBJECT_SUFFIX) + 1);
    6519            0 :                         strncpy (saved_suffix, suffix, suffix_length);
    6520            0 :                         strcpy (saved_suffix + suffix_length,
    6521              :                                 TARGET_OBJECT_SUFFIX);
    6522              :                       }
    6523        98457 :                     suffix_length += strlen (TARGET_OBJECT_SUFFIX);
    6524              :                   }
    6525              : 
    6526       523422 :                 if (compare_debug < 0)
    6527              :                   {
    6528          626 :                     suffix = concat (".gk", suffix, NULL);
    6529          626 :                     suffix_length += 3;
    6530              :                   }
    6531              : 
    6532              :                 /* If -save-temps was specified, use that for the
    6533              :                    temp file.  */
    6534       523422 :                 if (save_temps_flag)
    6535              :                   {
    6536         1233 :                     char *tmp;
    6537         1233 :                     bool adjusted_suffix = false;
    6538         1233 :                     if (suffix_length
    6539         1233 :                         && !outbase_length && !basename_length
    6540          233 :                         && !dumpdir_trailing_dash_added)
    6541              :                       {
    6542           20 :                         adjusted_suffix = true;
    6543           20 :                         suffix++;
    6544           20 :                         suffix_length--;
    6545              :                       }
    6546         1233 :                     temp_filename_length
    6547         1233 :                       = dumpdir_length + suffix_length + 1;
    6548         1233 :                     if (outbase_length)
    6549           72 :                       temp_filename_length += outbase_length;
    6550              :                     else
    6551         1161 :                       temp_filename_length += basename_length;
    6552         1233 :                     tmp = (char *) alloca (temp_filename_length);
    6553         1233 :                     if (dumpdir_length)
    6554         1075 :                       memcpy (tmp, dumpdir, dumpdir_length);
    6555         1233 :                     if (outbase_length)
    6556           72 :                       memcpy (tmp + dumpdir_length, outbase,
    6557              :                               outbase_length);
    6558         1161 :                     else if (basename_length)
    6559          928 :                       memcpy (tmp + dumpdir_length, input_basename,
    6560              :                               basename_length);
    6561         1233 :                     memcpy (tmp + temp_filename_length - suffix_length - 1,
    6562              :                             suffix, suffix_length);
    6563         1233 :                     if (adjusted_suffix)
    6564              :                       {
    6565           20 :                         adjusted_suffix = false;
    6566           20 :                         suffix--;
    6567           20 :                         suffix_length++;
    6568              :                       }
    6569         1233 :                     tmp[temp_filename_length - 1] = '\0';
    6570         1233 :                     temp_filename = tmp;
    6571              : 
    6572         1233 :                     if (filename_cmp (temp_filename, gcc_input_filename) != 0)
    6573              :                       {
    6574              : #ifndef HOST_LACKS_INODE_NUMBERS
    6575         1233 :                         struct stat st_temp;
    6576              : 
    6577              :                         /* Note, set_input() resets input_stat_set to 0.  */
    6578         1233 :                         if (input_stat_set == 0)
    6579              :                           {
    6580          576 :                             input_stat_set = stat (gcc_input_filename,
    6581              :                                                    &input_stat);
    6582          576 :                             if (input_stat_set >= 0)
    6583          576 :                               input_stat_set = 1;
    6584              :                           }
    6585              : 
    6586              :                         /* If we have the stat for the gcc_input_filename
    6587              :                            and we can do the stat for the temp_filename
    6588              :                            then the they could still refer to the same
    6589              :                            file if st_dev/st_ino's are the same.  */
    6590         1233 :                         if (input_stat_set != 1
    6591         1233 :                             || stat (temp_filename, &st_temp) < 0
    6592          375 :                             || input_stat.st_dev != st_temp.st_dev
    6593         1247 :                             || input_stat.st_ino != st_temp.st_ino)
    6594              : #else
    6595              :                         /* Just compare canonical pathnames.  */
    6596              :                         char* input_realname = lrealpath (gcc_input_filename);
    6597              :                         char* temp_realname = lrealpath (temp_filename);
    6598              :                         bool files_differ = filename_cmp (input_realname, temp_realname);
    6599              :                         free (input_realname);
    6600              :                         free (temp_realname);
    6601              :                         if (files_differ)
    6602              : #endif
    6603              :                           {
    6604         1233 :                             temp_filename
    6605         1233 :                               = save_string (temp_filename,
    6606              :                                              temp_filename_length - 1);
    6607         1233 :                             obstack_grow (&obstack, temp_filename,
    6608              :                                                     temp_filename_length);
    6609         1233 :                             arg_going = 1;
    6610         1233 :                             delete_this_arg = 0;
    6611         1233 :                             break;
    6612              :                           }
    6613              :                       }
    6614              :                   }
    6615              : 
    6616              :                 /* See if we already have an association of %g/%u/%U and
    6617              :                    suffix.  */
    6618       894352 :                 for (t = temp_names; t; t = t->next)
    6619       542234 :                   if (t->length == suffix_length
    6620       362667 :                       && strncmp (t->suffix, suffix, suffix_length) == 0
    6621       174038 :                       && t->unique == (c == 'u' || c == 'U' || c == 'j'))
    6622              :                     break;
    6623              : 
    6624              :                 /* Make a new association if needed.  %u and %j
    6625              :                    require one.  */
    6626       522189 :                 if (t == 0 || c == 'u' || c == 'j')
    6627              :                   {
    6628       355885 :                     if (t == 0)
    6629              :                       {
    6630       352118 :                         t = XNEW (struct temp_name);
    6631       352118 :                         t->next = temp_names;
    6632       352118 :                         temp_names = t;
    6633              :                       }
    6634       355885 :                     t->length = suffix_length;
    6635       355885 :                     if (saved_suffix)
    6636              :                       {
    6637            0 :                         t->suffix = saved_suffix;
    6638            0 :                         saved_suffix = NULL;
    6639              :                       }
    6640              :                     else
    6641       355885 :                       t->suffix = save_string (suffix, suffix_length);
    6642       355885 :                     t->unique = (c == 'u' || c == 'U' || c == 'j');
    6643       355885 :                     temp_filename = make_temp_file (t->suffix);
    6644       355885 :                     temp_filename_length = strlen (temp_filename);
    6645       355885 :                     t->filename = temp_filename;
    6646       355885 :                     t->filename_length = temp_filename_length;
    6647              :                   }
    6648              : 
    6649       522189 :                 free (saved_suffix);
    6650              : 
    6651       522189 :                 obstack_grow (&obstack, t->filename, t->filename_length);
    6652       522189 :                 delete_this_arg = 1;
    6653              :               }
    6654       522189 :             arg_going = 1;
    6655       522189 :             break;
    6656              : 
    6657       291881 :           case 'i':
    6658       291881 :             if (combine_inputs)
    6659              :               {
    6660              :                 /* We are going to expand `%i' into `@FILE', where FILE
    6661              :                    is a newly-created temporary filename.  The filenames
    6662              :                    that would usually be expanded in place of %o will be
    6663              :                    written to the temporary file.  */
    6664        29910 :                 if (at_file_supplied)
    6665        12287 :                   open_at_file ();
    6666              : 
    6667        73788 :                 for (i = 0; (int) i < n_infiles; i++)
    6668        87756 :                   if (compile_input_file_p (&infiles[i]))
    6669              :                     {
    6670        39032 :                       store_arg (infiles[i].name, 0, 0);
    6671        39032 :                       infiles[i].compiled = true;
    6672              :                     }
    6673              : 
    6674        29910 :                 if (at_file_supplied)
    6675        12287 :                   close_at_file ();
    6676              :               }
    6677              :             else
    6678              :               {
    6679       261971 :                 obstack_grow (&obstack, gcc_input_filename,
    6680              :                               input_filename_length);
    6681       261971 :                 arg_going = 1;
    6682              :               }
    6683              :             break;
    6684              : 
    6685       227085 :           case 'I':
    6686       227085 :             {
    6687       227085 :               struct spec_path info;
    6688              : 
    6689       227085 :               if (multilib_dir)
    6690              :                 {
    6691         6029 :                   do_spec_1 ("-imultilib", 1, NULL);
    6692              :                   /* Make this a separate argument.  */
    6693         6029 :                   do_spec_1 (" ", 0, NULL);
    6694         6029 :                   do_spec_1 (multilib_dir, 1, NULL);
    6695         6029 :                   do_spec_1 (" ", 0, NULL);
    6696              :                 }
    6697              : 
    6698       227085 :               if (multiarch_dir)
    6699              :                 {
    6700            0 :                   do_spec_1 ("-imultiarch", 1, NULL);
    6701              :                   /* Make this a separate argument.  */
    6702            0 :                   do_spec_1 (" ", 0, NULL);
    6703            0 :                   do_spec_1 (multiarch_dir, 1, NULL);
    6704            0 :                   do_spec_1 (" ", 0, NULL);
    6705              :                 }
    6706              : 
    6707       227085 :               if (gcc_exec_prefix)
    6708              :                 {
    6709       227085 :                   do_spec_1 ("-iprefix", 1, NULL);
    6710              :                   /* Make this a separate argument.  */
    6711       227085 :                   do_spec_1 (" ", 0, NULL);
    6712       227085 :                   do_spec_1 (gcc_exec_prefix, 1, NULL);
    6713       227085 :                   do_spec_1 (" ", 0, NULL);
    6714              :                 }
    6715              : 
    6716       227085 :               if (target_system_root_changed ||
    6717       227085 :                   (target_system_root && target_sysroot_hdrs_suffix))
    6718              :                 {
    6719            0 :                   do_spec_1 ("-isysroot", 1, NULL);
    6720              :                   /* Make this a separate argument.  */
    6721            0 :                   do_spec_1 (" ", 0, NULL);
    6722            0 :                   do_spec_1 (target_system_root, 1, NULL);
    6723            0 :                   if (target_sysroot_hdrs_suffix)
    6724            0 :                     do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
    6725            0 :                   do_spec_1 (" ", 0, NULL);
    6726              :                 }
    6727              : 
    6728       227085 :               info.option = "-isystem";
    6729       227085 :               info.append = "include";
    6730       227085 :               info.append_len = strlen (info.append);
    6731       227085 :               info.omit_relative = false;
    6732       227085 :               info.separate_options = true;
    6733       227085 :               info.realpaths = false;
    6734              : 
    6735       227085 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6736              : 
    6737       227085 :               info.append = "include-fixed";
    6738       227085 :               if (*sysroot_hdrs_suffix_spec)
    6739            0 :                 info.append = concat (info.append, dir_separator_str,
    6740              :                                       multilib_dir, NULL);
    6741       227085 :               else if (multiarch_dir)
    6742              :                 {
    6743              :                   /* For multiarch, search include-fixed/<multiarch-dir>
    6744              :                      before include-fixed.  */
    6745            0 :                   info.append = concat (info.append, dir_separator_str,
    6746              :                                         multiarch_dir, NULL);
    6747            0 :                   info.append_len = strlen (info.append);
    6748            0 :                   for_each_path (&include_prefixes, false,
    6749              :                                  info.append_len, info);
    6750              : 
    6751            0 :                   info.append = "include-fixed";
    6752              :                 }
    6753       227085 :               info.append_len = strlen (info.append);
    6754       227085 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6755              :             }
    6756       227085 :             break;
    6757              : 
    6758        96277 :           case 'o':
    6759              :             /* We are going to expand `%o' into `@FILE', where FILE
    6760              :                is a newly-created temporary filename.  The filenames
    6761              :                that would usually be expanded in place of %o will be
    6762              :                written to the temporary file.  */
    6763        96277 :             if (at_file_supplied)
    6764            6 :               open_at_file ();
    6765              : 
    6766       428785 :             for (i = 0; i < n_infiles + lang_specific_extra_outfiles; i++)
    6767       332508 :               if (outfiles[i])
    6768       332468 :                 store_arg (outfiles[i], 0, 0);
    6769              : 
    6770        96277 :             if (at_file_supplied)
    6771            6 :               close_at_file ();
    6772              :             break;
    6773              : 
    6774         3759 :           case 'O':
    6775         3759 :             obstack_grow (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    6776         3759 :             arg_going = 1;
    6777         3759 :             break;
    6778              : 
    6779       544767 :           case 's':
    6780       544767 :             this_is_library_file = 1;
    6781       544767 :             break;
    6782              : 
    6783            0 :           case 'T':
    6784            0 :             this_is_linker_script = 1;
    6785            0 :             break;
    6786              : 
    6787          420 :           case 'V':
    6788          420 :             outfiles[input_file_number] = NULL;
    6789          420 :             break;
    6790              : 
    6791       101178 :           case 'w':
    6792       101178 :             this_is_output_file = 1;
    6793       101178 :             break;
    6794              : 
    6795       178566 :           case 'W':
    6796       178566 :             {
    6797       178566 :               unsigned int cur_index = argbuf.length ();
    6798              :               /* Handle the {...} following the %W.  */
    6799       178566 :               if (*p != '{')
    6800            0 :                 fatal_error (input_location,
    6801              :                              "spec %qs has invalid %<%%W%c%>", spec, *p);
    6802       178566 :               p = handle_braces (p + 1);
    6803       178566 :               if (p == 0)
    6804              :                 return -1;
    6805       178566 :               end_going_arg ();
    6806              :               /* If any args were output, mark the last one for deletion
    6807              :                  on failure.  */
    6808       357132 :               if (argbuf.length () != cur_index)
    6809       175387 :                 record_temp_file (argbuf.last (), 0, 1);
    6810              :               break;
    6811              :             }
    6812              : 
    6813       307030 :           case '@':
    6814              :             /* Handle the {...} following the %@.  */
    6815       307030 :             if (*p != '{')
    6816            0 :               fatal_error (input_location,
    6817              :                            "spec %qs has invalid %<%%@%c%>", spec, *p);
    6818       307030 :             if (at_file_supplied)
    6819           67 :               open_at_file ();
    6820       307030 :             p = handle_braces (p + 1);
    6821       307030 :             if (at_file_supplied)
    6822           67 :               close_at_file ();
    6823       307030 :             if (p == 0)
    6824              :               return -1;
    6825              :             break;
    6826              : 
    6827              :           /* %x{OPTION} records OPTION for %X to output.  */
    6828            0 :           case 'x':
    6829            0 :             {
    6830            0 :               const char *p1 = p;
    6831            0 :               char *string;
    6832              : 
    6833              :               /* Skip past the option value and make a copy.  */
    6834            0 :               if (*p != '{')
    6835            0 :                 fatal_error (input_location,
    6836              :                              "spec %qs has invalid %<%%x%c%>", spec, *p);
    6837            0 :               while (*p++ != '}')
    6838              :                 ;
    6839            0 :               string = save_string (p1 + 1, p - p1 - 2);
    6840              : 
    6841              :               /* See if we already recorded this option.  */
    6842            0 :               for (const char *opt : linker_options)
    6843            0 :                 if (! strcmp (string, opt))
    6844              :                   {
    6845            0 :                     free (string);
    6846            0 :                     return 0;
    6847              :                   }
    6848              : 
    6849              :               /* This option is new; add it.  */
    6850            0 :               add_linker_option (string, strlen (string));
    6851            0 :               free (string);
    6852              :             }
    6853            0 :             break;
    6854              : 
    6855              :           /* Dump out the options accumulated previously using %x.  */
    6856        96277 :           case 'X':
    6857        96277 :             do_specs_vec (linker_options);
    6858        96277 :             break;
    6859              : 
    6860              :           /* Dump out the options accumulated previously using -Wa,.  */
    6861       164892 :           case 'Y':
    6862       164892 :             do_specs_vec (assembler_options);
    6863       164892 :             break;
    6864              : 
    6865              :           /* Dump out the options accumulated previously using -Wp,.  */
    6866       210753 :           case 'Z':
    6867       210753 :             do_specs_vec (preprocessor_options);
    6868       210753 :             break;
    6869              : 
    6870              :             /* Here are digits and numbers that just process
    6871              :                a certain constant string as a spec.  */
    6872              : 
    6873       288771 :           case '1':
    6874       288771 :             value = do_spec_1 (cc1_spec, 0, NULL);
    6875       288771 :             if (value != 0)
    6876              :               return value;
    6877              :             break;
    6878              : 
    6879       100334 :           case '2':
    6880       100334 :             value = do_spec_1 (cc1plus_spec, 0, NULL);
    6881       100334 :             if (value != 0)
    6882              :               return value;
    6883              :             break;
    6884              : 
    6885       164892 :           case 'a':
    6886       164892 :             value = do_spec_1 (asm_spec, 0, NULL);
    6887       164892 :             if (value != 0)
    6888              :               return value;
    6889              :             break;
    6890              : 
    6891       164892 :           case 'A':
    6892       164892 :             value = do_spec_1 (asm_final_spec, 0, NULL);
    6893       164892 :             if (value != 0)
    6894              :               return value;
    6895              :             break;
    6896              : 
    6897       210753 :           case 'C':
    6898       210753 :             {
    6899       110551 :               const char *const spec
    6900       210753 :                 = (input_file_compiler->cpp_spec
    6901       210753 :                    ? input_file_compiler->cpp_spec
    6902              :                    : cpp_spec);
    6903       210753 :               value = do_spec_1 (spec, 0, NULL);
    6904       210753 :               if (value != 0)
    6905              :                 return value;
    6906              :             }
    6907              :             break;
    6908              : 
    6909        96073 :           case 'E':
    6910        96073 :             value = do_spec_1 (endfile_spec, 0, NULL);
    6911        96073 :             if (value != 0)
    6912              :               return value;
    6913              :             break;
    6914              : 
    6915        96277 :           case 'l':
    6916        96277 :             value = do_spec_1 (link_spec, 0, NULL);
    6917        96277 :             if (value != 0)
    6918              :               return value;
    6919              :             break;
    6920              : 
    6921       186595 :           case 'L':
    6922       186595 :             value = do_spec_1 (lib_spec, 0, NULL);
    6923       186595 :             if (value != 0)
    6924              :               return value;
    6925              :             break;
    6926              : 
    6927            0 :           case 'M':
    6928            0 :             if (multilib_os_dir == NULL)
    6929            0 :               obstack_1grow (&obstack, '.');
    6930              :             else
    6931            0 :               obstack_grow (&obstack, multilib_os_dir,
    6932              :                             strlen (multilib_os_dir));
    6933              :             break;
    6934              : 
    6935       372996 :           case 'G':
    6936       372996 :             value = do_spec_1 (libgcc_spec, 0, NULL);
    6937       372996 :             if (value != 0)
    6938              :               return value;
    6939              :             break;
    6940              : 
    6941            0 :           case 'R':
    6942              :             /* We assume there is a directory
    6943              :                separator at the end of this string.  */
    6944            0 :             if (target_system_root)
    6945              :               {
    6946            0 :                 obstack_grow (&obstack, target_system_root,
    6947              :                               strlen (target_system_root));
    6948            0 :                 if (target_sysroot_suffix)
    6949            0 :                   obstack_grow (&obstack, target_sysroot_suffix,
    6950              :                                 strlen (target_sysroot_suffix));
    6951              :               }
    6952              :             break;
    6953              : 
    6954        96073 :           case 'S':
    6955        96073 :             value = do_spec_1 (startfile_spec, 0, NULL);
    6956        96073 :             if (value != 0)
    6957              :               return value;
    6958              :             break;
    6959              : 
    6960              :             /* Here we define characters other than letters and digits.  */
    6961              : 
    6962     40577113 :           case '{':
    6963     40577113 :             p = handle_braces (p);
    6964     40577113 :             if (p == 0)
    6965              :               return -1;
    6966              :             break;
    6967              : 
    6968       444121 :           case ':':
    6969       444121 :             p = handle_spec_function (p, NULL, soft_matched_part);
    6970       444121 :             if (p == 0)
    6971              :               return -1;
    6972              :             break;
    6973              : 
    6974            0 :           case '%':
    6975            0 :             obstack_1grow (&obstack, '%');
    6976            0 :             break;
    6977              : 
    6978              :           case '.':
    6979              :             {
    6980              :               unsigned len = 0;
    6981              : 
    6982        11906 :               while (p[len] && p[len] != ' ' && p[len] != '%')
    6983         5971 :                 len++;
    6984         5935 :               suffix_subst = save_string (p - 1, len + 1);
    6985         5935 :               p += len;
    6986              :             }
    6987         5935 :            break;
    6988              : 
    6989              :            /* Henceforth ignore the option(s) matching the pattern
    6990              :               after the %<.  */
    6991      1487548 :           case '<':
    6992      1487548 :           case '>':
    6993      1487548 :             {
    6994      1487548 :               unsigned len = 0;
    6995      1487548 :               int have_wildcard = 0;
    6996      1487548 :               int i;
    6997      1487548 :               int switch_option;
    6998              : 
    6999      1487548 :               if (c == '>')
    7000      1487548 :                 switch_option = SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC;
    7001              :               else
    7002      1487526 :                 switch_option = SWITCH_IGNORE;
    7003              : 
    7004     17959817 :               while (p[len] && p[len] != ' ' && p[len] != '\t')
    7005     16472269 :                 len++;
    7006              : 
    7007      1487548 :               if (p[len-1] == '*')
    7008        14741 :                 have_wildcard = 1;
    7009              : 
    7010     35721417 :               for (i = 0; i < n_switches; i++)
    7011     34233869 :                 if (!strncmp (switches[i].part1, p, len - have_wildcard)
    7012        45638 :                     && (have_wildcard || switches[i].part1[len] == '\0'))
    7013              :                   {
    7014        45365 :                     switches[i].live_cond |= switch_option;
    7015              :                     /* User switch be validated from validate_all_switches.
    7016              :                        when the definition is seen from the spec file.
    7017              :                        If not defined anywhere, will be rejected.  */
    7018        45365 :                     if (switches[i].known)
    7019        45365 :                       switches[i].validated = true;
    7020              :                   }
    7021              : 
    7022              :               p += len;
    7023              :             }
    7024              :             break;
    7025              : 
    7026         6802 :           case '*':
    7027         6802 :             if (soft_matched_part)
    7028              :               {
    7029         6802 :                 if (soft_matched_part[0])
    7030          334 :                   do_spec_1 (soft_matched_part, 1, NULL);
    7031              :                 /* Only insert a space after the substitution if it is at the
    7032              :                    end of the current sequence.  So if:
    7033              : 
    7034              :                      "%{foo=*:bar%*}%{foo=*:one%*two}"
    7035              : 
    7036              :                    matches -foo=hello then it will produce:
    7037              : 
    7038              :                      barhello onehellotwo
    7039              :                 */
    7040         6802 :                 if (*p == 0 || *p == '}')
    7041         6802 :                   do_spec_1 (" ", 0, NULL);
    7042              :               }
    7043              :             else
    7044              :               /* Catch the case where a spec string contains something like
    7045              :                  '%{foo:%*}'.  i.e. there is no * in the pattern on the left
    7046              :                  hand side of the :.  */
    7047            0 :               error ("spec failure: %<%%*%> has not been initialized by pattern match");
    7048              :             break;
    7049              : 
    7050              :             /* Process a string found as the value of a spec given by name.
    7051              :                This feature allows individual machine descriptions
    7052              :                to add and use their own specs.  */
    7053              :           case '(':
    7054              :             {
    7055     33643981 :               const char *name = p;
    7056              :               struct spec_list *sl;
    7057              :               int len;
    7058              : 
    7059              :               /* The string after the S/P is the name of a spec that is to be
    7060              :                  processed.  */
    7061     33643981 :               while (*p && *p != ')')
    7062     31048007 :                 p++;
    7063              : 
    7064              :               /* See if it's in the list.  */
    7065     35587743 :               for (len = p - name, sl = specs; sl; sl = sl->next)
    7066     35587743 :                 if (sl->name_len == len && !strncmp (sl->name, name, len))
    7067              :                   {
    7068      2595974 :                     name = *(sl->ptr_spec);
    7069              : #ifdef DEBUG_SPECS
    7070              :                     fnotice (stderr, "Processing spec (%s), which is '%s'\n",
    7071              :                              sl->name, name);
    7072              : #endif
    7073      2595974 :                     break;
    7074              :                   }
    7075              : 
    7076      2595974 :               if (sl)
    7077              :                 {
    7078      2595974 :                   value = do_spec_1 (name, 0, NULL);
    7079      2595974 :                   if (value != 0)
    7080              :                     return value;
    7081              :                 }
    7082              : 
    7083              :               /* Discard the closing paren.  */
    7084      2590645 :               if (*p)
    7085      2590645 :                 p++;
    7086              :             }
    7087              :             break;
    7088              : 
    7089            9 :           case '"':
    7090              :             /* End a previous argument, if there is one, then issue an
    7091              :                empty argument.  */
    7092            9 :             end_going_arg ();
    7093            9 :             arg_going = 1;
    7094            9 :             end_going_arg ();
    7095            9 :             break;
    7096              : 
    7097            0 :           default:
    7098            0 :             error ("spec failure: unrecognized spec option %qc", c);
    7099            0 :             break;
    7100              :           }
    7101              :         break;
    7102              : 
    7103            0 :       case '\\':
    7104              :         /* Backslash: treat next character as ordinary.  */
    7105            0 :         c = *p++;
    7106              : 
    7107              :         /* When adding more cases that previously matched default, make
    7108              :            sure to adjust quote_spec_char_p as well.  */
    7109              : 
    7110              :         /* Fall through.  */
    7111    366658075 :       default:
    7112              :         /* Ordinary character: put it into the current argument.  */
    7113    366658075 :         obstack_1grow (&obstack, c);
    7114    366658075 :         arg_going = 1;
    7115              :       }
    7116              : 
    7117              :   /* End of string.  If we are processing a spec function, we need to
    7118              :      end any pending argument.  */
    7119     53464291 :   if (processing_spec_function)
    7120      4548604 :     end_going_arg ();
    7121              : 
    7122              :   return 0;
    7123              : }
    7124              : 
    7125              : /* Look up a spec function.  */
    7126              : 
    7127              : static const struct spec_function *
    7128      2095224 : lookup_spec_function (const char *name)
    7129              : {
    7130      2095224 :   const struct spec_function *sf;
    7131              : 
    7132     25124452 :   for (sf = static_spec_functions; sf->name != NULL; sf++)
    7133     25124452 :     if (strcmp (sf->name, name) == 0)
    7134              :       return sf;
    7135              : 
    7136              :   return NULL;
    7137              : }
    7138              : 
    7139              : /* Evaluate a spec function.  */
    7140              : 
    7141              : static const char *
    7142      2095224 : eval_spec_function (const char *func, const char *args,
    7143              :                     const char *soft_matched_part)
    7144              : {
    7145      2095224 :   const struct spec_function *sf;
    7146      2095224 :   const char *funcval;
    7147              : 
    7148              :   /* Saved spec processing context.  */
    7149      2095224 :   vec<const_char_p> save_argbuf;
    7150              : 
    7151      2095224 :   int save_arg_going;
    7152      2095224 :   int save_delete_this_arg;
    7153      2095224 :   int save_this_is_output_file;
    7154      2095224 :   int save_this_is_library_file;
    7155      2095224 :   int save_input_from_pipe;
    7156      2095224 :   int save_this_is_linker_script;
    7157      2095224 :   const char *save_suffix_subst;
    7158              : 
    7159      2095224 :   int save_growing_size;
    7160      2095224 :   void *save_growing_value = NULL;
    7161              : 
    7162      2095224 :   sf = lookup_spec_function (func);
    7163      2095224 :   if (sf == NULL)
    7164            0 :     fatal_error (input_location, "unknown spec function %qs", func);
    7165              : 
    7166              :   /* Push the spec processing context.  */
    7167      2095224 :   save_argbuf = argbuf;
    7168              : 
    7169      2095224 :   save_arg_going = arg_going;
    7170      2095224 :   save_delete_this_arg = delete_this_arg;
    7171      2095224 :   save_this_is_output_file = this_is_output_file;
    7172      2095224 :   save_this_is_library_file = this_is_library_file;
    7173      2095224 :   save_this_is_linker_script = this_is_linker_script;
    7174      2095224 :   save_input_from_pipe = input_from_pipe;
    7175      2095224 :   save_suffix_subst = suffix_subst;
    7176              : 
    7177              :   /* If we have some object growing now, finalize it so the args and function
    7178              :      eval proceed from a cleared context.  This is needed to prevent the first
    7179              :      constructed arg from mistakenly including the growing value.  We'll push
    7180              :      this value back on the obstack once the function evaluation is done, to
    7181              :      restore a consistent processing context for our caller.  This is fine as
    7182              :      the address of growing objects isn't guaranteed to remain stable until
    7183              :      they are finalized, and we expect this situation to be rare enough for
    7184              :      the extra copy not to be an issue.  */
    7185      2095224 :   save_growing_size = obstack_object_size (&obstack);
    7186      2095224 :   if (save_growing_size > 0)
    7187        43119 :     save_growing_value = obstack_finish (&obstack);
    7188              : 
    7189              :   /* Create a new spec processing context, and build the function
    7190              :      arguments.  */
    7191              : 
    7192      2095224 :   alloc_args ();
    7193      2095224 :   if (do_spec_2 (args, soft_matched_part) < 0)
    7194            0 :     fatal_error (input_location, "error in arguments to spec function %qs",
    7195              :                  func);
    7196              : 
    7197              :   /* argbuf_index is an index for the next argument to be inserted, and
    7198              :      so contains the count of the args already inserted.  */
    7199              : 
    7200      6285672 :   funcval = (*sf->func) (argbuf.length (),
    7201              :                          argbuf.address ());
    7202              : 
    7203              :   /* Pop the spec processing context.  */
    7204      2095224 :   argbuf.release ();
    7205      2095224 :   argbuf = save_argbuf;
    7206              : 
    7207      2095224 :   arg_going = save_arg_going;
    7208      2095224 :   delete_this_arg = save_delete_this_arg;
    7209      2095224 :   this_is_output_file = save_this_is_output_file;
    7210      2095224 :   this_is_library_file = save_this_is_library_file;
    7211      2095224 :   this_is_linker_script = save_this_is_linker_script;
    7212      2095224 :   input_from_pipe = save_input_from_pipe;
    7213      2095224 :   suffix_subst = save_suffix_subst;
    7214              : 
    7215      2095224 :   if (save_growing_size > 0)
    7216        43119 :     obstack_grow (&obstack, save_growing_value, save_growing_size);
    7217              : 
    7218      2095224 :   return funcval;
    7219              : }
    7220              : 
    7221              : /* Handle a spec function call of the form:
    7222              : 
    7223              :    %:function(args)
    7224              : 
    7225              :    ARGS is processed as a spec in a separate context and split into an
    7226              :    argument vector in the normal fashion.  The function returns a string
    7227              :    containing a spec which we then process in the caller's context, or
    7228              :    NULL if no processing is required.
    7229              : 
    7230              :    If RETVAL_NONNULL is not NULL, then store a bool whether function
    7231              :    returned non-NULL.
    7232              : 
    7233              :    SOFT_MATCHED_PART holds the current value of a matched * pattern, which
    7234              :    may be re-expanded with a %* as part of the function arguments.  */
    7235              : 
    7236              : static const char *
    7237      2095224 : handle_spec_function (const char *p, bool *retval_nonnull,
    7238              :                       const char *soft_matched_part)
    7239              : {
    7240      2095224 :   char *func, *args;
    7241      2095224 :   const char *endp, *funcval;
    7242      2095224 :   int count;
    7243              : 
    7244      2095224 :   processing_spec_function++;
    7245              : 
    7246              :   /* Get the function name.  */
    7247     19472033 :   for (endp = p; *endp != '\0'; endp++)
    7248              :     {
    7249     19472033 :       if (*endp == '(')         /* ) */
    7250              :         break;
    7251              :       /* Only allow [A-Za-z0-9], -, and _ in function names.  */
    7252     17376809 :       if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
    7253            0 :         fatal_error (input_location, "malformed spec function name");
    7254              :     }
    7255      2095224 :   if (*endp != '(')             /* ) */
    7256            0 :     fatal_error (input_location, "no arguments for spec function");
    7257      2095224 :   func = save_string (p, endp - p);
    7258      2095224 :   p = ++endp;
    7259              : 
    7260              :   /* Get the arguments.  */
    7261     25545607 :   for (count = 0; *endp != '\0'; endp++)
    7262              :     {
    7263              :       /* ( */
    7264     25545607 :       if (*endp == ')')
    7265              :         {
    7266      2185748 :           if (count == 0)
    7267              :             break;
    7268        90524 :           count--;
    7269              :         }
    7270     23359859 :       else if (*endp == '(')    /* ) */
    7271        90524 :         count++;
    7272              :     }
    7273              :   /* ( */
    7274      2095224 :   if (*endp != ')')
    7275            0 :     fatal_error (input_location, "malformed spec function arguments");
    7276      2095224 :   args = save_string (p, endp - p);
    7277      2095224 :   p = ++endp;
    7278              : 
    7279              :   /* p now points to just past the end of the spec function expression.  */
    7280              : 
    7281      2095224 :   funcval = eval_spec_function (func, args, soft_matched_part);
    7282      2095224 :   if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
    7283              :     p = NULL;
    7284      2095224 :   if (retval_nonnull)
    7285      1651103 :     *retval_nonnull = funcval != NULL;
    7286              : 
    7287      2095224 :   free (func);
    7288      2095224 :   free (args);
    7289              : 
    7290      2095224 :   processing_spec_function--;
    7291              : 
    7292      2095224 :   return p;
    7293              : }
    7294              : 
    7295              : /* Inline subroutine of handle_braces.  Returns true if the current
    7296              :    input suffix matches the atom bracketed by ATOM and END_ATOM.  */
    7297              : static inline bool
    7298            0 : input_suffix_matches (const char *atom, const char *end_atom)
    7299              : {
    7300            0 :   return (input_suffix
    7301            0 :           && !strncmp (input_suffix, atom, end_atom - atom)
    7302            0 :           && input_suffix[end_atom - atom] == '\0');
    7303              : }
    7304              : 
    7305              : /* Subroutine of handle_braces.  Returns true if the current
    7306              :    input file's spec name matches the atom bracketed by ATOM and END_ATOM.  */
    7307              : static bool
    7308            0 : input_spec_matches (const char *atom, const char *end_atom)
    7309              : {
    7310            0 :   return (input_file_compiler
    7311            0 :           && input_file_compiler->suffix
    7312            0 :           && input_file_compiler->suffix[0] != '\0'
    7313            0 :           && !strncmp (input_file_compiler->suffix + 1, atom,
    7314            0 :                        end_atom - atom)
    7315            0 :           && input_file_compiler->suffix[end_atom - atom + 1] == '\0');
    7316              : }
    7317              : 
    7318              : /* Subroutine of handle_braces.  Returns true if a switch
    7319              :    matching the atom bracketed by ATOM and END_ATOM appeared on the
    7320              :    command line.  */
    7321              : static bool
    7322     38969274 : switch_matches (const char *atom, const char *end_atom, int starred)
    7323              : {
    7324     38969274 :   int i;
    7325     38969274 :   int len = end_atom - atom;
    7326     38969274 :   int plen = starred ? len : -1;
    7327              : 
    7328    919891295 :   for (i = 0; i < n_switches; i++)
    7329    882316098 :     if (!strncmp (switches[i].part1, atom, len)
    7330      2354289 :         && (starred || switches[i].part1[len] == '\0')
    7331    883710808 :         && check_live_switch (i, plen))
    7332              :       return true;
    7333              : 
    7334              :     /* Check if a switch with separated form matching the atom.
    7335              :        We check -D and -U switches. */
    7336    880922022 :     else if (switches[i].args != 0)
    7337              :       {
    7338    203739693 :         if ((*switches[i].part1 == 'D' || *switches[i].part1 == 'U')
    7339      8803316 :             && *switches[i].part1 == atom[0])
    7340              :           {
    7341            1 :             if (!strncmp (switches[i].args[0], &atom[1], len - 1)
    7342            1 :                 && (starred || (switches[i].part1[1] == '\0'
    7343            1 :                                 && switches[i].args[0][len - 1] == '\0'))
    7344            2 :                 && check_live_switch (i, (starred ? 1 : -1)))
    7345              :               return true;
    7346              :           }
    7347              :       }
    7348              : 
    7349              :   return false;
    7350              : }
    7351              : 
    7352              : /* Inline subroutine of handle_braces.  Mark all of the switches which
    7353              :    match ATOM (extends to END_ATOM; STARRED indicates whether there
    7354              :    was a star after the atom) for later processing.  */
    7355              : static inline void
    7356     11343427 : mark_matching_switches (const char *atom, const char *end_atom, int starred)
    7357              : {
    7358     11343427 :   int i;
    7359     11343427 :   int len = end_atom - atom;
    7360     11343427 :   int plen = starred ? len : -1;
    7361              : 
    7362    271531871 :   for (i = 0; i < n_switches; i++)
    7363    260188444 :     if (!strncmp (switches[i].part1, atom, len)
    7364      6474775 :         && (starred || switches[i].part1[len] == '\0')
    7365    266440091 :         && check_live_switch (i, plen))
    7366      6206292 :       switches[i].ordering = 1;
    7367     11343427 : }
    7368              : 
    7369              : /* Inline subroutine of handle_braces.  Process all the currently
    7370              :    marked switches through give_switch, and clear the marks.  */
    7371              : static inline void
    7372      9844855 : process_marked_switches (void)
    7373              : {
    7374      9844855 :   int i;
    7375              : 
    7376    235615676 :   for (i = 0; i < n_switches; i++)
    7377    225770821 :     if (switches[i].ordering == 1)
    7378              :       {
    7379      6206292 :         switches[i].ordering = 0;
    7380      6206292 :         give_switch (i, 0);
    7381              :       }
    7382      9844855 : }
    7383              : 
    7384              : /* Handle a %{ ... } construct.  P points just inside the leading {.
    7385              :    Returns a pointer one past the end of the brace block, or 0
    7386              :    if we call do_spec_1 and that returns -1.  */
    7387              : 
    7388              : static const char *
    7389     41062709 : handle_braces (const char *p)
    7390              : {
    7391     41062709 :   const char *atom, *end_atom;
    7392     41062709 :   const char *d_atom = NULL, *d_end_atom = NULL;
    7393     41062709 :   char *esc_buf = NULL, *d_esc_buf = NULL;
    7394     41062709 :   int esc;
    7395     41062709 :   const char *orig = p;
    7396              : 
    7397     41062709 :   bool a_is_suffix;
    7398     41062709 :   bool a_is_spectype;
    7399     41062709 :   bool a_is_starred;
    7400     41062709 :   bool a_is_negated;
    7401     41062709 :   bool a_matched;
    7402              : 
    7403     41062709 :   bool a_must_be_last = false;
    7404     41062709 :   bool ordered_set    = false;
    7405     41062709 :   bool disjunct_set   = false;
    7406     41062709 :   bool disj_matched   = false;
    7407     41062709 :   bool disj_starred   = true;
    7408     41062709 :   bool n_way_choice   = false;
    7409     41062709 :   bool n_way_matched  = false;
    7410              : 
    7411              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    7412              : 
    7413     54574879 :   do
    7414              :     {
    7415     54574879 :       if (a_must_be_last)
    7416            0 :         goto invalid;
    7417              : 
    7418              :       /* Scan one "atom" (S in the description above of %{}, possibly
    7419              :          with '!', '.', '@', ',', or '*' modifiers).  */
    7420     54574879 :       a_matched = false;
    7421     54574879 :       a_is_suffix = false;
    7422     54574879 :       a_is_starred = false;
    7423     54574879 :       a_is_negated = false;
    7424     54574879 :       a_is_spectype = false;
    7425              : 
    7426     62168569 :       SKIP_WHITE ();
    7427     54574879 :       if (*p == '!')
    7428     13195254 :         p++, a_is_negated = true;
    7429              : 
    7430     54574879 :       SKIP_WHITE ();
    7431     54574879 :       if (*p == '%' && p[1] == ':')
    7432              :         {
    7433      1651103 :           atom = NULL;
    7434      1651103 :           end_atom = NULL;
    7435      1651103 :           p = handle_spec_function (p + 2, &a_matched, NULL);
    7436              :         }
    7437              :       else
    7438              :         {
    7439     52923776 :           if (*p == '.')
    7440            0 :             p++, a_is_suffix = true;
    7441     52923776 :           else if (*p == ',')
    7442            0 :             p++, a_is_spectype = true;
    7443              : 
    7444     52923776 :           atom = p;
    7445     52923776 :           esc = 0;
    7446     52923776 :           while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    7447    398752962 :                  || *p == ',' || *p == '.' || *p == '@' || *p == '\\')
    7448              :             {
    7449    345829186 :               if (*p == '\\')
    7450              :                 {
    7451            0 :                   p++;
    7452            0 :                   if (!*p)
    7453            0 :                     fatal_error (input_location,
    7454              :                                  "braced spec %qs ends in escape", orig);
    7455            0 :                   esc++;
    7456              :                 }
    7457    345829186 :               p++;
    7458              :             }
    7459     52923776 :           end_atom = p;
    7460              : 
    7461     52923776 :           if (esc)
    7462              :             {
    7463            0 :               const char *ap;
    7464            0 :               char *ep;
    7465              : 
    7466            0 :               if (esc_buf && esc_buf != d_esc_buf)
    7467            0 :                 free (esc_buf);
    7468            0 :               esc_buf = NULL;
    7469            0 :               ep = esc_buf = (char *) xmalloc (end_atom - atom - esc + 1);
    7470            0 :               for (ap = atom; ap != end_atom; ap++, ep++)
    7471              :                 {
    7472            0 :                   if (*ap == '\\')
    7473            0 :                     ap++;
    7474            0 :                   *ep = *ap;
    7475              :                 }
    7476            0 :               *ep = '\0';
    7477            0 :               atom = esc_buf;
    7478            0 :               end_atom = ep;
    7479              :             }
    7480              : 
    7481     52923776 :           if (*p == '*')
    7482     11957899 :             p++, a_is_starred = 1;
    7483              :         }
    7484              : 
    7485     54574879 :       SKIP_WHITE ();
    7486     54574879 :       switch (*p)
    7487              :         {
    7488     11343427 :         case '&': case '}':
    7489              :           /* Substitute the switch(es) indicated by the current atom.  */
    7490     11343427 :           ordered_set = true;
    7491     11343427 :           if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
    7492     11343427 :               || a_is_spectype || atom == end_atom)
    7493            0 :             goto invalid;
    7494              : 
    7495     11343427 :           mark_matching_switches (atom, end_atom, a_is_starred);
    7496              : 
    7497     11343427 :           if (*p == '}')
    7498      9844855 :             process_marked_switches ();
    7499              :           break;
    7500              : 
    7501     43231452 :         case '|': case ':':
    7502              :           /* Substitute some text if the current atom appears as a switch
    7503              :              or suffix.  */
    7504     43231452 :           disjunct_set = true;
    7505     43231452 :           if (ordered_set)
    7506            0 :             goto invalid;
    7507              : 
    7508     43231452 :           if (atom && atom == end_atom)
    7509              :             {
    7510      1784907 :               if (!n_way_choice || disj_matched || *p == '|'
    7511      1784907 :                   || a_is_negated || a_is_suffix || a_is_spectype
    7512      1784907 :                   || a_is_starred)
    7513            0 :                 goto invalid;
    7514              : 
    7515              :               /* An empty term may appear as the last choice of an
    7516              :                  N-way choice set; it means "otherwise".  */
    7517      1784907 :               a_must_be_last = true;
    7518      1784907 :               disj_matched = !n_way_matched;
    7519      1784907 :               disj_starred = false;
    7520              :             }
    7521              :           else
    7522              :             {
    7523     41446545 :               if ((a_is_suffix || a_is_spectype) && a_is_starred)
    7524            0 :                 goto invalid;
    7525              : 
    7526     41446545 :               if (!a_is_starred)
    7527     35796786 :                 disj_starred = false;
    7528              : 
    7529              :               /* Don't bother testing this atom if we already have a
    7530              :                  match.  */
    7531     41446545 :               if (!disj_matched && !n_way_matched)
    7532              :                 {
    7533     40418665 :                   if (atom == NULL)
    7534              :                     /* a_matched is already set by handle_spec_function.  */;
    7535     38872993 :                   else if (a_is_suffix)
    7536            0 :                     a_matched = input_suffix_matches (atom, end_atom);
    7537     38872993 :                   else if (a_is_spectype)
    7538            0 :                     a_matched = input_spec_matches (atom, end_atom);
    7539              :                   else
    7540     38872993 :                     a_matched = switch_matches (atom, end_atom, a_is_starred);
    7541              : 
    7542     40418665 :                   if (a_matched != a_is_negated)
    7543              :                     {
    7544     13068174 :                       disj_matched = true;
    7545     13068174 :                       d_atom = atom;
    7546     13068174 :                       d_end_atom = end_atom;
    7547     13068174 :                       d_esc_buf = esc_buf;
    7548              :                     }
    7549              :                 }
    7550              :             }
    7551              : 
    7552     43231452 :           if (*p == ':')
    7553              :             {
    7554              :               /* Found the body, that is, the text to substitute if the
    7555              :                  current disjunction matches.  */
    7556     68484790 :               p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
    7557     34242395 :                                       disj_matched && !n_way_matched);
    7558     34242395 :               if (p == 0)
    7559        35295 :                 goto done;
    7560              : 
    7561              :               /* If we have an N-way choice, reset state for the next
    7562              :                  disjunction.  */
    7563     34207100 :               if (*p == ';')
    7564              :                 {
    7565      3024541 :                   n_way_choice = true;
    7566      3024541 :                   n_way_matched |= disj_matched;
    7567      3024541 :                   disj_matched = false;
    7568      3024541 :                   disj_starred = true;
    7569      3024541 :                   d_atom = d_end_atom = NULL;
    7570              :                 }
    7571              :             }
    7572              :           break;
    7573              : 
    7574            0 :         default:
    7575            0 :           goto invalid;
    7576              :         }
    7577              :     }
    7578     54539584 :   while (*p++ != '}');
    7579              : 
    7580     41027414 :  done:
    7581     41062709 :   if (d_esc_buf && d_esc_buf != esc_buf)
    7582            0 :     free (d_esc_buf);
    7583     41062709 :   if (esc_buf)
    7584            0 :     free (esc_buf);
    7585              : 
    7586     41062709 :   return p;
    7587              : 
    7588            0 :  invalid:
    7589            0 :   fatal_error (input_location, "braced spec %qs is invalid at %qc", orig, *p);
    7590              : 
    7591              : #undef SKIP_WHITE
    7592              : }
    7593              : 
    7594              : /* Subroutine of handle_braces.  Scan and process a brace substitution body
    7595              :    (X in the description of %{} syntax).  P points one past the colon;
    7596              :    ATOM and END_ATOM bracket the first atom which was found to be true
    7597              :    (present) in the current disjunction; STARRED indicates whether all
    7598              :    the atoms in the current disjunction were starred (for syntax validation);
    7599              :    MATCHED indicates whether the disjunction matched or not, and therefore
    7600              :    whether or not the body is to be processed through do_spec_1 or just
    7601              :    skipped.  Returns a pointer to the closing } or ;, or 0 if do_spec_1
    7602              :    returns -1.  */
    7603              : 
    7604              : static const char *
    7605     34242395 : process_brace_body (const char *p, const char *atom, const char *end_atom,
    7606              :                     int starred, int matched)
    7607              : {
    7608     34242395 :   const char *body, *end_body;
    7609     34242395 :   unsigned int nesting_level;
    7610     34242395 :   bool have_subst     = false;
    7611              : 
    7612              :   /* Locate the closing } or ;, honoring nested braces.
    7613              :      Trim trailing whitespace.  */
    7614     34242395 :   body = p;
    7615     34242395 :   nesting_level = 1;
    7616  11592362823 :   for (;;)
    7617              :     {
    7618   5813302609 :       if (*p == '{')
    7619    173357821 :         nesting_level++;
    7620   5639944788 :       else if (*p == '}')
    7621              :         {
    7622    204575675 :           if (!--nesting_level)
    7623              :             break;
    7624              :         }
    7625   5435369113 :       else if (*p == ';' && nesting_level == 1)
    7626              :         break;
    7627   5432344572 :       else if (*p == '%' && p[1] == '*' && nesting_level == 1)
    7628              :         have_subst = true;
    7629   5431550327 :       else if (*p == '\0')
    7630            0 :         goto invalid;
    7631   5779060214 :       p++;
    7632              :     }
    7633              : 
    7634              :   end_body = p;
    7635     37044685 :   while (end_body[-1] == ' ' || end_body[-1] == '\t')
    7636      2802290 :     end_body--;
    7637              : 
    7638     34242395 :   if (have_subst && !starred)
    7639            0 :     goto invalid;
    7640              : 
    7641     34242395 :   if (matched)
    7642              :     {
    7643              :       /* Copy the substitution body to permanent storage and execute it.
    7644              :          If have_subst is false, this is a simple matter of running the
    7645              :          body through do_spec_1...  */
    7646     14030503 :       char *string = save_string (body, end_body - body);
    7647     14030503 :       if (!have_subst)
    7648              :         {
    7649     14023705 :           if (do_spec_1 (string, 0, NULL) < 0)
    7650              :             {
    7651        35295 :               free (string);
    7652        35295 :               return 0;
    7653              :             }
    7654              :         }
    7655              :       else
    7656              :         {
    7657              :           /* ... but if have_subst is true, we have to process the
    7658              :              body once for each matching switch, with %* set to the
    7659              :              variant part of the switch.  */
    7660         6798 :           unsigned int hard_match_len = end_atom - atom;
    7661         6798 :           int i;
    7662              : 
    7663       274010 :           for (i = 0; i < n_switches; i++)
    7664       267212 :             if (!strncmp (switches[i].part1, atom, hard_match_len)
    7665       267212 :                 && check_live_switch (i, hard_match_len))
    7666              :               {
    7667         6802 :                 if (do_spec_1 (string, 0,
    7668              :                                &switches[i].part1[hard_match_len]) < 0)
    7669              :                   {
    7670            0 :                     free (string);
    7671            0 :                     return 0;
    7672              :                   }
    7673              :                 /* Pass any arguments this switch has.  */
    7674         6802 :                 give_switch (i, 1);
    7675         6802 :                 suffix_subst = NULL;
    7676              :               }
    7677              :         }
    7678     13995208 :       free (string);
    7679              :     }
    7680              : 
    7681              :   return p;
    7682              : 
    7683            0 :  invalid:
    7684            0 :   fatal_error (input_location, "braced spec body %qs is invalid", body);
    7685              : }
    7686              : 
    7687              : /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
    7688              :    on the command line.  PREFIX_LENGTH is the length of XXX in an {XXX*}
    7689              :    spec, or -1 if either exact match or %* is used.
    7690              : 
    7691              :    A -O switch is obsoleted by a later -O switch.  A -f, -g, -m, or -W switch
    7692              :    whose value does not begin with "no-" is obsoleted by the same value
    7693              :    with the "no-", similarly for a switch with the "no-" prefix.  */
    7694              : 
    7695              : static int
    7696      7653160 : check_live_switch (int switchnum, int prefix_length)
    7697              : {
    7698      7653160 :   const char *name = switches[switchnum].part1;
    7699      7653160 :   int i;
    7700              : 
    7701              :   /* If we already processed this switch and determined if it was
    7702              :      live or not, return our past determination.  */
    7703      7653160 :   if (switches[switchnum].live_cond != 0)
    7704       960346 :     return ((switches[switchnum].live_cond & SWITCH_LIVE) != 0
    7705       914375 :             && (switches[switchnum].live_cond & SWITCH_FALSE) == 0
    7706      1874721 :             && (switches[switchnum].live_cond & SWITCH_IGNORE_PERMANENTLY)
    7707       960346 :                == 0);
    7708              : 
    7709              :   /* In the common case of {<at-most-one-letter>*}, a negating
    7710              :      switch would always match, so ignore that case.  We will just
    7711              :      send the conflicting switches to the compiler phase.  */
    7712      6692814 :   if (prefix_length >= 0 && prefix_length <= 1)
    7713              :     return 1;
    7714              : 
    7715              :   /* Now search for duplicate in a manner that depends on the name.  */
    7716       909698 :   switch (*name)
    7717              :     {
    7718           64 :     case 'O':
    7719          360 :       for (i = switchnum + 1; i < n_switches; i++)
    7720          301 :         if (switches[i].part1[0] == 'O')
    7721              :           {
    7722            5 :             switches[switchnum].validated = true;
    7723            5 :             switches[switchnum].live_cond = SWITCH_FALSE;
    7724            5 :             return 0;
    7725              :           }
    7726              :       break;
    7727              : 
    7728       296514 :     case 'W':  case 'f':  case 'm': case 'g':
    7729       296514 :       if (startswith (name + 1, "no-"))
    7730              :         {
    7731              :           /* We have Xno-YYY, search for XYYY.  */
    7732        35626 :           for (i = switchnum + 1; i < n_switches; i++)
    7733        29955 :             if (switches[i].part1[0] == name[0]
    7734         5706 :                 && ! strcmp (&switches[i].part1[1], &name[4]))
    7735              :               {
    7736              :                 /* --specs are validated with the validate_switches mechanism.  */
    7737            0 :                 if (switches[switchnum].known)
    7738            0 :                   switches[switchnum].validated = true;
    7739            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7740            0 :                 return 0;
    7741              :               }
    7742              :         }
    7743              :       else
    7744              :         {
    7745              :           /* We have XYYY, search for Xno-YYY.  */
    7746      3089463 :           for (i = switchnum + 1; i < n_switches; i++)
    7747      2798620 :             if (switches[i].part1[0] == name[0]
    7748      1720427 :                 && switches[i].part1[1] == 'n'
    7749       218344 :                 && switches[i].part1[2] == 'o'
    7750       218343 :                 && switches[i].part1[3] == '-'
    7751       218313 :                 && !strcmp (&switches[i].part1[4], &name[1]))
    7752              :               {
    7753              :                 /* --specs are validated with the validate_switches mechanism.  */
    7754            0 :                 if (switches[switchnum].known)
    7755            0 :                   switches[switchnum].validated = true;
    7756            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7757            0 :                 return 0;
    7758              :               }
    7759              :         }
    7760              :       break;
    7761              :     }
    7762              : 
    7763              :   /* Otherwise the switch is live.  */
    7764       909693 :   switches[switchnum].live_cond |= SWITCH_LIVE;
    7765       909693 :   return 1;
    7766              : }
    7767              : 
    7768              : /* Pass a switch to the current accumulating command
    7769              :    in the same form that we received it.
    7770              :    SWITCHNUM identifies the switch; it is an index into
    7771              :    the vector of switches gcc received, which is `switches'.
    7772              :    This cannot fail since it never finishes a command line.
    7773              : 
    7774              :    If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.  */
    7775              : 
    7776              : static void
    7777      6213094 : give_switch (int switchnum, int omit_first_word)
    7778              : {
    7779      6213094 :   if ((switches[switchnum].live_cond & SWITCH_IGNORE) != 0)
    7780              :     return;
    7781              : 
    7782      6213083 :   if (!omit_first_word)
    7783              :     {
    7784      6206281 :       do_spec_1 ("-", 0, NULL);
    7785      6206281 :       do_spec_1 (switches[switchnum].part1, 1, NULL);
    7786              :     }
    7787              : 
    7788      6213083 :   if (switches[switchnum].args != 0)
    7789              :     {
    7790              :       const char **p;
    7791      2531166 :       for (p = switches[switchnum].args; *p; p++)
    7792              :         {
    7793      1265583 :           const char *arg = *p;
    7794              : 
    7795      1265583 :           do_spec_1 (" ", 0, NULL);
    7796      1265583 :           if (suffix_subst)
    7797              :             {
    7798         5935 :               unsigned length = strlen (arg);
    7799         5935 :               int dot = 0;
    7800              : 
    7801        11870 :               while (length-- && !IS_DIR_SEPARATOR (arg[length]))
    7802        11870 :                 if (arg[length] == '.')
    7803              :                   {
    7804         5935 :                     (const_cast<char *> (arg))[length] = 0;
    7805         5935 :                     dot = 1;
    7806         5935 :                     break;
    7807              :                   }
    7808         5935 :               do_spec_1 (arg, 1, NULL);
    7809         5935 :               if (dot)
    7810         5935 :                 (const_cast<char *> (arg))[length] = '.';
    7811         5935 :               do_spec_1 (suffix_subst, 1, NULL);
    7812              :             }
    7813              :           else
    7814      1259648 :             do_spec_1 (arg, 1, NULL);
    7815              :         }
    7816              :     }
    7817              : 
    7818      6213083 :   do_spec_1 (" ", 0, NULL);
    7819      6213083 :   switches[switchnum].validated = true;
    7820              : }
    7821              : 
    7822              : /* Print GCC configuration (e.g. version, thread model, target,
    7823              :    configuration_arguments) to a given FILE.  */
    7824              : 
    7825              : static void
    7826         1577 : print_configuration (FILE *file)
    7827              : {
    7828         1577 :   int n;
    7829         1577 :   const char *thrmod;
    7830              : 
    7831         1577 :   fnotice (file, "Target: %s\n", spec_machine);
    7832         1577 :   fnotice (file, "Configured with: %s\n", configuration_arguments);
    7833              : 
    7834              : #ifdef THREAD_MODEL_SPEC
    7835              :   /* We could have defined THREAD_MODEL_SPEC to "%*" by default,
    7836              :   but there's no point in doing all this processing just to get
    7837              :   thread_model back.  */
    7838              :   obstack_init (&obstack);
    7839              :   do_spec_1 (THREAD_MODEL_SPEC, 0, thread_model);
    7840              :   obstack_1grow (&obstack, '\0');
    7841              :   thrmod = XOBFINISH (&obstack, const char *);
    7842              : #else
    7843         1577 :   thrmod = thread_model;
    7844              : #endif
    7845              : 
    7846         1577 :   fnotice (file, "Thread model: %s\n", thrmod);
    7847         1577 :   fnotice (file, "Supported LTO compression algorithms: zlib");
    7848              : #ifdef HAVE_ZSTD_H
    7849         1577 :   fnotice (file, " zstd");
    7850              : #endif
    7851         1577 :   fnotice (file, "\n");
    7852              : 
    7853              :   /* compiler_version is truncated at the first space when initialized
    7854              :   from version string, so truncate version_string at the first space
    7855              :   before comparing.  */
    7856        12616 :   for (n = 0; version_string[n]; n++)
    7857        11039 :     if (version_string[n] == ' ')
    7858              :       break;
    7859              : 
    7860         1577 :   if (! strncmp (version_string, compiler_version, n)
    7861         1577 :       && compiler_version[n] == 0)
    7862         1577 :     fnotice (file, "gcc version %s %s\n", version_string,
    7863              :              pkgversion_string);
    7864              :   else
    7865            0 :     fnotice (file, "gcc driver version %s %sexecuting gcc version %s\n",
    7866              :              version_string, pkgversion_string, compiler_version);
    7867              : 
    7868         1577 : }
    7869              : 
    7870              : #define RETRY_ICE_ATTEMPTS 3
    7871              : 
    7872              : /* Returns true if FILE1 and FILE2 contain equivalent data, 0 otherwise.
    7873              :    If lines start with 0x followed by 1-16 lowercase hexadecimal digits
    7874              :    followed by a space, ignore anything before that space.  These are
    7875              :    typically function addresses from libbacktrace and those can differ
    7876              :    due to ASLR.  */
    7877              : 
    7878              : static bool
    7879            0 : files_equal_p (char *file1, char *file2)
    7880              : {
    7881            0 :   FILE *f1 = fopen (file1, "rb");
    7882            0 :   FILE *f2 = fopen (file2, "rb");
    7883            0 :   char line1[256], line2[256];
    7884              : 
    7885            0 :   bool line_start = true;
    7886            0 :   while (fgets (line1, sizeof (line1), f1))
    7887              :     {
    7888            0 :       if (!fgets (line2, sizeof (line2), f2))
    7889            0 :         goto error;
    7890            0 :       char *p1 = line1, *p2 = line2;
    7891            0 :       if (line_start
    7892            0 :           && line1[0] == '0'
    7893            0 :           && line1[1] == 'x'
    7894            0 :           && line2[0] == '0'
    7895            0 :           && line2[1] == 'x')
    7896              :         {
    7897              :           int i, j;
    7898            0 :           for (i = 0; i < 16; ++i)
    7899            0 :             if (!ISXDIGIT (line1[2 + i]) || ISUPPER (line1[2 + i]))
    7900              :               break;
    7901            0 :           for (j = 0; j < 16; ++j)
    7902            0 :             if (!ISXDIGIT (line2[2 + j]) || ISUPPER (line2[2 + j]))
    7903              :               break;
    7904            0 :           if (i && line1[2 + i] == ' ' && j && line2[2 + j] == ' ')
    7905              :             {
    7906            0 :               p1 = line1 + i + 3;
    7907            0 :               p2 = line2 + j + 3;
    7908              :             }
    7909              :         }
    7910            0 :       if (strcmp (p1, p2) != 0)
    7911            0 :         goto error;
    7912            0 :       line_start = strchr (line1, '\n') != NULL;
    7913              :     }
    7914            0 :   if (fgets (line2, sizeof (line2), f2))
    7915            0 :     goto error;
    7916              : 
    7917            0 :   fclose (f1);
    7918            0 :   fclose (f2);
    7919            0 :   return 1;
    7920              : 
    7921            0 : error:
    7922            0 :   fclose (f1);
    7923            0 :   fclose (f2);
    7924            0 :   return 0;
    7925              : }
    7926              : 
    7927              : /* Check that compiler's output doesn't differ across runs.
    7928              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are arrays of files, containing
    7929              :    stdout and stderr for each compiler run.  Return true if all of
    7930              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are equivalent.  */
    7931              : 
    7932              : static bool
    7933            0 : check_repro (char **temp_stdout_files, char **temp_stderr_files)
    7934              : {
    7935            0 :   int i;
    7936            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS - 2; ++i)
    7937              :     {
    7938            0 :      if (!files_equal_p (temp_stdout_files[i], temp_stdout_files[i + 1])
    7939            0 :          || !files_equal_p (temp_stderr_files[i], temp_stderr_files[i + 1]))
    7940              :        {
    7941            0 :          fnotice (stderr, "The bug is not reproducible, so it is"
    7942              :                   " likely a hardware or OS problem.\n");
    7943            0 :          break;
    7944              :        }
    7945              :     }
    7946            0 :   return i == RETRY_ICE_ATTEMPTS - 2;
    7947              : }
    7948              : 
    7949              : enum attempt_status {
    7950              :   ATTEMPT_STATUS_FAIL_TO_RUN,
    7951              :   ATTEMPT_STATUS_SUCCESS,
    7952              :   ATTEMPT_STATUS_ICE
    7953              : };
    7954              : 
    7955              : 
    7956              : /* Run compiler with arguments NEW_ARGV to reproduce the ICE, storing stdout
    7957              :    to OUT_TEMP and stderr to ERR_TEMP.  If APPEND is TRUE, append to OUT_TEMP
    7958              :    and ERR_TEMP instead of truncating.  If EMIT_SYSTEM_INFO is TRUE, also write
    7959              :    GCC configuration into to ERR_TEMP.  Return ATTEMPT_STATUS_FAIL_TO_RUN if
    7960              :    compiler failed to run, ATTEMPT_STATUS_ICE if compiled ICE-ed and
    7961              :    ATTEMPT_STATUS_SUCCESS otherwise.  */
    7962              : 
    7963              : static enum attempt_status
    7964            0 : run_attempt (const char **new_argv, const char *out_temp,
    7965              :              const char *err_temp, int emit_system_info, int append)
    7966              : {
    7967              : 
    7968            0 :   if (emit_system_info)
    7969              :     {
    7970            0 :       FILE *file_out = fopen (err_temp, "a");
    7971            0 :       print_configuration (file_out);
    7972            0 :       fputs ("\n", file_out);
    7973            0 :       fclose (file_out);
    7974              :     }
    7975              : 
    7976            0 :   int exit_status;
    7977            0 :   const char *errmsg;
    7978            0 :   struct pex_obj *pex;
    7979            0 :   int err;
    7980            0 :   int pex_flags = PEX_USE_PIPES | PEX_LAST;
    7981            0 :   enum attempt_status status = ATTEMPT_STATUS_FAIL_TO_RUN;
    7982              : 
    7983            0 :   if (append)
    7984            0 :     pex_flags |= PEX_STDOUT_APPEND | PEX_STDERR_APPEND;
    7985              : 
    7986            0 :   pex = pex_init (PEX_USE_PIPES, new_argv[0], NULL);
    7987            0 :   if (!pex)
    7988              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    7989              : 
    7990            0 :   errmsg = pex_run (pex, pex_flags, new_argv[0],
    7991            0 :                     const_cast<char *const *> (&new_argv[1]),
    7992              :                     out_temp, err_temp, &err);
    7993            0 :   if (errmsg != NULL)
    7994              :     {
    7995            0 :       errno = err;
    7996            0 :       fatal_error (input_location,
    7997              :                    err ? G_ ("cannot execute %qs: %s: %m")
    7998              :                    : G_ ("cannot execute %qs: %s"),
    7999              :                    new_argv[0], errmsg);
    8000              :     }
    8001              : 
    8002            0 :   if (!pex_get_status (pex, 1, &exit_status))
    8003            0 :     goto out;
    8004              : 
    8005            0 :   switch (WEXITSTATUS (exit_status))
    8006              :     {
    8007              :       case ICE_EXIT_CODE:
    8008            0 :         status = ATTEMPT_STATUS_ICE;
    8009              :         break;
    8010              : 
    8011            0 :       case SUCCESS_EXIT_CODE:
    8012            0 :         status = ATTEMPT_STATUS_SUCCESS;
    8013            0 :         break;
    8014              : 
    8015            0 :       default:
    8016            0 :         ;
    8017              :     }
    8018              : 
    8019            0 : out:
    8020            0 :   pex_free (pex);
    8021            0 :   return status;
    8022              : }
    8023              : 
    8024              : /* This routine reads lines from IN file, adds C++ style comments
    8025              :    at the beginning of each line and writes result into OUT.  */
    8026              : 
    8027              : static void
    8028            0 : insert_comments (const char *file_in, const char *file_out)
    8029              : {
    8030            0 :   FILE *in = fopen (file_in, "rb");
    8031            0 :   FILE *out = fopen (file_out, "wb");
    8032            0 :   char line[256];
    8033              : 
    8034            0 :   bool add_comment = true;
    8035            0 :   while (fgets (line, sizeof (line), in))
    8036              :     {
    8037            0 :       if (add_comment)
    8038            0 :         fputs ("// ", out);
    8039            0 :       fputs (line, out);
    8040            0 :       add_comment = strchr (line, '\n') != NULL;
    8041              :     }
    8042              : 
    8043            0 :   fclose (in);
    8044            0 :   fclose (out);
    8045            0 : }
    8046              : 
    8047              : /* This routine adds preprocessed source code into the given ERR_FILE.
    8048              :    To do this, it adds "-E" to NEW_ARGV and execute RUN_ATTEMPT routine to
    8049              :    add information in report file.  RUN_ATTEMPT should return
    8050              :    ATTEMPT_STATUS_SUCCESS, in other case we cannot generate the report.  */
    8051              : 
    8052              : static void
    8053            0 : do_report_bug (const char **new_argv, const int nargs,
    8054              :                char **out_file, char **err_file)
    8055              : {
    8056            0 :   int i, status;
    8057            0 :   int fd = open (*out_file, O_RDWR | O_APPEND);
    8058            0 :   if (fd < 0)
    8059              :     return;
    8060            0 :   write (fd, "\n//", 3);
    8061            0 :   for (i = 0; i < nargs; i++)
    8062              :     {
    8063            0 :       write (fd, " ", 1);
    8064            0 :       write (fd, new_argv[i], strlen (new_argv[i]));
    8065              :     }
    8066            0 :   write (fd, "\n\n", 2);
    8067            0 :   close (fd);
    8068            0 :   new_argv[nargs] = "-E";
    8069            0 :   new_argv[nargs + 1] = NULL;
    8070              : 
    8071            0 :   status = run_attempt (new_argv, *out_file, *err_file, 0, 1);
    8072              : 
    8073            0 :   if (status == ATTEMPT_STATUS_SUCCESS)
    8074              :     {
    8075            0 :       fnotice (stderr, "Preprocessed source stored into %s file,"
    8076              :                " please attach this to your bugreport.\n", *out_file);
    8077              :       /* Make sure it is not deleted.  */
    8078            0 :       free (*out_file);
    8079            0 :       *out_file = NULL;
    8080              :     }
    8081              : }
    8082              : 
    8083              : /* Try to reproduce ICE.  If bug is reproducible, generate report .err file
    8084              :    containing GCC configuration, backtrace, compiler's command line options
    8085              :    and preprocessed source code.  */
    8086              : 
    8087              : static void
    8088            0 : try_generate_repro (const char **argv)
    8089              : {
    8090            0 :   int i, nargs, out_arg = -1, quiet = 0, attempt;
    8091            0 :   const char **new_argv;
    8092            0 :   char *temp_files[RETRY_ICE_ATTEMPTS * 2];
    8093            0 :   char **temp_stdout_files = &temp_files[0];
    8094            0 :   char **temp_stderr_files = &temp_files[RETRY_ICE_ATTEMPTS];
    8095              : 
    8096            0 :   if (gcc_input_filename == NULL || ! strcmp (gcc_input_filename, "-"))
    8097            0 :     return;
    8098              : 
    8099            0 :   for (nargs = 0; argv[nargs] != NULL; ++nargs)
    8100              :     /* Only retry compiler ICEs, not preprocessor ones.  */
    8101            0 :     if (! strcmp (argv[nargs], "-E"))
    8102              :       return;
    8103            0 :     else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o')
    8104              :       {
    8105            0 :         if (out_arg == -1)
    8106              :           out_arg = nargs;
    8107              :         else
    8108              :           return;
    8109              :       }
    8110              :     /* If the compiler is going to output any time information,
    8111              :        it might varry between invocations.  */
    8112            0 :     else if (! strcmp (argv[nargs], "-quiet"))
    8113              :       quiet = 1;
    8114            0 :     else if (! strcmp (argv[nargs], "-ftime-report"))
    8115              :       return;
    8116              : 
    8117            0 :   if (out_arg == -1 || !quiet)
    8118              :     return;
    8119              : 
    8120            0 :   memset (temp_files, '\0', sizeof (temp_files));
    8121            0 :   new_argv = XALLOCAVEC (const char *, nargs + 4);
    8122            0 :   memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *));
    8123            0 :   new_argv[nargs++] = "-frandom-seed=0";
    8124            0 :   new_argv[nargs++] = "-fdump-noaddr";
    8125            0 :   new_argv[nargs] = NULL;
    8126            0 :   if (new_argv[out_arg][2] == '\0')
    8127            0 :     new_argv[out_arg + 1] = "-";
    8128              :   else
    8129            0 :     new_argv[out_arg] = "-o-";
    8130              : 
    8131              : #ifdef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
    8132            0 :   personality (personality (0xffffffffU) | ADDR_NO_RANDOMIZE);
    8133              : #endif
    8134              : 
    8135            0 :   int status;
    8136            0 :   for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS; ++attempt)
    8137              :     {
    8138            0 :       int emit_system_info = 0;
    8139            0 :       int append = 0;
    8140            0 :       temp_stdout_files[attempt] = make_temp_file (".out");
    8141            0 :       temp_stderr_files[attempt] = make_temp_file (".err");
    8142              : 
    8143            0 :       if (attempt == RETRY_ICE_ATTEMPTS - 1)
    8144              :         {
    8145            0 :           append = 1;
    8146            0 :           emit_system_info = 1;
    8147              :         }
    8148              : 
    8149            0 :       status = run_attempt (new_argv, temp_stdout_files[attempt],
    8150              :                             temp_stderr_files[attempt], emit_system_info,
    8151              :                             append);
    8152              : 
    8153            0 :       if (status != ATTEMPT_STATUS_ICE)
    8154              :         {
    8155            0 :           fnotice (stderr, "The bug is not reproducible, so it is"
    8156              :                    " likely a hardware or OS problem.\n");
    8157            0 :           goto out;
    8158              :         }
    8159              :     }
    8160              : 
    8161            0 :   if (!check_repro (temp_stdout_files, temp_stderr_files))
    8162            0 :     goto out;
    8163              : 
    8164            0 :   {
    8165              :     /* Insert commented out backtrace into report file.  */
    8166            0 :     char **stderr_commented = &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1];
    8167            0 :     insert_comments (temp_stderr_files[RETRY_ICE_ATTEMPTS - 1],
    8168              :                      *stderr_commented);
    8169              : 
    8170              :     /* In final attempt we append compiler options and preprocesssed code to last
    8171              :        generated .out file with configuration and backtrace.  */
    8172            0 :     char **err = &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1];
    8173            0 :     do_report_bug (new_argv, nargs, stderr_commented, err);
    8174              :   }
    8175              : 
    8176              : out:
    8177            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS * 2; i++)
    8178            0 :     if (temp_files[i])
    8179              :       {
    8180            0 :         unlink (temp_stdout_files[i]);
    8181            0 :         free (temp_stdout_files[i]);
    8182              :       }
    8183              : }
    8184              : 
    8185              : /* Search for a file named NAME trying various prefixes including the
    8186              :    user's -B prefix and some standard ones.
    8187              :    Return the absolute file name found.  If nothing is found, return NAME.  */
    8188              : 
    8189              : static const char *
    8190       549823 : find_file (const char *name)
    8191              : {
    8192       549823 :   char *newname = find_a_file (&startfile_prefixes, name, true);
    8193       549823 :   return newname ? newname : name;
    8194              : }
    8195              : 
    8196              : /* Determine whether a directory exists.  */
    8197              : 
    8198              : static int
    8199     10501068 : is_directory (const char *path1)
    8200              : {
    8201     10501068 :   int len1;
    8202     10501068 :   char *path;
    8203     10501068 :   char *cp;
    8204     10501068 :   struct stat st;
    8205              : 
    8206              :   /* Ensure the string ends with "/.".  The resulting path will be a
    8207              :      directory even if the given path is a symbolic link.  */
    8208     10501068 :   len1 = strlen (path1);
    8209     10501068 :   path = (char *) alloca (3 + len1);
    8210     10501068 :   memcpy (path, path1, len1);
    8211     10501068 :   cp = path + len1;
    8212     10501068 :   if (!IS_DIR_SEPARATOR (cp[-1]))
    8213      1525418 :     *cp++ = DIR_SEPARATOR;
    8214     10501068 :   *cp++ = '.';
    8215     10501068 :   *cp = '\0';
    8216              : 
    8217     10501068 :   return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
    8218              : }
    8219              : 
    8220              : /* Set up the various global variables to indicate that we're processing
    8221              :    the input file named FILENAME.  */
    8222              : 
    8223              : void
    8224       847632 : set_input (const char *filename)
    8225              : {
    8226       847632 :   const char *p;
    8227              : 
    8228       847632 :   gcc_input_filename = filename;
    8229       847632 :   input_filename_length = strlen (gcc_input_filename);
    8230       847632 :   input_basename = lbasename (gcc_input_filename);
    8231              : 
    8232              :   /* Find a suffix starting with the last period,
    8233              :      and set basename_length to exclude that suffix.  */
    8234       847632 :   basename_length = strlen (input_basename);
    8235       847632 :   suffixed_basename_length = basename_length;
    8236       847632 :   p = input_basename + basename_length;
    8237      3735767 :   while (p != input_basename && *p != '.')
    8238      2888135 :     --p;
    8239       847632 :   if (*p == '.' && p != input_basename)
    8240              :     {
    8241       606306 :       basename_length = p - input_basename;
    8242       606306 :       input_suffix = p + 1;
    8243              :     }
    8244              :   else
    8245       241326 :     input_suffix = "";
    8246              : 
    8247              :   /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then
    8248              :      we will need to do a stat on the gcc_input_filename.  The
    8249              :      INPUT_STAT_SET signals that the stat is needed.  */
    8250       847632 :   input_stat_set = 0;
    8251       847632 : }
    8252              : 
    8253              : /* On fatal signals, delete all the temporary files.  */
    8254              : 
    8255              : static void
    8256            0 : fatal_signal (int signum)
    8257              : {
    8258            0 :   signal (signum, SIG_DFL);
    8259            0 :   delete_failure_queue ();
    8260            0 :   delete_temp_files ();
    8261              :   /* Get the same signal again, this time not handled,
    8262              :      so its normal effect occurs.  */
    8263            0 :   kill (getpid (), signum);
    8264            0 : }
    8265              : 
    8266              : /* Compare the contents of the two files named CMPFILE[0] and
    8267              :    CMPFILE[1].  Return zero if they're identical, nonzero
    8268              :    otherwise.  */
    8269              : 
    8270              : static int
    8271          629 : compare_files (char *cmpfile[])
    8272              : {
    8273          629 :   int ret = 0;
    8274          629 :   FILE *temp[2] = { NULL, NULL };
    8275          629 :   int i;
    8276              : 
    8277              : #if HAVE_MMAP_FILE
    8278          629 :   {
    8279          629 :     size_t length[2];
    8280          629 :     void *map[2] = { NULL, NULL };
    8281              : 
    8282         1887 :     for (i = 0; i < 2; i++)
    8283              :       {
    8284         1258 :         struct stat st;
    8285              : 
    8286         1258 :         if (stat (cmpfile[i], &st) < 0 || !S_ISREG (st.st_mode))
    8287              :           {
    8288            0 :             error ("%s: could not determine length of compare-debug file %s",
    8289              :                    gcc_input_filename, cmpfile[i]);
    8290            0 :             ret = 1;
    8291            0 :             break;
    8292              :           }
    8293              : 
    8294         1258 :         length[i] = st.st_size;
    8295              :       }
    8296              : 
    8297          629 :     if (!ret && length[0] != length[1])
    8298              :       {
    8299           14 :         error ("%s: %<-fcompare-debug%> failure (length)", gcc_input_filename);
    8300           14 :         ret = 1;
    8301              :       }
    8302              : 
    8303           14 :     if (!ret)
    8304         1779 :       for (i = 0; i < 2; i++)
    8305              :         {
    8306         1197 :           int fd = open (cmpfile[i], O_RDONLY);
    8307         1197 :           if (fd < 0)
    8308              :             {
    8309            0 :               error ("%s: could not open compare-debug file %s",
    8310              :                      gcc_input_filename, cmpfile[i]);
    8311            0 :               ret = 1;
    8312            0 :               break;
    8313              :             }
    8314              : 
    8315         1197 :           map[i] = mmap (NULL, length[i], PROT_READ, MAP_PRIVATE, fd, 0);
    8316         1197 :           close (fd);
    8317              : 
    8318         1197 :           if (map[i] == (void *) MAP_FAILED)
    8319              :             {
    8320              :               ret = -1;
    8321              :               break;
    8322              :             }
    8323              :         }
    8324              : 
    8325          615 :     if (!ret)
    8326              :       {
    8327          582 :         if (memcmp (map[0], map[1], length[0]) != 0)
    8328              :           {
    8329            0 :             error ("%s: %<-fcompare-debug%> failure", gcc_input_filename);
    8330            0 :             ret = 1;
    8331              :           }
    8332              :       }
    8333              : 
    8334         1887 :     for (i = 0; i < 2; i++)
    8335         1258 :       if (map[i])
    8336         1197 :         munmap ((caddr_t) map[i], length[i]);
    8337              : 
    8338          629 :     if (ret >= 0)
    8339          596 :       return ret;
    8340              : 
    8341           33 :     ret = 0;
    8342              :   }
    8343              : #endif
    8344              : 
    8345           99 :   for (i = 0; i < 2; i++)
    8346              :     {
    8347           66 :       temp[i] = fopen (cmpfile[i], "r");
    8348           66 :       if (!temp[i])
    8349              :         {
    8350            0 :           error ("%s: could not open compare-debug file %s",
    8351              :                  gcc_input_filename, cmpfile[i]);
    8352            0 :           ret = 1;
    8353            0 :           break;
    8354              :         }
    8355              :     }
    8356              : 
    8357           33 :   if (!ret && temp[0] && temp[1])
    8358           33 :     for (;;)
    8359              :       {
    8360           33 :         int c0, c1;
    8361           33 :         c0 = fgetc (temp[0]);
    8362           33 :         c1 = fgetc (temp[1]);
    8363              : 
    8364           33 :         if (c0 != c1)
    8365              :           {
    8366            0 :             error ("%s: %<-fcompare-debug%> failure",
    8367              :                    gcc_input_filename);
    8368            0 :             ret = 1;
    8369            0 :             break;
    8370              :           }
    8371              : 
    8372           33 :         if (c0 == EOF)
    8373              :           break;
    8374              :       }
    8375              : 
    8376           99 :   for (i = 1; i >= 0; i--)
    8377              :     {
    8378           66 :       if (temp[i])
    8379           66 :         fclose (temp[i]);
    8380              :     }
    8381              : 
    8382              :   return ret;
    8383              : }
    8384              : 
    8385       304123 : driver::driver (bool can_finalize, bool debug) :
    8386       304123 :   explicit_link_files (NULL),
    8387       304123 :   decoded_options (NULL)
    8388              : {
    8389       304123 :   env.init (can_finalize, debug);
    8390       304123 : }
    8391              : 
    8392       303641 : driver::~driver ()
    8393              : {
    8394       303641 :   XDELETEVEC (explicit_link_files);
    8395       303641 :   XDELETEVEC (decoded_options);
    8396       303641 : }
    8397              : 
    8398              : /* driver::main is implemented as a series of driver:: method calls.  */
    8399              : 
    8400              : int
    8401       304123 : driver::main (int argc, char **argv)
    8402              : {
    8403       304123 :   bool early_exit;
    8404              : 
    8405       304123 :   set_progname (argv[0]);
    8406       304123 :   expand_at_files (&argc, &argv);
    8407       304123 :   decode_argv (argc, const_cast <const char **> (argv));
    8408       304123 :   global_initializations ();
    8409       304123 :   build_multilib_strings ();
    8410       304123 :   set_up_specs ();
    8411       303836 :   putenv_COLLECT_AS_OPTIONS (assembler_options);
    8412       303836 :   putenv_COLLECT_GCC (argv[0]);
    8413       303836 :   maybe_putenv_COLLECT_LTO_WRAPPER ();
    8414       303836 :   maybe_putenv_OFFLOAD_TARGETS ();
    8415       303836 :   handle_unrecognized_options ();
    8416              : 
    8417       303836 :   if (completion)
    8418              :     {
    8419            5 :       m_option_proposer.suggest_completion (completion);
    8420            5 :       return 0;
    8421              :     }
    8422              : 
    8423       303831 :   if (!maybe_print_and_exit ())
    8424              :     return 0;
    8425              : 
    8426       288237 :   early_exit = prepare_infiles ();
    8427       288043 :   if (early_exit)
    8428          423 :     return get_exit_code ();
    8429              : 
    8430       287620 :   do_spec_on_infiles ();
    8431       287620 :   maybe_run_linker (argv[0]);
    8432       287620 :   final_actions ();
    8433       287620 :   return get_exit_code ();
    8434              : }
    8435              : 
    8436              : /* Locate the final component of argv[0] after any leading path, and set
    8437              :    the program name accordingly.  */
    8438              : 
    8439              : void
    8440       304123 : driver::set_progname (const char *argv0) const
    8441              : {
    8442       304123 :   const char *p = argv0 + strlen (argv0);
    8443      1674540 :   while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
    8444      1370417 :     --p;
    8445       304123 :   progname = p;
    8446              : 
    8447       304123 :   xmalloc_set_program_name (progname);
    8448       304123 : }
    8449              : 
    8450              : /* Expand any @ files within the command-line args,
    8451              :    setting at_file_supplied if any were expanded.  */
    8452              : 
    8453              : void
    8454       304123 : driver::expand_at_files (int *argc, char ***argv) const
    8455              : {
    8456       304123 :   char **old_argv = *argv;
    8457              : 
    8458       304123 :   expandargv (argc, argv);
    8459              : 
    8460              :   /* Determine if any expansions were made.  */
    8461       304123 :   if (*argv != old_argv)
    8462        12345 :     at_file_supplied = true;
    8463       304123 : }
    8464              : 
    8465              : /* Decode the command-line arguments from argc/argv into the
    8466              :    decoded_options array.  */
    8467              : 
    8468              : void
    8469       304123 : driver::decode_argv (int argc, const char **argv)
    8470              : {
    8471       304123 :   init_opts_obstack ();
    8472       304123 :   init_options_struct (&global_options, &global_options_set);
    8473              : 
    8474       304123 :   decode_cmdline_options_to_array (argc, argv,
    8475              :                                    CL_DRIVER,
    8476              :                                    &decoded_options, &decoded_options_count);
    8477       304123 : }
    8478              : 
    8479              : /* Perform various initializations and setup.  */
    8480              : 
    8481              : void
    8482       304123 : driver::global_initializations ()
    8483              : {
    8484              :   /* Unlock the stdio streams.  */
    8485       304123 :   unlock_std_streams ();
    8486              : 
    8487       304123 :   gcc_init_libintl ();
    8488              : 
    8489       304123 :   diagnostic_initialize (global_dc, 0);
    8490       304123 :   diagnostic_color_init (global_dc);
    8491       304123 :   diagnostic_urls_init (global_dc);
    8492       304123 :   global_dc->push_owned_urlifier (make_gcc_urlifier (0));
    8493              : 
    8494              : #ifdef GCC_DRIVER_HOST_INITIALIZATION
    8495              :   /* Perform host dependent initialization when needed.  */
    8496              :   GCC_DRIVER_HOST_INITIALIZATION;
    8497              : #endif
    8498              : 
    8499       304123 :   if (atexit (delete_temp_files) != 0)
    8500            0 :     fatal_error (input_location, "atexit failed");
    8501              : 
    8502       304123 :   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
    8503       303972 :     signal (SIGINT, fatal_signal);
    8504              : #ifdef SIGHUP
    8505       304123 :   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
    8506        21391 :     signal (SIGHUP, fatal_signal);
    8507              : #endif
    8508       304123 :   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
    8509       304123 :     signal (SIGTERM, fatal_signal);
    8510              : #ifdef SIGPIPE
    8511       304123 :   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
    8512       304123 :     signal (SIGPIPE, fatal_signal);
    8513              : #endif
    8514              : #ifdef SIGCHLD
    8515              :   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
    8516              :      receive the signal.  A different setting is inheritable */
    8517       304123 :   signal (SIGCHLD, SIG_DFL);
    8518              : #endif
    8519              : 
    8520              :   /* Parsing and gimplification sometimes need quite large stack.
    8521              :      Increase stack size limits if possible.  */
    8522              : #ifdef __SANITIZE_ADDRESS__
    8523              :   stack_limit_increase (128 * 1024 * 1024);
    8524              : #else
    8525       304123 :   stack_limit_increase (64 * 1024 * 1024);
    8526              : #endif
    8527              : 
    8528              :   /* Allocate the argument vector.  */
    8529       304123 :   alloc_args ();
    8530              : 
    8531       304123 :   obstack_init (&obstack);
    8532       304123 : }
    8533              : 
    8534              : /* Build multilib_select, et. al from the separate lines that make up each
    8535              :    multilib selection.  */
    8536              : 
    8537              : void
    8538       304123 : driver::build_multilib_strings () const
    8539              : {
    8540       304123 :   {
    8541       304123 :     const char *p;
    8542       304123 :     const char *const *q = multilib_raw;
    8543       304123 :     int need_space;
    8544              : 
    8545       304123 :     obstack_init (&multilib_obstack);
    8546       304123 :     while ((p = *q++) != (char *) 0)
    8547      1216492 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8548              : 
    8549       304123 :     obstack_1grow (&multilib_obstack, 0);
    8550       304123 :     multilib_select = XOBFINISH (&multilib_obstack, const char *);
    8551              : 
    8552       304123 :     q = multilib_matches_raw;
    8553       304123 :     while ((p = *q++) != (char *) 0)
    8554       912369 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8555              : 
    8556       304123 :     obstack_1grow (&multilib_obstack, 0);
    8557       304123 :     multilib_matches = XOBFINISH (&multilib_obstack, const char *);
    8558              : 
    8559       304123 :     q = multilib_exclusions_raw;
    8560       304123 :     while ((p = *q++) != (char *) 0)
    8561       304123 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8562              : 
    8563       304123 :     obstack_1grow (&multilib_obstack, 0);
    8564       304123 :     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
    8565              : 
    8566       304123 :     q = multilib_reuse_raw;
    8567       304123 :     while ((p = *q++) != (char *) 0)
    8568       304123 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8569              : 
    8570       304123 :     obstack_1grow (&multilib_obstack, 0);
    8571       304123 :     multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
    8572              : 
    8573       304123 :     need_space = false;
    8574       608246 :     for (size_t i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
    8575              :       {
    8576       304123 :         if (need_space)
    8577            0 :           obstack_1grow (&multilib_obstack, ' ');
    8578       304123 :         obstack_grow (&multilib_obstack,
    8579              :                       multilib_defaults_raw[i],
    8580              :                       strlen (multilib_defaults_raw[i]));
    8581       304123 :         need_space = true;
    8582              :       }
    8583              : 
    8584       304123 :     obstack_1grow (&multilib_obstack, 0);
    8585       304123 :     multilib_defaults = XOBFINISH (&multilib_obstack, const char *);
    8586              :   }
    8587       304123 : }
    8588              : 
    8589              : /* Set up the spec-handling machinery.  */
    8590              : 
    8591              : void
    8592       304123 : driver::set_up_specs () const
    8593              : {
    8594       304123 :   const char *spec_machine_suffix;
    8595       304123 :   char *specs_file;
    8596       304123 :   size_t i;
    8597              : 
    8598              : #ifdef INIT_ENVIRONMENT
    8599              :   /* Set up any other necessary machine specific environment variables.  */
    8600              :   xputenv (INIT_ENVIRONMENT);
    8601              : #endif
    8602              : 
    8603              :   /* Make a table of what switches there are (switches, n_switches).
    8604              :      Make a table of specified input files (infiles, n_infiles).
    8605              :      Decode switches that are handled locally.  */
    8606              : 
    8607       304123 :   process_command (decoded_options_count, decoded_options);
    8608              : 
    8609              :   /* Initialize the vector of specs to just the default.
    8610              :      This means one element containing 0s, as a terminator.  */
    8611              : 
    8612       303837 :   compilers = XNEWVAR (struct compiler, sizeof default_compilers);
    8613       303837 :   memcpy (compilers, default_compilers, sizeof default_compilers);
    8614       303837 :   n_compilers = n_default_compilers;
    8615              : 
    8616              :   /* Read specs from a file if there is one.  */
    8617              : 
    8618       303837 :   machine_suffix = concat (spec_host_machine, dir_separator_str, spec_version,
    8619              :                            accel_dir_suffix, dir_separator_str, NULL);
    8620       303837 :   just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
    8621       303837 :   just_machine_prefix = concat (spec_machine, "-", NULL);
    8622              : 
    8623       303837 :   specs_file = find_a_file (&startfile_prefixes, "specs", true);
    8624              :   /* Read the specs file unless it is a default one.  */
    8625       303837 :   if (specs_file != 0 && strcmp (specs_file, "specs"))
    8626       302736 :     read_specs (specs_file, true, false);
    8627              :   else
    8628         1101 :     init_spec ();
    8629              : 
    8630              : #ifdef ACCEL_COMPILER
    8631              :   spec_machine_suffix = machine_suffix;
    8632              : #else
    8633       303837 :   spec_machine_suffix = just_machine_suffix;
    8634              : #endif
    8635              : 
    8636       303837 :   const char *exec_prefix
    8637       303837 :     = gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix;
    8638              :   /* We need to check standard_exec_prefix/spec_machine_suffix/specs
    8639              :      for any override of as, ld and libraries.  */
    8640       303837 :   specs_file = (char *) alloca (
    8641              :     strlen (exec_prefix) + strlen (spec_machine_suffix) + sizeof ("specs"));
    8642       303837 :   strcpy (specs_file, exec_prefix);
    8643       303837 :   strcat (specs_file, spec_machine_suffix);
    8644       303837 :   strcat (specs_file, "specs");
    8645       303837 :   if (access (specs_file, R_OK) == 0)
    8646            0 :     read_specs (specs_file, true, false);
    8647              : 
    8648              :   /* Process any configure-time defaults specified for the command line
    8649              :      options, via OPTION_DEFAULT_SPECS.  */
    8650      3342207 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
    8651      3038370 :     do_option_spec (option_default_specs[i].name,
    8652      3038370 :                     option_default_specs[i].spec);
    8653              : 
    8654              :   /* Process DRIVER_SELF_SPECS, adding any new options to the end
    8655              :      of the command line.  */
    8656              : 
    8657      2126859 :   for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
    8658      1823022 :     do_self_spec (driver_self_specs[i]);
    8659              : 
    8660              :   /* If not cross-compiling, look for executables in the standard
    8661              :      places.  */
    8662       303837 :   if (*cross_compile == '0')
    8663              :     {
    8664       303837 :       if (*md_exec_prefix)
    8665              :         {
    8666            0 :           add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
    8667              :                       PREFIX_PRIORITY_LAST, 0, 0);
    8668              :         }
    8669              :     }
    8670              : 
    8671              :   /* Process sysroot_suffix_spec.  */
    8672       303837 :   if (*sysroot_suffix_spec != 0
    8673            0 :       && !no_sysroot_suffix
    8674       303837 :       && do_spec_2 (sysroot_suffix_spec, NULL) == 0)
    8675              :     {
    8676            0 :       if (argbuf.length () > 1)
    8677            0 :         error ("spec failure: more than one argument to "
    8678              :                "%<SYSROOT_SUFFIX_SPEC%>");
    8679            0 :       else if (argbuf.length () == 1)
    8680            0 :         target_sysroot_suffix = xstrdup (argbuf.last ());
    8681              :     }
    8682              : 
    8683              : #ifdef HAVE_LD_SYSROOT
    8684              :   /* Pass the --sysroot option to the linker, if it supports that.  If
    8685              :      there is a sysroot_suffix_spec, it has already been processed by
    8686              :      this point, so target_system_root really is the system root we
    8687              :      should be using.  */
    8688       303837 :   if (target_system_root)
    8689              :     {
    8690            0 :       obstack_grow (&obstack, "%(sysroot_spec) ", strlen ("%(sysroot_spec) "));
    8691            0 :       obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    8692            0 :       set_spec ("link", XOBFINISH (&obstack, const char *), false);
    8693              :     }
    8694              : #endif
    8695              : 
    8696              :   /* Process sysroot_hdrs_suffix_spec.  */
    8697       303837 :   if (*sysroot_hdrs_suffix_spec != 0
    8698            0 :       && !no_sysroot_suffix
    8699       303837 :       && do_spec_2 (sysroot_hdrs_suffix_spec, NULL) == 0)
    8700              :     {
    8701            0 :       if (argbuf.length () > 1)
    8702            0 :         error ("spec failure: more than one argument "
    8703              :                "to %<SYSROOT_HEADERS_SUFFIX_SPEC%>");
    8704            0 :       else if (argbuf.length () == 1)
    8705            0 :         target_sysroot_hdrs_suffix = xstrdup (argbuf.last ());
    8706              :     }
    8707              : 
    8708              :   /* Look for startfiles in the standard places.  */
    8709       303837 :   if (*startfile_prefix_spec != 0
    8710            0 :       && do_spec_2 (startfile_prefix_spec, NULL) == 0
    8711       303837 :       && do_spec_1 (" ", 0, NULL) == 0)
    8712              :     {
    8713            0 :       for (const char *arg : argbuf)
    8714            0 :         add_sysrooted_prefix (&startfile_prefixes, arg, "BINUTILS",
    8715              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8716              :     }
    8717              :   /* We should eventually get rid of all these and stick to
    8718              :      startfile_prefix_spec exclusively.  */
    8719       303837 :   else if (*cross_compile == '0' || target_system_root)
    8720              :     {
    8721       303837 :       if (*md_startfile_prefix)
    8722            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
    8723              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8724              : 
    8725       303837 :       if (*md_startfile_prefix_1)
    8726            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
    8727              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8728              : 
    8729              :       /* If standard_startfile_prefix is relative, base it on
    8730              :          standard_exec_prefix.  This lets us move the installed tree
    8731              :          as a unit.  If GCC_EXEC_PREFIX is defined, base
    8732              :          standard_startfile_prefix on that as well.
    8733              : 
    8734              :          If the prefix is relative, only search it for native compilers;
    8735              :          otherwise we will search a directory containing host libraries.  */
    8736       303837 :       if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
    8737              :         add_sysrooted_prefix (&startfile_prefixes,
    8738              :                               standard_startfile_prefix, "BINUTILS",
    8739              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8740       303837 :       else if (*cross_compile == '0')
    8741              :         {
    8742       303837 :           add_prefix (&startfile_prefixes,
    8743       607674 :                       concat (gcc_exec_prefix
    8744              :                               ? gcc_exec_prefix : standard_exec_prefix,
    8745              :                               machine_suffix,
    8746              :                               standard_startfile_prefix, NULL),
    8747              :                       NULL, PREFIX_PRIORITY_LAST, 0, 1);
    8748              :         }
    8749              : 
    8750              :       /* Sysrooted prefixes are relocated because target_system_root is
    8751              :          also relocated by gcc_exec_prefix.  */
    8752       303837 :       if (*standard_startfile_prefix_1)
    8753       303837 :         add_sysrooted_prefix (&startfile_prefixes,
    8754              :                               standard_startfile_prefix_1, "BINUTILS",
    8755              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8756       303837 :       if (*standard_startfile_prefix_2)
    8757       303837 :         add_sysrooted_prefix (&startfile_prefixes,
    8758              :                               standard_startfile_prefix_2, "BINUTILS",
    8759              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8760              :     }
    8761              : 
    8762              :   /* Process any user specified specs in the order given on the command
    8763              :      line.  */
    8764       303839 :   for (struct user_specs *uptr = user_specs_head; uptr; uptr = uptr->next)
    8765              :     {
    8766            3 :       char *filename = find_a_file (&startfile_prefixes, uptr->filename,
    8767              :                                     true);
    8768            3 :       read_specs (filename ? filename : uptr->filename, false, true);
    8769              :     }
    8770              : 
    8771              :   /* Process any user self specs.  */
    8772       303836 :   {
    8773       303836 :     struct spec_list *sl;
    8774     14280292 :     for (sl = specs; sl; sl = sl->next)
    8775     13976456 :       if (sl->name_len == sizeof "self_spec" - 1
    8776      2126852 :           && !strcmp (sl->name, "self_spec"))
    8777       303836 :         do_self_spec (*sl->ptr_spec);
    8778              :   }
    8779              : 
    8780       303836 :   if (compare_debug)
    8781              :     {
    8782          635 :       enum save_temps save;
    8783              : 
    8784          635 :       if (!compare_debug_second)
    8785              :         {
    8786          635 :           n_switches_debug_check[1] = n_switches;
    8787          635 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8788          635 :           switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
    8789              :                                              n_switches_alloc);
    8790              : 
    8791          635 :           do_self_spec ("%:compare-debug-self-opt()");
    8792          635 :           n_switches_debug_check[0] = n_switches;
    8793          635 :           n_switches_alloc_debug_check[0] = n_switches_alloc;
    8794          635 :           switches_debug_check[0] = switches;
    8795              : 
    8796          635 :           n_switches = n_switches_debug_check[1];
    8797          635 :           n_switches_alloc = n_switches_alloc_debug_check[1];
    8798          635 :           switches = switches_debug_check[1];
    8799              :         }
    8800              : 
    8801              :       /* Avoid crash when computing %j in this early.  */
    8802          635 :       save = save_temps_flag;
    8803          635 :       save_temps_flag = SAVE_TEMPS_NONE;
    8804              : 
    8805          635 :       compare_debug = -compare_debug;
    8806          635 :       do_self_spec ("%:compare-debug-self-opt()");
    8807              : 
    8808          635 :       save_temps_flag = save;
    8809              : 
    8810          635 :       if (!compare_debug_second)
    8811              :         {
    8812          635 :           n_switches_debug_check[1] = n_switches;
    8813          635 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8814          635 :           switches_debug_check[1] = switches;
    8815          635 :           compare_debug = -compare_debug;
    8816          635 :           n_switches = n_switches_debug_check[0];
    8817          635 :           n_switches_alloc = n_switches_debug_check[0];
    8818          635 :           switches = switches_debug_check[0];
    8819              :         }
    8820              :     }
    8821              : 
    8822              : 
    8823              :   /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake.  */
    8824       303836 :   if (gcc_exec_prefix)
    8825       303836 :     gcc_exec_prefix = concat (gcc_exec_prefix, spec_host_machine,
    8826              :                               dir_separator_str, spec_version,
    8827              :                               accel_dir_suffix, dir_separator_str, NULL);
    8828              : 
    8829              :   /* Now we have the specs.
    8830              :      Set the `valid' bits for switches that match anything in any spec.  */
    8831              : 
    8832       303836 :   validate_all_switches ();
    8833              : 
    8834              :   /* Now that we have the switches and the specs, set
    8835              :      the subdirectory based on the options.  */
    8836       303836 :   set_multilib_dir ();
    8837       303836 : }
    8838              : 
    8839              : /* Set up to remember the pathname of gcc and any options
    8840              :    needed for collect.  We use argv[0] instead of progname because
    8841              :    we need the complete pathname.  */
    8842              : 
    8843              : void
    8844       303836 : driver::putenv_COLLECT_GCC (const char *argv0) const
    8845              : {
    8846       303836 :   obstack_init (&collect_obstack);
    8847       303836 :   obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
    8848       303836 :   obstack_grow (&collect_obstack, argv0, strlen (argv0) + 1);
    8849       303836 :   xputenv (XOBFINISH (&collect_obstack, char *));
    8850       303836 : }
    8851              : 
    8852              : /* Set up to remember the pathname of the lto wrapper. */
    8853              : 
    8854              : void
    8855       303836 : driver::maybe_putenv_COLLECT_LTO_WRAPPER () const
    8856              : {
    8857       303836 :   char *lto_wrapper_file;
    8858              : 
    8859       303836 :   if (have_c)
    8860              :     lto_wrapper_file = NULL;
    8861              :   else
    8862       112249 :     lto_wrapper_file = find_a_program ("lto-wrapper");
    8863       112249 :   if (lto_wrapper_file)
    8864              :     {
    8865       220016 :       lto_wrapper_file = convert_white_space (lto_wrapper_file);
    8866       110008 :       set_static_spec_owned (&lto_wrapper_spec, lto_wrapper_file);
    8867       110008 :       obstack_init (&collect_obstack);
    8868       110008 :       obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
    8869              :                     sizeof ("COLLECT_LTO_WRAPPER=") - 1);
    8870       110008 :       obstack_grow (&collect_obstack, lto_wrapper_spec,
    8871              :                     strlen (lto_wrapper_spec) + 1);
    8872       110008 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8873              :     }
    8874              : 
    8875       303836 : }
    8876              : 
    8877              : /* Set up to remember the names of offload targets.  */
    8878              : 
    8879              : void
    8880       303836 : driver::maybe_putenv_OFFLOAD_TARGETS () const
    8881              : {
    8882       303836 :   if (offload_targets && offload_targets[0] != '\0')
    8883              :     {
    8884            0 :       obstack_grow (&collect_obstack, "OFFLOAD_TARGET_NAMES=",
    8885              :                     sizeof ("OFFLOAD_TARGET_NAMES=") - 1);
    8886            0 :       obstack_grow (&collect_obstack, offload_targets,
    8887              :                     strlen (offload_targets) + 1);
    8888            0 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8889              : #if OFFLOAD_DEFAULTED
    8890              :       if (offload_targets_default)
    8891              :         xputenv ("OFFLOAD_TARGET_DEFAULT=1");
    8892              : #endif
    8893              :     }
    8894              : 
    8895       303836 :   free (offload_targets);
    8896       303836 :   offload_targets = NULL;
    8897       303836 : }
    8898              : 
    8899              : /* Reject switches that no pass was interested in.  */
    8900              : 
    8901              : void
    8902       303836 : driver::handle_unrecognized_options ()
    8903              : {
    8904      7202762 :   for (size_t i = 0; (int) i < n_switches; i++)
    8905      6898926 :     if (! switches[i].validated)
    8906              :       {
    8907          605 :         const char *hint = m_option_proposer.suggest_option (switches[i].part1);
    8908          605 :         if (hint)
    8909          225 :           error ("unrecognized command-line option %<-%s%>;"
    8910              :                  " did you mean %<-%s%>?",
    8911          225 :                  switches[i].part1, hint);
    8912              :         else
    8913          380 :           error ("unrecognized command-line option %<-%s%>",
    8914          380 :                  switches[i].part1);
    8915              :       }
    8916       303836 : }
    8917              : 
    8918              : /* Handle the various -print-* options, returning 0 if the driver
    8919              :    should exit, or nonzero if the driver should continue.  */
    8920              : 
    8921              : int
    8922       303831 : driver::maybe_print_and_exit () const
    8923              : {
    8924       303831 :   if (print_search_dirs)
    8925              :     {
    8926           56 :       printf (_("install: %s%s\n"),
    8927              :               gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    8928           28 :               gcc_exec_prefix ? "" : machine_suffix);
    8929           28 :       printf (_("programs: %s\n"),
    8930              :               build_search_list (&exec_prefixes, "", false, false));
    8931           28 :       printf (_("libraries: %s\n"),
    8932              :               build_search_list (&startfile_prefixes, "", false, true));
    8933           28 :       return (0);
    8934              :     }
    8935              : 
    8936       303803 :   if (print_autofdo_gcov_version)
    8937              :     {
    8938            0 :       printf ("%d\n", AUTO_PROFILE_VERSION);
    8939            0 :       return (0);
    8940              :     }
    8941              : 
    8942       303803 :   if (print_file_name)
    8943              :     {
    8944         4632 :       printf ("%s\n", find_file (print_file_name));
    8945         4632 :       return (0);
    8946              :     }
    8947              : 
    8948       299171 :   if (print_prog_name)
    8949              :     {
    8950          217 :       if (use_ld != NULL && ! strcmp (print_prog_name, "ld"))
    8951              :         {
    8952              :           /* Append USE_LD to the default linker.  */
    8953              : #ifdef DEFAULT_LINKER
    8954              :           char *ld;
    8955              : # ifdef HAVE_HOST_EXECUTABLE_SUFFIX
    8956              :           int len = (sizeof (DEFAULT_LINKER)
    8957              :                      - sizeof (HOST_EXECUTABLE_SUFFIX));
    8958              :           ld = NULL;
    8959              :           if (len > 0)
    8960              :             {
    8961              :               char *default_linker = xstrdup (DEFAULT_LINKER);
    8962              :               /* Strip HOST_EXECUTABLE_SUFFIX if DEFAULT_LINKER contains
    8963              :                  HOST_EXECUTABLE_SUFFIX.  */
    8964              :               if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
    8965              :                 {
    8966              :                   default_linker[len] = '\0';
    8967              :                   ld = concat (default_linker, use_ld,
    8968              :                                HOST_EXECUTABLE_SUFFIX, NULL);
    8969              :                 }
    8970              :             }
    8971              :           if (ld == NULL)
    8972              : # endif
    8973              :           ld = concat (DEFAULT_LINKER, use_ld, NULL);
    8974              :           if (access (ld, X_OK) == 0)
    8975              :             {
    8976              :               printf ("%s\n", ld);
    8977              :               return (0);
    8978              :             }
    8979              : #endif
    8980            0 :           print_prog_name = concat (print_prog_name, use_ld, NULL);
    8981              :         }
    8982          217 :       char *newname = find_a_program (print_prog_name);
    8983          217 :       printf ("%s\n", (newname ? newname : print_prog_name));
    8984          217 :       return (0);
    8985              :     }
    8986              : 
    8987       298954 :   if (print_multi_lib)
    8988              :     {
    8989         5181 :       print_multilib_info ();
    8990         5181 :       return (0);
    8991              :     }
    8992              : 
    8993       293773 :   if (print_multi_directory)
    8994              :     {
    8995         4550 :       if (multilib_dir == NULL)
    8996         4525 :         printf (".\n");
    8997              :       else
    8998           25 :         printf ("%s\n", multilib_dir);
    8999         4550 :       return (0);
    9000              :     }
    9001              : 
    9002       289223 :   if (print_multiarch)
    9003              :     {
    9004            0 :       if (multiarch_dir == NULL)
    9005            0 :         printf ("\n");
    9006              :       else
    9007            0 :         printf ("%s\n", multiarch_dir);
    9008            0 :       return (0);
    9009              :     }
    9010              : 
    9011       289223 :   if (print_sysroot)
    9012              :     {
    9013            0 :       if (target_system_root)
    9014              :         {
    9015            0 :           if (target_sysroot_suffix)
    9016            0 :             printf ("%s%s\n", target_system_root, target_sysroot_suffix);
    9017              :           else
    9018            0 :             printf ("%s\n", target_system_root);
    9019              :         }
    9020            0 :       return (0);
    9021              :     }
    9022              : 
    9023       289223 :   if (print_multi_os_directory)
    9024              :     {
    9025          149 :       if (multilib_os_dir == NULL)
    9026            0 :         printf (".\n");
    9027              :       else
    9028          149 :         printf ("%s\n", multilib_os_dir);
    9029          149 :       return (0);
    9030              :     }
    9031              : 
    9032       289074 :   if (print_sysroot_headers_suffix)
    9033              :     {
    9034            1 :       if (*sysroot_hdrs_suffix_spec)
    9035              :         {
    9036            0 :           printf("%s\n", (target_sysroot_hdrs_suffix
    9037              :                           ? target_sysroot_hdrs_suffix
    9038              :                           : ""));
    9039            0 :           return (0);
    9040              :         }
    9041              :       else
    9042              :         /* The error status indicates that only one set of fixed
    9043              :            headers should be built.  */
    9044            1 :         fatal_error (input_location,
    9045              :                      "not configured with sysroot headers suffix");
    9046              :     }
    9047              : 
    9048       289073 :   if (print_help_list)
    9049              :     {
    9050            4 :       display_help ();
    9051              : 
    9052            4 :       if (! verbose_flag)
    9053              :         {
    9054            1 :           printf (_("\nFor bug reporting instructions, please see:\n"));
    9055            1 :           printf ("%s.\n", bug_report_url);
    9056              : 
    9057            1 :           return (0);
    9058              :         }
    9059              : 
    9060              :       /* We do not exit here.  Instead we have created a fake input file
    9061              :          called 'help-dummy' which needs to be compiled, and we pass this
    9062              :          on the various sub-processes, along with the --help switch.
    9063              :          Ensure their output appears after ours.  */
    9064            3 :       fputc ('\n', stdout);
    9065            3 :       fflush (stdout);
    9066              :     }
    9067              : 
    9068       289072 :   if (print_version)
    9069              :     {
    9070           78 :       printf (_("%s %s%s\n"), progname, pkgversion_string,
    9071              :               version_string);
    9072           78 :       printf ("Copyright %s 2026 Free Software Foundation, Inc.\n",
    9073              :               _("(C)"));
    9074           78 :       fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
    9075              : warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
    9076              :              stdout);
    9077           78 :       if (! verbose_flag)
    9078              :         return 0;
    9079              : 
    9080              :       /* We do not exit here. We use the same mechanism of --help to print
    9081              :          the version of the sub-processes. */
    9082            0 :       fputc ('\n', stdout);
    9083            0 :       fflush (stdout);
    9084              :     }
    9085              : 
    9086       288994 :   if (verbose_flag)
    9087              :     {
    9088         1577 :       print_configuration (stderr);
    9089         1577 :       if (n_infiles == 0)
    9090              :         return (0);
    9091              :     }
    9092              : 
    9093              :   return 1;
    9094              : }
    9095              : 
    9096              : /* Figure out what to do with each input file.
    9097              :    Return true if we need to exit early from "main", false otherwise.  */
    9098              : 
    9099              : bool
    9100       288237 : driver::prepare_infiles ()
    9101              : {
    9102       288237 :   size_t i;
    9103       288237 :   int lang_n_infiles = 0;
    9104              : 
    9105       288237 :   if (n_infiles == added_libraries)
    9106          194 :     fatal_error (input_location, "no input files");
    9107              : 
    9108       288043 :   if (seen_error ())
    9109              :     /* Early exit needed from main.  */
    9110              :     return true;
    9111              : 
    9112              :   /* Make a place to record the compiler output file names
    9113              :      that correspond to the input files.  */
    9114              : 
    9115       287620 :   i = n_infiles;
    9116       287620 :   i += lang_specific_extra_outfiles;
    9117       287620 :   outfiles = XCNEWVEC (const char *, i);
    9118              : 
    9119              :   /* Record which files were specified explicitly as link input.  */
    9120              : 
    9121       287620 :   explicit_link_files = XCNEWVEC (char, n_infiles);
    9122              : 
    9123       287620 :   combine_inputs = have_o || flag_wpa;
    9124              : 
    9125       849551 :   for (i = 0; (int) i < n_infiles; i++)
    9126              :     {
    9127       561931 :       const char *name = infiles[i].name;
    9128       561931 :       struct compiler *compiler = lookup_compiler (name,
    9129              :                                                    strlen (name),
    9130              :                                                    infiles[i].language);
    9131              : 
    9132       561931 :       if (compiler && !(compiler->combinable))
    9133       259022 :         combine_inputs = false;
    9134              : 
    9135       561931 :       if (lang_n_infiles > 0 && compiler != input_file_compiler
    9136       252477 :           && infiles[i].language && infiles[i].language[0] != '*')
    9137           36 :         infiles[i].incompiler = compiler;
    9138       561895 :       else if (infiles[i].artificial)
    9139              :         /* Leave lang_n_infiles alone so files added by the driver don't
    9140              :            interfere with -c -o.  */
    9141            3 :         infiles[i].incompiler = compiler;
    9142       561892 :       else if (compiler)
    9143              :         {
    9144       298620 :           lang_n_infiles++;
    9145       298620 :           input_file_compiler = compiler;
    9146       298620 :           infiles[i].incompiler = compiler;
    9147              :         }
    9148              :       else
    9149              :         {
    9150              :           /* Since there is no compiler for this input file, assume it is a
    9151              :              linker file.  */
    9152       263272 :           explicit_link_files[i] = 1;
    9153       263272 :           infiles[i].incompiler = NULL;
    9154              :         }
    9155       561931 :       infiles[i].compiled = false;
    9156       561931 :       infiles[i].preprocessed = false;
    9157              :     }
    9158              : 
    9159       287620 :   if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
    9160            0 :     fatal_error (input_location,
    9161              :                  "cannot specify %<-o%> with %<-c%>, %<-S%> or %<-E%> "
    9162              :                  "with multiple files");
    9163              : 
    9164              :   /* No early exit needed from main; we can continue.  */
    9165              :   return false;
    9166              : }
    9167              : 
    9168              : /* Run the spec machinery on each input file.  */
    9169              : 
    9170              : void
    9171       287620 : driver::do_spec_on_infiles () const
    9172              : {
    9173       287620 :   size_t i;
    9174              : 
    9175       849551 :   for (i = 0; (int) i < n_infiles; i++)
    9176              :     {
    9177       561931 :       int this_file_error = 0;
    9178              : 
    9179              :       /* Tell do_spec what to substitute for %i.  */
    9180              : 
    9181       561931 :       input_file_number = i;
    9182       561931 :       set_input (infiles[i].name);
    9183              : 
    9184       561931 :       if (infiles[i].compiled)
    9185         9122 :         continue;
    9186              : 
    9187              :       /* Use the same thing in %o, unless cp->spec says otherwise.  */
    9188              : 
    9189       552809 :       outfiles[i] = gcc_input_filename;
    9190              : 
    9191              :       /* Figure out which compiler from the file's suffix.  */
    9192              : 
    9193       552809 :       input_file_compiler
    9194       552809 :         = lookup_compiler (infiles[i].name, input_filename_length,
    9195              :                            infiles[i].language);
    9196              : 
    9197       552809 :       if (input_file_compiler)
    9198              :         {
    9199              :           /* Ok, we found an applicable compiler.  Run its spec.  */
    9200              : 
    9201       289537 :           if (input_file_compiler->spec[0] == '#')
    9202              :             {
    9203            0 :               error ("%s: %s compiler not installed on this system",
    9204              :                      gcc_input_filename, &input_file_compiler->spec[1]);
    9205            0 :               this_file_error = 1;
    9206              :             }
    9207              :           else
    9208              :             {
    9209       289537 :               int value;
    9210              : 
    9211       289537 :               if (compare_debug)
    9212              :                 {
    9213          633 :                   free (debug_check_temp_file[0]);
    9214          633 :                   debug_check_temp_file[0] = NULL;
    9215              : 
    9216          633 :                   free (debug_check_temp_file[1]);
    9217          633 :                   debug_check_temp_file[1] = NULL;
    9218              :                 }
    9219              : 
    9220       289537 :               value = do_spec (input_file_compiler->spec);
    9221       289537 :               infiles[i].compiled = true;
    9222       289537 :               if (value < 0)
    9223              :                 this_file_error = 1;
    9224       259615 :               else if (compare_debug && debug_check_temp_file[0])
    9225              :                 {
    9226          629 :                   if (verbose_flag)
    9227            0 :                     inform (UNKNOWN_LOCATION,
    9228              :                             "recompiling with %<-fcompare-debug%>");
    9229              : 
    9230          629 :                   compare_debug = -compare_debug;
    9231          629 :                   n_switches = n_switches_debug_check[1];
    9232          629 :                   n_switches_alloc = n_switches_alloc_debug_check[1];
    9233          629 :                   switches = switches_debug_check[1];
    9234              : 
    9235          629 :                   value = do_spec (input_file_compiler->spec);
    9236              : 
    9237          629 :                   compare_debug = -compare_debug;
    9238          629 :                   n_switches = n_switches_debug_check[0];
    9239          629 :                   n_switches_alloc = n_switches_alloc_debug_check[0];
    9240          629 :                   switches = switches_debug_check[0];
    9241              : 
    9242          629 :                   if (value < 0)
    9243              :                     {
    9244            2 :                       error ("during %<-fcompare-debug%> recompilation");
    9245            2 :                       this_file_error = 1;
    9246              :                     }
    9247              : 
    9248          629 :                   gcc_assert (debug_check_temp_file[1]
    9249              :                               && filename_cmp (debug_check_temp_file[0],
    9250              :                                                debug_check_temp_file[1]));
    9251              : 
    9252          629 :                   if (verbose_flag)
    9253            0 :                     inform (UNKNOWN_LOCATION, "comparing final insns dumps");
    9254              : 
    9255          629 :                   if (compare_files (debug_check_temp_file))
    9256        29936 :                     this_file_error = 1;
    9257              :                 }
    9258              : 
    9259       289537 :               if (compare_debug)
    9260              :                 {
    9261          633 :                   free (debug_check_temp_file[0]);
    9262          633 :                   debug_check_temp_file[0] = NULL;
    9263              : 
    9264          633 :                   free (debug_check_temp_file[1]);
    9265          633 :                   debug_check_temp_file[1] = NULL;
    9266              :                 }
    9267              :             }
    9268              :         }
    9269              : 
    9270              :       /* If this file's name does not contain a recognized suffix,
    9271              :          record it as explicit linker input.  */
    9272              : 
    9273              :       else
    9274       263272 :         explicit_link_files[i] = 1;
    9275              : 
    9276              :       /* Clear the delete-on-failure queue, deleting the files in it
    9277              :          if this compilation failed.  */
    9278              : 
    9279       552809 :       if (this_file_error)
    9280              :         {
    9281        29936 :           delete_failure_queue ();
    9282        29936 :           errorcount++;
    9283              :         }
    9284              :       /* If this compilation succeeded, don't delete those files later.  */
    9285       552809 :       clear_failure_queue ();
    9286              :     }
    9287              : 
    9288              :   /* Reset the input file name to the first compile/object file name, for use
    9289              :      with %b in LINK_SPEC. We use the first input file that we can find
    9290              :      a compiler to compile it instead of using infiles.language since for
    9291              :      languages other than C we use aliases that we then lookup later.  */
    9292       287620 :   if (n_infiles > 0)
    9293              :     {
    9294              :       int i;
    9295              : 
    9296       299850 :       for (i = 0; i < n_infiles ; i++)
    9297       297931 :         if (infiles[i].incompiler
    9298        12230 :             || (infiles[i].language && infiles[i].language[0] != '*'))
    9299              :           {
    9300       285701 :             set_input (infiles[i].name);
    9301       285701 :             break;
    9302              :           }
    9303              :     }
    9304              : 
    9305       287620 :   if (!seen_error ())
    9306              :     {
    9307              :       /* Make sure INPUT_FILE_NUMBER points to first available open
    9308              :          slot.  */
    9309       257684 :       input_file_number = n_infiles;
    9310       257684 :       if (lang_specific_pre_link ())
    9311            0 :         errorcount++;
    9312              :     }
    9313       287620 : }
    9314              : 
    9315              : /* If we have to run the linker, do it now.  */
    9316              : 
    9317              : void
    9318       287620 : driver::maybe_run_linker (const char *argv0) const
    9319              : {
    9320       287620 :   size_t i;
    9321       287620 :   int linker_was_run = 0;
    9322       287620 :   int num_linker_inputs;
    9323              : 
    9324              :   /* Determine if there are any linker input files.  */
    9325       287620 :   num_linker_inputs = 0;
    9326       849551 :   for (i = 0; (int) i < n_infiles; i++)
    9327       561931 :     if (explicit_link_files[i] || outfiles[i] != NULL)
    9328       552389 :       num_linker_inputs++;
    9329              : 
    9330              :   /* Arrange for temporary file names created during linking to take
    9331              :      on names related with the linker output rather than with the
    9332              :      inputs when appropriate.  */
    9333       287620 :   if (outbase && *outbase)
    9334              :     {
    9335       265563 :       if (dumpdir)
    9336              :         {
    9337        90810 :           char *tofree = dumpdir;
    9338        90810 :           gcc_checking_assert (strlen (dumpdir) == dumpdir_length);
    9339        90810 :           dumpdir = concat (dumpdir, outbase, ".", NULL);
    9340        90810 :           free (tofree);
    9341              :         }
    9342              :       else
    9343       174753 :         dumpdir = concat (outbase, ".", NULL);
    9344       265563 :       dumpdir_length += strlen (outbase) + 1;
    9345       265563 :       dumpdir_trailing_dash_added = true;
    9346       265563 :     }
    9347        22057 :   else if (dumpdir_trailing_dash_added)
    9348              :     {
    9349        17613 :       gcc_assert (dumpdir[dumpdir_length - 1] == '-');
    9350        17613 :       dumpdir[dumpdir_length - 1] = '.';
    9351              :     }
    9352              : 
    9353       287620 :   if (dumpdir_trailing_dash_added)
    9354              :     {
    9355       283176 :       gcc_assert (dumpdir_length > 0);
    9356       283176 :       gcc_assert (dumpdir[dumpdir_length - 1] == '.');
    9357       283176 :       dumpdir_length--;
    9358              :     }
    9359              : 
    9360       287620 :   free (outbase);
    9361       287620 :   input_basename = outbase = NULL;
    9362       287620 :   outbase_length = suffixed_basename_length = basename_length = 0;
    9363              : 
    9364              :   /* Run ld to link all the compiler output files.  */
    9365              : 
    9366       287620 :   if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
    9367              :     {
    9368       257193 :       int tmp = execution_count;
    9369              : 
    9370       257193 :       detect_jobserver ();
    9371              : 
    9372       257193 :       if (! have_c)
    9373              :         {
    9374              : #if HAVE_LTO_PLUGIN > 0
    9375              : #if HAVE_LTO_PLUGIN == 2
    9376        96281 :           const char *fno_use_linker_plugin = "fno-use-linker-plugin";
    9377              : #else
    9378              :           const char *fuse_linker_plugin = "fuse-linker-plugin";
    9379              : #endif
    9380              : #endif
    9381              : 
    9382              :           /* We'll use ld if we can't find collect2.  */
    9383        96281 :           if (! strcmp (linker_name_spec, "collect2"))
    9384              :             {
    9385        96281 :               char *s = find_a_program ("collect2");
    9386        96281 :               if (s == NULL)
    9387         1139 :                 set_static_spec_shared (&linker_name_spec, "ld");
    9388              :             }
    9389              : 
    9390              : #if HAVE_LTO_PLUGIN > 0
    9391              : #if HAVE_LTO_PLUGIN == 2
    9392        96281 :           if (!switch_matches (fno_use_linker_plugin,
    9393              :                                fno_use_linker_plugin
    9394              :                                + strlen (fno_use_linker_plugin), 0))
    9395              : #else
    9396              :           if (switch_matches (fuse_linker_plugin,
    9397              :                               fuse_linker_plugin
    9398              :                               + strlen (fuse_linker_plugin), 0))
    9399              : #endif
    9400              :             {
    9401        90725 :               char *temp_spec = find_a_file (&exec_prefixes,
    9402              :                                              LTOPLUGINSONAME,
    9403              :                                              false);
    9404        90725 :               if (!temp_spec)
    9405            0 :                 fatal_error (input_location,
    9406              :                              "%<-fuse-linker-plugin%>, but %s not found",
    9407              :                              LTOPLUGINSONAME);
    9408        90725 :               linker_plugin_file_spec = convert_white_space (temp_spec);
    9409              :             }
    9410              : #endif
    9411        96281 :           set_static_spec_shared (&lto_gcc_spec, argv0);
    9412              :         }
    9413              : 
    9414              :       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    9415              :          for collect.  */
    9416       257193 :       putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
    9417       257193 :       putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
    9418              : 
    9419       257193 :       if (print_subprocess_help == 1)
    9420              :         {
    9421            0 :           printf (_("\nLinker options\n==============\n\n"));
    9422            0 :           printf (_("Use \"-Wl,OPTION\" to pass \"OPTION\""
    9423              :                     " to the linker.\n\n"));
    9424            0 :           fflush (stdout);
    9425              :         }
    9426       257193 :       int value = do_spec (link_command_spec);
    9427       257193 :       if (value < 0)
    9428          131 :         errorcount = 1;
    9429       257193 :       linker_was_run = (tmp != execution_count);
    9430              :     }
    9431              : 
    9432              :   /* If options said don't run linker,
    9433              :      complain about input files to be given to the linker.  */
    9434              : 
    9435       287620 :   if (! linker_was_run && !seen_error ())
    9436       357278 :     for (i = 0; (int) i < n_infiles; i++)
    9437       195871 :       if (explicit_link_files[i]
    9438        25357 :           && !(infiles[i].language && infiles[i].language[0] == '*'))
    9439              :         {
    9440           38 :           warning (0, "%s: linker input file unused because linking not done",
    9441           19 :                    outfiles[i]);
    9442           19 :           if (access (outfiles[i], F_OK) < 0)
    9443              :             /* This is can be an indication the user specified an erroneous
    9444              :                separated option value, (or used the wrong prefix for an
    9445              :                option).  */
    9446            7 :             error ("%s: linker input file not found: %m", outfiles[i]);
    9447              :         }
    9448       287620 : }
    9449              : 
    9450              : /* The end of "main".  */
    9451              : 
    9452              : void
    9453       287620 : driver::final_actions () const
    9454              : {
    9455              :   /* Delete some or all of the temporary files we made.  */
    9456              : 
    9457       287620 :   if (seen_error ())
    9458        30072 :     delete_failure_queue ();
    9459       287620 :   delete_temp_files ();
    9460              : 
    9461       287620 :   if (totruncate_file != NULL && !seen_error ())
    9462              :     /* Truncate file specified by -truncate.
    9463              :        Used by lto-wrapper to reduce temporary disk-space usage. */
    9464         8068 :     truncate(totruncate_file, 0);
    9465              : 
    9466       287620 :   if (print_help_list)
    9467              :     {
    9468            3 :       printf (("\nFor bug reporting instructions, please see:\n"));
    9469            3 :       printf ("%s\n", bug_report_url);
    9470              :     }
    9471       287620 : }
    9472              : 
    9473              : /* Detect whether jobserver is active and working.  If not drop
    9474              :    --jobserver-auth from MAKEFLAGS.  */
    9475              : 
    9476              : void
    9477       257193 : driver::detect_jobserver () const
    9478              : {
    9479       257193 :   jobserver_info jinfo;
    9480       257193 :   if (!jinfo.is_active && !jinfo.skipped_makeflags.empty ())
    9481            0 :     xputenv (xstrdup (jinfo.skipped_makeflags.c_str ()));
    9482       257193 : }
    9483              : 
    9484              : /* Determine what the exit code of the driver should be.  */
    9485              : 
    9486              : int
    9487       288043 : driver::get_exit_code () const
    9488              : {
    9489       288043 :   return (signal_count != 0 ? 2
    9490       288043 :           : seen_error () ? (pass_exit_codes ? greatest_status : 1)
    9491            0 :           : 0);
    9492              : }
    9493              : 
    9494              : /* Find the proper compilation spec for the file name NAME,
    9495              :    whose length is LENGTH.  LANGUAGE is the specified language,
    9496              :    or 0 if this file is to be passed to the linker.  */
    9497              : 
    9498              : static struct compiler *
    9499      1114740 : lookup_compiler (const char *name, size_t length, const char *language)
    9500              : {
    9501      1630773 :   struct compiler *cp;
    9502              : 
    9503              :   /* If this was specified by the user to be a linker input, indicate that.  */
    9504      1630773 :   if (language != 0 && language[0] == '*')
    9505              :     return 0;
    9506              : 
    9507              :   /* Otherwise, look for the language, if one is spec'd.  */
    9508      1152577 :   if (language != 0)
    9509              :     {
    9510     23295433 :       for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9511     23295433 :         if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language))
    9512              :           {
    9513       588182 :             if (name != NULL && strcmp (name, "-") == 0
    9514         2078 :                 && (strcmp (cp->suffix, "@c-header") == 0
    9515         2078 :                     || strcmp (cp->suffix, "@c++-header") == 0)
    9516            0 :                 && !have_E)
    9517            0 :               fatal_error (input_location,
    9518              :                            "cannot use %<-%> as input filename for a "
    9519              :                            "precompiled header");
    9520              : 
    9521              :             return cp;
    9522              :           }
    9523              : 
    9524            0 :       error ("language %s not recognized", language);
    9525            0 :       return 0;
    9526              :     }
    9527              : 
    9528              :   /* Look for a suffix.  */
    9529     31204341 :   for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9530              :     {
    9531     31155993 :       if (/* The suffix `-' matches only the file name `-'.  */
    9532     31155993 :           (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9533     31155979 :           || (strlen (cp->suffix) < length
    9534              :               /* See if the suffix matches the end of NAME.  */
    9535     30702626 :               && !strcmp (cp->suffix,
    9536     30702626 :                           name + length - strlen (cp->suffix))
    9537              :          ))
    9538              :         break;
    9539              :     }
    9540              : 
    9541              : #if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
    9542              :   /* Look again, but case-insensitively this time.  */
    9543              :   if (cp < compilers)
    9544              :     for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9545              :       {
    9546              :         if (/* The suffix `-' matches only the file name `-'.  */
    9547              :             (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9548              :             || (strlen (cp->suffix) < length
    9549              :                 /* See if the suffix matches the end of NAME.  */
    9550              :                 && ((!strcmp (cp->suffix,
    9551              :                              name + length - strlen (cp->suffix))
    9552              :                      || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
    9553              :                     && !strcasecmp (cp->suffix,
    9554              :                                     name + length - strlen (cp->suffix)))
    9555              :            ))
    9556              :           break;
    9557              :       }
    9558              : #endif
    9559              : 
    9560       564395 :   if (cp >= compilers)
    9561              :     {
    9562       516047 :       if (cp->spec[0] != '@')
    9563              :         /* A non-alias entry: return it.  */
    9564              :         return cp;
    9565              : 
    9566              :       /* An alias entry maps a suffix to a language.
    9567              :          Search for the language; pass 0 for NAME and LENGTH
    9568              :          to avoid infinite recursion if language not found.  */
    9569       516033 :       return lookup_compiler (NULL, 0, cp->spec + 1);
    9570              :     }
    9571              :   return 0;
    9572              : }
    9573              : 
    9574              : static char *
    9575     47096906 : save_string (const char *s, int len)
    9576              : {
    9577     47096906 :   char *result = XNEWVEC (char, len + 1);
    9578              : 
    9579     47096906 :   gcc_checking_assert (strlen (s) >= (unsigned int) len);
    9580     47096906 :   memcpy (result, s, len);
    9581     47096906 :   result[len] = 0;
    9582     47096906 :   return result;
    9583              : }
    9584              : 
    9585              : 
    9586              : static inline void
    9587     47094580 : validate_switches_from_spec (const char *spec, bool user)
    9588              : {
    9589     47094580 :   const char *p = spec;
    9590     47094580 :   char c;
    9591    581238271 :   while ((c = *p++))
    9592    487049111 :     if (c == '%'
    9593    487049111 :         && (*p == '{'
    9594     11545768 :             || *p == '<'
    9595     10634260 :             || (*p == 'W' && *++p == '{')
    9596     10634260 :             || (*p == '@' && *++p == '{')))
    9597              :       /* We have a switch spec.  */
    9598     46790746 :       p = validate_switches (p + 1, user, *p == '{');
    9599     47094580 : }
    9600              : 
    9601              : static void
    9602       303836 : validate_all_switches (void)
    9603              : {
    9604       303836 :   struct compiler *comp;
    9605       303836 :   struct spec_list *spec;
    9606              : 
    9607     33118124 :   for (comp = compilers; comp->spec; comp++)
    9608     32814288 :     validate_switches_from_spec (comp->spec, false);
    9609              : 
    9610              :   /* Look through the linked list of specs read from the specs file.  */
    9611     14280292 :   for (spec = specs; spec; spec = spec->next)
    9612     13976456 :     validate_switches_from_spec (*spec->ptr_spec, spec->user_p);
    9613              : 
    9614       303836 :   validate_switches_from_spec (link_command_spec, false);
    9615       303836 : }
    9616              : 
    9617              : /* Look at the switch-name that comes after START and mark as valid
    9618              :    all supplied switches that match it.  If BRACED, handle other
    9619              :    switches after '|' and '&', and specs after ':' until ';' or '}',
    9620              :    going back for more switches after ';'.  Without BRACED, handle
    9621              :    only one atom.  Return a pointer to whatever follows the handled
    9622              :    items, after the closing brace if BRACED.  */
    9623              : 
    9624              : static const char *
    9625    202354778 : validate_switches (const char *start, bool user_spec, bool braced)
    9626              : {
    9627    202354778 :   const char *p = start;
    9628    260995126 :   const char *atom;
    9629    260995126 :   size_t len;
    9630    260995126 :   int i;
    9631    260995126 :   bool suffix;
    9632    260995126 :   bool starred;
    9633              : 
    9634              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    9635              : 
    9636    260995126 : next_member:
    9637    260995126 :   suffix = false;
    9638    260995126 :   starred = false;
    9639              : 
    9640    288340366 :   SKIP_WHITE ();
    9641              : 
    9642    260995126 :   if (*p == '!')
    9643     80820377 :     p++;
    9644              : 
    9645    260995126 :   SKIP_WHITE ();
    9646    260995126 :   if (*p == '.' || *p == ',')
    9647            0 :     suffix = true, p++;
    9648              : 
    9649    260995126 :   atom = p;
    9650    260995126 :   while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    9651   1747360852 :          || *p == ',' || *p == '.' || *p == '@')
    9652   1486365726 :     p++;
    9653    260995126 :   len = p - atom;
    9654              : 
    9655    260995126 :   if (*p == '*')
    9656     68970772 :     starred = true, p++;
    9657              : 
    9658    262210470 :   SKIP_WHITE ();
    9659              : 
    9660    260995126 :   if (!suffix)
    9661              :     {
    9662              :       /* Mark all matching switches as valid.  */
    9663   6187172590 :       for (i = 0; i < n_switches; i++)
    9664   5926177464 :         if (!strncmp (switches[i].part1, atom, len)
    9665    493107262 :             && (starred || switches[i].part1[len] == '\0')
    9666     51327500 :             && (switches[i].known || user_spec))
    9667     51324994 :               switches[i].validated = true;
    9668              :     }
    9669              : 
    9670    260995126 :   if (!braced)
    9671              :     return p;
    9672              : 
    9673    259475946 :   if (*p) p++;
    9674    259475946 :   if (*p && (p[-1] == '|' || p[-1] == '&'))
    9675     40106352 :     goto next_member;
    9676              : 
    9677    219369594 :   if (*p && p[-1] == ':')
    9678              :     {
    9679   2945993852 :       while (*p && *p != ';' && *p != '}')
    9680              :         {
    9681   2776757197 :           if (*p == '%')
    9682              :             {
    9683    261298960 :               p++;
    9684    261298960 :               if (*p == '{' || *p == '<')
    9685    152829508 :                 p = validate_switches (p+1, user_spec, *p == '{');
    9686    108469452 :               else if (p[0] == 'W' && p[1] == '{')
    9687      2430688 :                 p = validate_switches (p+2, user_spec, true);
    9688    106038764 :               else if (p[0] == '@' && p[1] == '{')
    9689       303836 :                 p = validate_switches (p+2, user_spec, true);
    9690              :             }
    9691              :           else
    9692   2515458237 :             p++;
    9693              :         }
    9694              : 
    9695    169236655 :       if (*p) p++;
    9696    169236655 :       if (*p && p[-1] == ';')
    9697     18533996 :         goto next_member;
    9698              :     }
    9699              : 
    9700              :   return p;
    9701              : #undef SKIP_WHITE
    9702              : }
    9703              : 
    9704              : struct mdswitchstr
    9705              : {
    9706              :   const char *str;
    9707              :   int len;
    9708              : };
    9709              : 
    9710              : static struct mdswitchstr *mdswitches;
    9711              : static int n_mdswitches;
    9712              : 
    9713              : /* Check whether a particular argument was used.  The first time we
    9714              :    canonicalize the switches to keep only the ones we care about.  */
    9715              : 
    9716              : struct used_arg_t
    9717              : {
    9718              :  public:
    9719              :   int operator () (const char *p, int len);
    9720              :   void finalize ();
    9721              : 
    9722              :  private:
    9723              :   struct mswitchstr
    9724              :   {
    9725              :     const char *str;
    9726              :     const char *replace;
    9727              :     int len;
    9728              :     int rep_len;
    9729              :   };
    9730              : 
    9731              :   mswitchstr *mswitches;
    9732              :   int n_mswitches;
    9733              : 
    9734              : };
    9735              : 
    9736              : used_arg_t used_arg;
    9737              : 
    9738              : int
    9739      1836461 : used_arg_t::operator () (const char *p, int len)
    9740              : {
    9741      1836461 :   int i, j;
    9742              : 
    9743      1836461 :   if (!mswitches)
    9744              :     {
    9745       303836 :       struct mswitchstr *matches;
    9746       303836 :       const char *q;
    9747       303836 :       int cnt = 0;
    9748              : 
    9749              :       /* Break multilib_matches into the component strings of string
    9750              :          and replacement string.  */
    9751      5165212 :       for (q = multilib_matches; *q != '\0'; q++)
    9752      4861376 :         if (*q == ';')
    9753       607672 :           cnt++;
    9754              : 
    9755       303836 :       matches
    9756       303836 :         = (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
    9757       303836 :       i = 0;
    9758       303836 :       q = multilib_matches;
    9759       911508 :       while (*q != '\0')
    9760              :         {
    9761       607672 :           matches[i].str = q;
    9762      2430688 :           while (*q != ' ')
    9763              :             {
    9764      1823016 :               if (*q == '\0')
    9765              :                 {
    9766            0 :                 invalid_matches:
    9767            0 :                   fatal_error (input_location, "multilib spec %qs is invalid",
    9768              :                                multilib_matches);
    9769              :                 }
    9770      1823016 :               q++;
    9771              :             }
    9772       607672 :           matches[i].len = q - matches[i].str;
    9773              : 
    9774       607672 :           matches[i].replace = ++q;
    9775      2430688 :           while (*q != ';' && *q != '\0')
    9776              :             {
    9777      1823016 :               if (*q == ' ')
    9778            0 :                 goto invalid_matches;
    9779      1823016 :               q++;
    9780              :             }
    9781       607672 :           matches[i].rep_len = q - matches[i].replace;
    9782       607672 :           i++;
    9783       607672 :           if (*q == ';')
    9784       607672 :             q++;
    9785              :         }
    9786              : 
    9787              :       /* Now build a list of the replacement string for switches that we care
    9788              :          about.  Make sure we allocate at least one entry.  This prevents
    9789              :          xmalloc from calling fatal, and prevents us from re-executing this
    9790              :          block of code.  */
    9791       303836 :       mswitches
    9792       607672 :         = XNEWVEC (struct mswitchstr, n_mdswitches + (n_switches ? n_switches : 1));
    9793      7202762 :       for (i = 0; i < n_switches; i++)
    9794      6898926 :         if ((switches[i].live_cond & SWITCH_IGNORE) == 0)
    9795              :           {
    9796      6898920 :             int xlen = strlen (switches[i].part1);
    9797     20683915 :             for (j = 0; j < cnt; j++)
    9798     13795391 :               if (xlen == matches[j].len
    9799        19207 :                   && ! strncmp (switches[i].part1, matches[j].str, xlen))
    9800              :                 {
    9801        10396 :                   mswitches[n_mswitches].str = matches[j].replace;
    9802        10396 :                   mswitches[n_mswitches].len = matches[j].rep_len;
    9803        10396 :                   mswitches[n_mswitches].replace = (char *) 0;
    9804        10396 :                   mswitches[n_mswitches].rep_len = 0;
    9805        10396 :                   n_mswitches++;
    9806        10396 :                   break;
    9807              :                 }
    9808              :           }
    9809              : 
    9810              :       /* Add MULTILIB_DEFAULTS switches too, as long as they were not present
    9811              :          on the command line nor any options mutually incompatible with
    9812              :          them.  */
    9813       607672 :       for (i = 0; i < n_mdswitches; i++)
    9814              :         {
    9815       303836 :           const char *r;
    9816              : 
    9817       607672 :           for (q = multilib_options; *q != '\0'; *q && q++)
    9818              :             {
    9819       303836 :               while (*q == ' ')
    9820            0 :                 q++;
    9821              : 
    9822       303836 :               r = q;
    9823       303836 :               while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
    9824       303836 :                      || strchr (" /", q[mdswitches[i].len]) == NULL)
    9825              :                 {
    9826            0 :                   while (*q != ' ' && *q != '/' && *q != '\0')
    9827            0 :                     q++;
    9828            0 :                   if (*q != '/')
    9829              :                     break;
    9830            0 :                   q++;
    9831              :                 }
    9832              : 
    9833       303836 :               if (*q != ' ' && *q != '\0')
    9834              :                 {
    9835       605223 :                   while (*r != ' ' && *r != '\0')
    9836              :                     {
    9837              :                       q = r;
    9838      2420892 :                       while (*q != ' ' && *q != '/' && *q != '\0')
    9839      1815669 :                         q++;
    9840              : 
    9841       605223 :                       if (used_arg (r, q - r))
    9842              :                         break;
    9843              : 
    9844       594827 :                       if (*q != '/')
    9845              :                         {
    9846       293440 :                           mswitches[n_mswitches].str = mdswitches[i].str;
    9847       293440 :                           mswitches[n_mswitches].len = mdswitches[i].len;
    9848       293440 :                           mswitches[n_mswitches].replace = (char *) 0;
    9849       293440 :                           mswitches[n_mswitches].rep_len = 0;
    9850       293440 :                           n_mswitches++;
    9851       293440 :                           break;
    9852              :                         }
    9853              : 
    9854       301387 :                       r = q + 1;
    9855              :                     }
    9856              :                   break;
    9857              :                 }
    9858              :             }
    9859              :         }
    9860              :     }
    9861              : 
    9862      2460027 :   for (i = 0; i < n_mswitches; i++)
    9863      1249581 :     if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
    9864              :       return 1;
    9865              : 
    9866              :   return 0;
    9867              : }
    9868              : 
    9869         1144 : void used_arg_t::finalize ()
    9870              : {
    9871         1144 :   XDELETEVEC (mswitches);
    9872         1144 :   mswitches = NULL;
    9873         1144 :   n_mswitches = 0;
    9874         1144 : }
    9875              : 
    9876              : 
    9877              : static int
    9878      1251962 : default_arg (const char *p, int len)
    9879              : {
    9880      1251962 :   int i;
    9881              : 
    9882      1872762 :   for (i = 0; i < n_mdswitches; i++)
    9883      1251962 :     if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
    9884              :       return 1;
    9885              : 
    9886              :   return 0;
    9887              : }
    9888              : 
    9889              : /* Use multilib_dir as key to find corresponding multilib_os_dir and
    9890              :    multiarch_dir.  */
    9891              : 
    9892              : static void
    9893            0 : find_multilib_os_dir_by_multilib_dir (const char *multilib_dir,
    9894              :                                       const char **p_multilib_os_dir,
    9895              :                                       const char **p_multiarch_dir)
    9896              : {
    9897            0 :   const char *p = multilib_select;
    9898            0 :   unsigned int this_path_len;
    9899            0 :   const char *this_path;
    9900            0 :   int ok = 0;
    9901              : 
    9902            0 :   while (*p != '\0')
    9903              :     {
    9904              :       /* Ignore newlines.  */
    9905            0 :       if (*p == '\n')
    9906              :         {
    9907            0 :           ++p;
    9908            0 :           continue;
    9909              :         }
    9910              : 
    9911              :       /* Get the initial path.  */
    9912              :       this_path = p;
    9913            0 :       while (*p != ' ')
    9914              :         {
    9915            0 :           if (*p == '\0')
    9916              :             {
    9917            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
    9918              :                            multilib_select, multilib_reuse);
    9919              :             }
    9920            0 :           ++p;
    9921              :         }
    9922            0 :       this_path_len = p - this_path;
    9923              : 
    9924            0 :       ok = 0;
    9925              : 
    9926              :       /* Skip any arguments, we don't care at this stage.  */
    9927            0 :       while (*++p != ';');
    9928              : 
    9929            0 :       if (this_path_len != 1
    9930            0 :           || this_path[0] != '.')
    9931              :         {
    9932            0 :           char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
    9933            0 :           char *q;
    9934              : 
    9935            0 :           strncpy (new_multilib_dir, this_path, this_path_len);
    9936            0 :           new_multilib_dir[this_path_len] = '\0';
    9937            0 :           q = strchr (new_multilib_dir, ':');
    9938            0 :           if (q != NULL)
    9939            0 :             *q = '\0';
    9940              : 
    9941            0 :           if (strcmp (new_multilib_dir, multilib_dir) == 0)
    9942            0 :             ok = 1;
    9943              :         }
    9944              : 
    9945              :       /* Found matched multilib_dir, update multilib_os_dir and
    9946              :          multiarch_dir.  */
    9947            0 :       if (ok)
    9948              :         {
    9949            0 :           const char *q = this_path, *end = this_path + this_path_len;
    9950              : 
    9951            0 :           while (q < end && *q != ':')
    9952            0 :             q++;
    9953            0 :           if (q < end)
    9954              :             {
    9955            0 :               const char *q2 = q + 1, *ml_end = end;
    9956            0 :               char *new_multilib_os_dir;
    9957              : 
    9958            0 :               while (q2 < end && *q2 != ':')
    9959            0 :                 q2++;
    9960            0 :               if (*q2 == ':')
    9961            0 :                 ml_end = q2;
    9962            0 :               if (ml_end - q == 1)
    9963            0 :                 *p_multilib_os_dir = xstrdup (".");
    9964              :               else
    9965              :                 {
    9966            0 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
    9967            0 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
    9968            0 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
    9969            0 :                   *p_multilib_os_dir = new_multilib_os_dir;
    9970              :                 }
    9971              : 
    9972            0 :               if (q2 < end && *q2 == ':')
    9973              :                 {
    9974            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
    9975            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
    9976            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
    9977            0 :                   *p_multiarch_dir = new_multiarch_dir;
    9978              :                 }
    9979              :               break;
    9980              :             }
    9981              :         }
    9982            0 :       ++p;
    9983              :     }
    9984            0 : }
    9985              : 
    9986              : /* Work out the subdirectory to use based on the options. The format of
    9987              :    multilib_select is a list of elements. Each element is a subdirectory
    9988              :    name followed by a list of options followed by a semicolon. The format
    9989              :    of multilib_exclusions is the same, but without the preceding
    9990              :    directory. First gcc will check the exclusions, if none of the options
    9991              :    beginning with an exclamation point are present, and all of the other
    9992              :    options are present, then we will ignore this completely. Passing
    9993              :    that, gcc will consider each multilib_select in turn using the same
    9994              :    rules for matching the options. If a match is found, that subdirectory
    9995              :    will be used.
    9996              :    A subdirectory name is optionally followed by a colon and the corresponding
    9997              :    multiarch name.  */
    9998              : 
    9999              : static void
   10000       303836 : set_multilib_dir (void)
   10001              : {
   10002       303836 :   const char *p;
   10003       303836 :   unsigned int this_path_len;
   10004       303836 :   const char *this_path, *this_arg;
   10005       303836 :   const char *start, *end;
   10006       303836 :   int not_arg;
   10007       303836 :   int ok, ndfltok, first;
   10008              : 
   10009       303836 :   n_mdswitches = 0;
   10010       303836 :   start = multilib_defaults;
   10011       303836 :   while (*start == ' ' || *start == '\t')
   10012            0 :     start++;
   10013       607672 :   while (*start != '\0')
   10014              :     {
   10015       303836 :       n_mdswitches++;
   10016      1215344 :       while (*start != ' ' && *start != '\t' && *start != '\0')
   10017       911508 :         start++;
   10018       303836 :       while (*start == ' ' || *start == '\t')
   10019            0 :         start++;
   10020              :     }
   10021              : 
   10022       303836 :   if (n_mdswitches)
   10023              :     {
   10024       303836 :       int i = 0;
   10025              : 
   10026       303836 :       mdswitches = XNEWVEC (struct mdswitchstr, n_mdswitches);
   10027       303836 :       for (start = multilib_defaults; *start != '\0'; start = end + 1)
   10028              :         {
   10029       303836 :           while (*start == ' ' || *start == '\t')
   10030            0 :             start++;
   10031              : 
   10032       303836 :           if (*start == '\0')
   10033              :             break;
   10034              : 
   10035       911508 :           for (end = start + 1;
   10036       911508 :                *end != ' ' && *end != '\t' && *end != '\0'; end++)
   10037              :             ;
   10038              : 
   10039       303836 :           obstack_grow (&multilib_obstack, start, end - start);
   10040       303836 :           obstack_1grow (&multilib_obstack, 0);
   10041       303836 :           mdswitches[i].str = XOBFINISH (&multilib_obstack, const char *);
   10042       303836 :           mdswitches[i++].len = end - start;
   10043              : 
   10044       303836 :           if (*end == '\0')
   10045              :             break;
   10046              :         }
   10047              :     }
   10048              : 
   10049       303836 :   p = multilib_exclusions;
   10050       303836 :   while (*p != '\0')
   10051              :     {
   10052              :       /* Ignore newlines.  */
   10053            0 :       if (*p == '\n')
   10054              :         {
   10055            0 :           ++p;
   10056            0 :           continue;
   10057              :         }
   10058              : 
   10059              :       /* Check the arguments.  */
   10060              :       ok = 1;
   10061            0 :       while (*p != ';')
   10062              :         {
   10063            0 :           if (*p == '\0')
   10064              :             {
   10065            0 :             invalid_exclusions:
   10066            0 :               fatal_error (input_location, "multilib exclusions %qs is invalid",
   10067              :                            multilib_exclusions);
   10068              :             }
   10069              : 
   10070            0 :           if (! ok)
   10071              :             {
   10072            0 :               ++p;
   10073            0 :               continue;
   10074              :             }
   10075              : 
   10076            0 :           this_arg = p;
   10077            0 :           while (*p != ' ' && *p != ';')
   10078              :             {
   10079            0 :               if (*p == '\0')
   10080            0 :                 goto invalid_exclusions;
   10081            0 :               ++p;
   10082              :             }
   10083              : 
   10084            0 :           if (*this_arg != '!')
   10085              :             not_arg = 0;
   10086              :           else
   10087              :             {
   10088            0 :               not_arg = 1;
   10089            0 :               ++this_arg;
   10090              :             }
   10091              : 
   10092            0 :           ok = used_arg (this_arg, p - this_arg);
   10093            0 :           if (not_arg)
   10094            0 :             ok = ! ok;
   10095              : 
   10096            0 :           if (*p == ' ')
   10097            0 :             ++p;
   10098              :         }
   10099              : 
   10100            0 :       if (ok)
   10101              :         return;
   10102              : 
   10103            0 :       ++p;
   10104              :     }
   10105              : 
   10106       303836 :   first = 1;
   10107       303836 :   p = multilib_select;
   10108              : 
   10109              :   /* Append multilib reuse rules if any.  With those rules, we can reuse
   10110              :      one multilib for certain different options sets.  */
   10111       303836 :   if (strlen (multilib_reuse) > 0)
   10112            0 :     p = concat (p, multilib_reuse, NULL);
   10113              : 
   10114       615619 :   while (*p != '\0')
   10115              :     {
   10116              :       /* Ignore newlines.  */
   10117       615619 :       if (*p == '\n')
   10118              :         {
   10119            0 :           ++p;
   10120            0 :           continue;
   10121              :         }
   10122              : 
   10123              :       /* Get the initial path.  */
   10124              :       this_path = p;
   10125      4333174 :       while (*p != ' ')
   10126              :         {
   10127      3717555 :           if (*p == '\0')
   10128              :             {
   10129            0 :             invalid_select:
   10130            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
   10131              :                            multilib_select, multilib_reuse);
   10132              :             }
   10133      3717555 :           ++p;
   10134              :         }
   10135       615619 :       this_path_len = p - this_path;
   10136              : 
   10137              :       /* Check the arguments.  */
   10138       615619 :       ok = 1;
   10139       615619 :       ndfltok = 1;
   10140       615619 :       ++p;
   10141      1846857 :       while (*p != ';')
   10142              :         {
   10143      1231238 :           if (*p == '\0')
   10144            0 :             goto invalid_select;
   10145              : 
   10146      1231238 :           if (! ok)
   10147              :             {
   10148            0 :               ++p;
   10149            0 :               continue;
   10150              :             }
   10151              : 
   10152      5844407 :           this_arg = p;
   10153      5844407 :           while (*p != ' ' && *p != ';')
   10154              :             {
   10155      4613169 :               if (*p == '\0')
   10156            0 :                 goto invalid_select;
   10157      4613169 :               ++p;
   10158              :             }
   10159              : 
   10160      1231238 :           if (*this_arg != '!')
   10161              :             not_arg = 0;
   10162              :           else
   10163              :             {
   10164       919455 :               not_arg = 1;
   10165       919455 :               ++this_arg;
   10166              :             }
   10167              : 
   10168              :           /* If this is a default argument, we can just ignore it.
   10169              :              This is true even if this_arg begins with '!'.  Beginning
   10170              :              with '!' does not mean that this argument is necessarily
   10171              :              inappropriate for this library: it merely means that
   10172              :              there is a more specific library which uses this
   10173              :              argument.  If this argument is a default, we need not
   10174              :              consider that more specific library.  */
   10175      1231238 :           ok = used_arg (this_arg, p - this_arg);
   10176      1231238 :           if (not_arg)
   10177       919455 :             ok = ! ok;
   10178              : 
   10179      1231238 :           if (! ok)
   10180       319730 :             ndfltok = 0;
   10181              : 
   10182      1231238 :           if (default_arg (this_arg, p - this_arg))
   10183       615619 :             ok = 1;
   10184              : 
   10185      1231238 :           if (*p == ' ')
   10186       615619 :             ++p;
   10187              :         }
   10188              : 
   10189       615619 :       if (ok && first)
   10190              :         {
   10191       303836 :           if (this_path_len != 1
   10192       295889 :               || this_path[0] != '.')
   10193              :             {
   10194         7947 :               char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
   10195         7947 :               char *q;
   10196              : 
   10197         7947 :               strncpy (new_multilib_dir, this_path, this_path_len);
   10198         7947 :               new_multilib_dir[this_path_len] = '\0';
   10199         7947 :               q = strchr (new_multilib_dir, ':');
   10200         7947 :               if (q != NULL)
   10201         7947 :                 *q = '\0';
   10202         7947 :               multilib_dir = new_multilib_dir;
   10203              :             }
   10204              :           first = 0;
   10205              :         }
   10206              : 
   10207       615619 :       if (ndfltok)
   10208              :         {
   10209       303836 :           const char *q = this_path, *end = this_path + this_path_len;
   10210              : 
   10211       911508 :           while (q < end && *q != ':')
   10212       607672 :             q++;
   10213       303836 :           if (q < end)
   10214              :             {
   10215       303836 :               const char *q2 = q + 1, *ml_end = end;
   10216       303836 :               char *new_multilib_os_dir;
   10217              : 
   10218      2718630 :               while (q2 < end && *q2 != ':')
   10219      2414794 :                 q2++;
   10220       303836 :               if (*q2 == ':')
   10221            0 :                 ml_end = q2;
   10222       303836 :               if (ml_end - q == 1)
   10223            0 :                 multilib_os_dir = xstrdup (".");
   10224              :               else
   10225              :                 {
   10226       303836 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
   10227       303836 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
   10228       303836 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
   10229       303836 :                   multilib_os_dir = new_multilib_os_dir;
   10230              :                 }
   10231              : 
   10232       303836 :               if (q2 < end && *q2 == ':')
   10233              :                 {
   10234            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
   10235            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
   10236            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
   10237            0 :                   multiarch_dir = new_multiarch_dir;
   10238              :                 }
   10239              :               break;
   10240              :             }
   10241              :         }
   10242              : 
   10243       311783 :       ++p;
   10244              :     }
   10245              : 
   10246       607672 :   multilib_dir =
   10247       303836 :     targetm_common.compute_multilib (
   10248              :       switches,
   10249              :       n_switches,
   10250              :       multilib_dir,
   10251              :       multilib_defaults,
   10252              :       multilib_select,
   10253              :       multilib_matches,
   10254              :       multilib_exclusions,
   10255              :       multilib_reuse);
   10256              : 
   10257       303836 :   if (multilib_dir == NULL && multilib_os_dir != NULL
   10258       295889 :       && strcmp (multilib_os_dir, ".") == 0)
   10259              :     {
   10260            0 :       free (const_cast<char *> (multilib_os_dir));
   10261            0 :       multilib_os_dir = NULL;
   10262              :     }
   10263       303836 :   else if (multilib_dir != NULL && multilib_os_dir == NULL)
   10264              :     {
   10265              :       /* Give second chance to search matched multilib_os_dir again by matching
   10266              :          the multilib_dir since some target may use TARGET_COMPUTE_MULTILIB
   10267              :          hook rather than the builtin way.  */
   10268            0 :       find_multilib_os_dir_by_multilib_dir (multilib_dir, &multilib_os_dir,
   10269              :                                             &multiarch_dir);
   10270              : 
   10271            0 :       if (multilib_os_dir == NULL)
   10272            0 :         multilib_os_dir = multilib_dir;
   10273              :     }
   10274              : }
   10275              : 
   10276              : /* Print out the multiple library subdirectory selection
   10277              :    information.  This prints out a series of lines.  Each line looks
   10278              :    like SUBDIRECTORY;@OPTION@OPTION, with as many options as is
   10279              :    required.  Only the desired options are printed out, the negative
   10280              :    matches.  The options are print without a leading dash.  There are
   10281              :    no spaces to make it easy to use the information in the shell.
   10282              :    Each subdirectory is printed only once.  This assumes the ordering
   10283              :    generated by the genmultilib script. Also, we leave out ones that match
   10284              :    the exclusions.  */
   10285              : 
   10286              : static void
   10287         5181 : print_multilib_info (void)
   10288              : {
   10289         5181 :   const char *p = multilib_select;
   10290         5181 :   const char *last_path = 0, *this_path;
   10291         5181 :   int skip;
   10292         5181 :   int not_arg;
   10293         5181 :   unsigned int last_path_len = 0;
   10294              : 
   10295        20724 :   while (*p != '\0')
   10296              :     {
   10297        15543 :       skip = 0;
   10298              :       /* Ignore newlines.  */
   10299        15543 :       if (*p == '\n')
   10300              :         {
   10301            0 :           ++p;
   10302            0 :           continue;
   10303              :         }
   10304              : 
   10305              :       /* Get the initial path.  */
   10306              :       this_path = p;
   10307       124344 :       while (*p != ' ')
   10308              :         {
   10309       108801 :           if (*p == '\0')
   10310              :             {
   10311            0 :             invalid_select:
   10312            0 :               fatal_error (input_location,
   10313              :                            "multilib select %qs is invalid", multilib_select);
   10314              :             }
   10315              : 
   10316       108801 :           ++p;
   10317              :         }
   10318              : 
   10319              :       /* When --disable-multilib was used but target defines
   10320              :          MULTILIB_OSDIRNAMES, entries starting with .: (and not starting
   10321              :          with .:: for multiarch configurations) are there just to find
   10322              :          multilib_os_dir, so skip them from output.  */
   10323        15543 :       if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
   10324        15543 :         skip = 1;
   10325              : 
   10326              :       /* Check for matches with the multilib_exclusions. We don't bother
   10327              :          with the '!' in either list. If any of the exclusion rules match
   10328              :          all of its options with the select rule, we skip it.  */
   10329        15543 :       {
   10330        15543 :         const char *e = multilib_exclusions;
   10331        15543 :         const char *this_arg;
   10332              : 
   10333        15543 :         while (*e != '\0')
   10334              :           {
   10335            0 :             int m = 1;
   10336              :             /* Ignore newlines.  */
   10337            0 :             if (*e == '\n')
   10338              :               {
   10339            0 :                 ++e;
   10340            0 :                 continue;
   10341              :               }
   10342              : 
   10343              :             /* Check the arguments.  */
   10344            0 :             while (*e != ';')
   10345              :               {
   10346            0 :                 const char *q;
   10347            0 :                 int mp = 0;
   10348              : 
   10349            0 :                 if (*e == '\0')
   10350              :                   {
   10351            0 :                   invalid_exclusion:
   10352            0 :                     fatal_error (input_location,
   10353              :                                  "multilib exclusion %qs is invalid",
   10354              :                                  multilib_exclusions);
   10355              :                   }
   10356              : 
   10357            0 :                 if (! m)
   10358              :                   {
   10359            0 :                     ++e;
   10360            0 :                     continue;
   10361              :                   }
   10362              : 
   10363              :                 this_arg = e;
   10364              : 
   10365            0 :                 while (*e != ' ' && *e != ';')
   10366              :                   {
   10367            0 :                     if (*e == '\0')
   10368            0 :                       goto invalid_exclusion;
   10369            0 :                     ++e;
   10370              :                   }
   10371              : 
   10372            0 :                 q = p + 1;
   10373            0 :                 while (*q != ';')
   10374              :                   {
   10375            0 :                     const char *arg;
   10376            0 :                     int len = e - this_arg;
   10377              : 
   10378            0 :                     if (*q == '\0')
   10379            0 :                       goto invalid_select;
   10380              : 
   10381              :                     arg = q;
   10382              : 
   10383            0 :                     while (*q != ' ' && *q != ';')
   10384              :                       {
   10385            0 :                         if (*q == '\0')
   10386            0 :                           goto invalid_select;
   10387            0 :                         ++q;
   10388              :                       }
   10389              : 
   10390            0 :                     if (! strncmp (arg, this_arg,
   10391            0 :                                    (len < q - arg) ? q - arg : len)
   10392            0 :                         || default_arg (this_arg, e - this_arg))
   10393              :                       {
   10394              :                         mp = 1;
   10395              :                         break;
   10396              :                       }
   10397              : 
   10398            0 :                     if (*q == ' ')
   10399            0 :                       ++q;
   10400              :                   }
   10401              : 
   10402            0 :                 if (! mp)
   10403            0 :                   m = 0;
   10404              : 
   10405            0 :                 if (*e == ' ')
   10406            0 :                   ++e;
   10407              :               }
   10408              : 
   10409            0 :             if (m)
   10410              :               {
   10411              :                 skip = 1;
   10412              :                 break;
   10413              :               }
   10414              : 
   10415            0 :             if (*e != '\0')
   10416            0 :               ++e;
   10417              :           }
   10418              :       }
   10419              : 
   10420        15543 :       if (! skip)
   10421              :         {
   10422              :           /* If this is a duplicate, skip it.  */
   10423        31086 :           skip = (last_path != 0
   10424        10362 :                   && (unsigned int) (p - this_path) == last_path_len
   10425        15543 :                   && ! filename_ncmp (last_path, this_path, last_path_len));
   10426              : 
   10427        15543 :           last_path = this_path;
   10428        15543 :           last_path_len = p - this_path;
   10429              :         }
   10430              : 
   10431              :       /* If all required arguments are default arguments, and no default
   10432              :          arguments appear in the ! argument list, then we can skip it.
   10433              :          We will already have printed a directory identical to this one
   10434              :          which does not require that default argument.  */
   10435        15543 :       if (! skip)
   10436              :         {
   10437        15543 :           const char *q;
   10438        15543 :           bool default_arg_ok = false;
   10439              : 
   10440        15543 :           q = p + 1;
   10441        25905 :           while (*q != ';')
   10442              :             {
   10443        20724 :               const char *arg;
   10444              : 
   10445        20724 :               if (*q == '\0')
   10446            0 :                 goto invalid_select;
   10447              : 
   10448        20724 :               if (*q == '!')
   10449              :                 {
   10450        15543 :                   not_arg = 1;
   10451        15543 :                   q++;
   10452              :                 }
   10453              :               else
   10454              :                 not_arg = 0;
   10455        20724 :               arg = q;
   10456              : 
   10457        82896 :               while (*q != ' ' && *q != ';')
   10458              :                 {
   10459        62172 :                   if (*q == '\0')
   10460            0 :                     goto invalid_select;
   10461        62172 :                   ++q;
   10462              :                 }
   10463              : 
   10464        20724 :               if (default_arg (arg, q - arg))
   10465              :                 {
   10466              :                   /* Stop checking if any default arguments appeared in not
   10467              :                      list.  */
   10468        15543 :                   if (not_arg)
   10469              :                     {
   10470              :                       default_arg_ok = false;
   10471              :                       break;
   10472              :                     }
   10473              : 
   10474              :                   default_arg_ok = true;
   10475              :                 }
   10476         5181 :               else if (!not_arg)
   10477              :                 {
   10478              :                   /* Stop checking if any required argument is not provided by
   10479              :                      default arguments.  */
   10480              :                   default_arg_ok = false;
   10481              :                   break;
   10482              :                 }
   10483              : 
   10484        10362 :               if (*q == ' ')
   10485         5181 :                 ++q;
   10486              :             }
   10487              : 
   10488              :           /* Make sure all default argument is OK for this multi-lib set.  */
   10489        15543 :           if (default_arg_ok)
   10490              :             skip = 1;
   10491              :           else
   10492              :             skip = 0;
   10493              :         }
   10494              : 
   10495              :       if (! skip)
   10496              :         {
   10497              :           const char *p1;
   10498              : 
   10499        25905 :           for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
   10500        15543 :             putchar (*p1);
   10501        10362 :           putchar (';');
   10502              :         }
   10503              : 
   10504        15543 :       ++p;
   10505        77715 :       while (*p != ';')
   10506              :         {
   10507        62172 :           int use_arg;
   10508              : 
   10509        62172 :           if (*p == '\0')
   10510            0 :             goto invalid_select;
   10511              : 
   10512        62172 :           if (skip)
   10513              :             {
   10514        41448 :               ++p;
   10515        41448 :               continue;
   10516              :             }
   10517              : 
   10518        20724 :           use_arg = *p != '!';
   10519              : 
   10520        20724 :           if (use_arg)
   10521         5181 :             putchar ('@');
   10522              : 
   10523        98439 :           while (*p != ' ' && *p != ';')
   10524              :             {
   10525        77715 :               if (*p == '\0')
   10526            0 :                 goto invalid_select;
   10527        77715 :               if (use_arg)
   10528        15543 :                 putchar (*p);
   10529        77715 :               ++p;
   10530              :             }
   10531              : 
   10532        20724 :           if (*p == ' ')
   10533        10362 :             ++p;
   10534              :         }
   10535              : 
   10536        15543 :       if (! skip)
   10537              :         {
   10538              :           /* If there are extra options, print them now.  */
   10539        10362 :           if (multilib_extra && *multilib_extra)
   10540              :             {
   10541              :               int print_at = true;
   10542              :               const char *q;
   10543              : 
   10544            0 :               for (q = multilib_extra; *q != '\0'; q++)
   10545              :                 {
   10546            0 :                   if (*q == ' ')
   10547              :                     print_at = true;
   10548              :                   else
   10549              :                     {
   10550            0 :                       if (print_at)
   10551            0 :                         putchar ('@');
   10552            0 :                       putchar (*q);
   10553            0 :                       print_at = false;
   10554              :                     }
   10555              :                 }
   10556              :             }
   10557              : 
   10558        10362 :           putchar ('\n');
   10559              :         }
   10560              : 
   10561        15543 :       ++p;
   10562              :     }
   10563         5181 : }
   10564              : 
   10565              : /* getenv built-in spec function.
   10566              : 
   10567              :    Returns the value of the environment variable given by its first argument,
   10568              :    concatenated with the second argument.  If the variable is not defined, a
   10569              :    fatal error is issued unless such undefs are internally allowed, in which
   10570              :    case the variable name prefixed by a '/' is used as the variable value.
   10571              : 
   10572              :    The leading '/' allows using the result at a spot where a full path would
   10573              :    normally be expected and when the actual value doesn't really matter since
   10574              :    undef vars are allowed.  */
   10575              : 
   10576              : static const char *
   10577            0 : getenv_spec_function (int argc, const char **argv)
   10578              : {
   10579            0 :   const char *value;
   10580            0 :   const char *varname;
   10581              : 
   10582            0 :   char *result;
   10583            0 :   char *ptr;
   10584            0 :   size_t len;
   10585              : 
   10586            0 :   if (argc != 2)
   10587              :     return NULL;
   10588              : 
   10589            0 :   varname = argv[0];
   10590            0 :   value = env.get (varname);
   10591              : 
   10592              :   /* If the variable isn't defined and this is allowed, craft our expected
   10593              :      return value.  Assume variable names used in specs strings don't contain
   10594              :      any active spec character so don't need escaping.  */
   10595            0 :   if (!value && spec_undefvar_allowed)
   10596              :     {
   10597            0 :       result = XNEWVAR (char, strlen(varname) + 2);
   10598            0 :       sprintf (result, "/%s", varname);
   10599            0 :       return result;
   10600              :     }
   10601              : 
   10602            0 :   if (!value)
   10603            0 :     fatal_error (input_location,
   10604              :                  "environment variable %qs not defined", varname);
   10605              : 
   10606              :   /* We have to escape every character of the environment variable so
   10607              :      they are not interpreted as active spec characters.  A
   10608              :      particularly painful case is when we are reading a variable
   10609              :      holding a windows path complete with \ separators.  */
   10610            0 :   len = strlen (value) * 2 + strlen (argv[1]) + 1;
   10611            0 :   result = XNEWVAR (char, len);
   10612            0 :   for (ptr = result; *value; ptr += 2)
   10613              :     {
   10614            0 :       ptr[0] = '\\';
   10615            0 :       ptr[1] = *value++;
   10616              :     }
   10617              : 
   10618            0 :   strcpy (ptr, argv[1]);
   10619              : 
   10620            0 :   return result;
   10621              : }
   10622              : 
   10623              : /* if-exists built-in spec function.
   10624              : 
   10625              :    Checks to see if the file specified by the absolute pathname in
   10626              :    ARGS exists.  Returns that pathname if found.
   10627              : 
   10628              :    The usual use for this function is to check for a library file
   10629              :    (whose name has been expanded with %s).  */
   10630              : 
   10631              : static const char *
   10632            0 : if_exists_spec_function (int argc, const char **argv)
   10633              : {
   10634              :   /* Must have only one argument.  */
   10635            0 :   if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10636            0 :     return argv[0];
   10637              : 
   10638              :   return NULL;
   10639              : }
   10640              : 
   10641              : /* if-exists-else built-in spec function.
   10642              : 
   10643              :    This is like if-exists, but takes an additional argument which
   10644              :    is returned if the first argument does not exist.  */
   10645              : 
   10646              : static const char *
   10647            0 : if_exists_else_spec_function (int argc, const char **argv)
   10648              : {
   10649              :   /* Must have exactly two arguments.  */
   10650            0 :   if (argc != 2)
   10651              :     return NULL;
   10652              : 
   10653            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10654            0 :     return argv[0];
   10655              : 
   10656            0 :   return argv[1];
   10657              : }
   10658              : 
   10659              : /* if-exists-then-else built-in spec function.
   10660              : 
   10661              :    Checks to see if the file specified by the absolute pathname in
   10662              :    the first arg exists.  Returns the second arg if so, otherwise returns
   10663              :    the third arg if it is present.  */
   10664              : 
   10665              : static const char *
   10666            0 : if_exists_then_else_spec_function (int argc, const char **argv)
   10667              : {
   10668              : 
   10669              :   /* Must have two or three arguments.  */
   10670            0 :   if (argc != 2 && argc != 3)
   10671              :     return NULL;
   10672              : 
   10673            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10674            0 :     return argv[1];
   10675              : 
   10676            0 :   if (argc == 3)
   10677            0 :     return argv[2];
   10678              : 
   10679              :   return NULL;
   10680              : }
   10681              : 
   10682              : /* sanitize built-in spec function.
   10683              : 
   10684              :    This returns non-NULL, if sanitizing address, thread or
   10685              :    any of the undefined behavior sanitizers.  */
   10686              : 
   10687              : static const char *
   10688       864639 : sanitize_spec_function (int argc, const char **argv)
   10689              : {
   10690       864639 :   if (argc != 1)
   10691              :     return NULL;
   10692              : 
   10693       864639 :   if (strcmp (argv[0], "address") == 0)
   10694       381648 :     return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL;
   10695       672497 :   if (strcmp (argv[0], "hwaddress") == 0)
   10696       384094 :     return (flag_sanitize & SANITIZE_USER_HWADDRESS) ? "" : NULL;
   10697       480355 :   if (strcmp (argv[0], "kernel-address") == 0)
   10698            0 :     return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL;
   10699       480355 :   if (strcmp (argv[0], "kernel-hwaddress") == 0)
   10700            0 :     return (flag_sanitize & SANITIZE_KERNEL_HWADDRESS) ? "" : NULL;
   10701       480355 :   if (strcmp (argv[0], "memtag-stack") == 0)
   10702            0 :     return (flag_sanitize & SANITIZE_MEMTAG_STACK) ? "" : NULL;
   10703       480355 :   if (strcmp (argv[0], "thread") == 0)
   10704       383888 :     return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
   10705       288213 :   if (strcmp (argv[0], "undefined") == 0)
   10706        96071 :     return ((flag_sanitize
   10707        96071 :              & ~flag_sanitize_trap
   10708        96071 :              & (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)))
   10709       190242 :            ? "" : NULL;
   10710       192142 :   if (strcmp (argv[0], "leak") == 0)
   10711       192142 :     return ((flag_sanitize
   10712       192142 :              & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
   10713       384284 :             == SANITIZE_LEAK) ? "" : NULL;
   10714              :   return NULL;
   10715              : }
   10716              : 
   10717              : /* replace-outfile built-in spec function.
   10718              : 
   10719              :    This looks for the first argument in the outfiles array's name and
   10720              :    replaces it with the second argument.  */
   10721              : 
   10722              : static const char *
   10723            0 : replace_outfile_spec_function (int argc, const char **argv)
   10724              : {
   10725            0 :   int i;
   10726              :   /* Must have exactly two arguments.  */
   10727            0 :   if (argc != 2)
   10728            0 :     abort ();
   10729              : 
   10730            0 :   for (i = 0; i < n_infiles; i++)
   10731              :     {
   10732            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10733            0 :         outfiles[i] = xstrdup (argv[1]);
   10734              :     }
   10735            0 :   return NULL;
   10736              : }
   10737              : 
   10738              : /* remove-outfile built-in spec function.
   10739              :  *
   10740              :  *    This looks for the first argument in the outfiles array's name and
   10741              :  *       removes it.  */
   10742              : 
   10743              : static const char *
   10744            0 : remove_outfile_spec_function (int argc, const char **argv)
   10745              : {
   10746            0 :   int i;
   10747              :   /* Must have exactly one argument.  */
   10748            0 :   if (argc != 1)
   10749            0 :     abort ();
   10750              : 
   10751            0 :   for (i = 0; i < n_infiles; i++)
   10752              :     {
   10753            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10754            0 :         outfiles[i] = NULL;
   10755              :     }
   10756            0 :   return NULL;
   10757              : }
   10758              : 
   10759              : /* Given two version numbers, compares the two numbers.
   10760              :    A version number must match the regular expression
   10761              :    ([1-9][0-9]*|0)(\.([1-9][0-9]*|0))*
   10762              : */
   10763              : static int
   10764            0 : compare_version_strings (const char *v1, const char *v2)
   10765              : {
   10766            0 :   int rresult;
   10767            0 :   regex_t r;
   10768              : 
   10769            0 :   if (regcomp (&r, "^([1-9][0-9]*|0)(\\.([1-9][0-9]*|0))*$",
   10770              :                REG_EXTENDED | REG_NOSUB) != 0)
   10771            0 :     abort ();
   10772            0 :   rresult = regexec (&r, v1, 0, NULL, 0);
   10773            0 :   if (rresult == REG_NOMATCH)
   10774            0 :     fatal_error (input_location, "invalid version number %qs", v1);
   10775            0 :   else if (rresult != 0)
   10776            0 :     abort ();
   10777            0 :   rresult = regexec (&r, v2, 0, NULL, 0);
   10778            0 :   if (rresult == REG_NOMATCH)
   10779            0 :     fatal_error (input_location, "invalid version number %qs", v2);
   10780            0 :   else if (rresult != 0)
   10781            0 :     abort ();
   10782              : 
   10783            0 :   return strverscmp (v1, v2);
   10784              : }
   10785              : 
   10786              : 
   10787              : /* version_compare built-in spec function.
   10788              : 
   10789              :    This takes an argument of the following form:
   10790              : 
   10791              :    <comparison-op> <arg1> [<arg2>] <switch> <result>
   10792              : 
   10793              :    and produces "result" if the comparison evaluates to true,
   10794              :    and nothing if it doesn't.
   10795              : 
   10796              :    The supported <comparison-op> values are:
   10797              : 
   10798              :    >=  true if switch is a later (or same) version than arg1
   10799              :    !>  opposite of >=
   10800              :    <   true if switch is an earlier version than arg1
   10801              :    !<  opposite of <
   10802              :    ><  true if switch is arg1 or later, and earlier than arg2
   10803              :    <>  true if switch is earlier than arg1 or is arg2 or later
   10804              : 
   10805              :    If the switch is not present, the condition is false unless
   10806              :    the first character of the <comparison-op> is '!'.
   10807              : 
   10808              :    For example,
   10809              :    %:version-compare(>= 10.3 mmacosx-version-min= -lmx)
   10810              :    adds -lmx if -mmacosx-version-min=10.3.9 was passed.  */
   10811              : 
   10812              : static const char *
   10813            0 : version_compare_spec_function (int argc, const char **argv)
   10814              : {
   10815            0 :   int comp1, comp2;
   10816            0 :   size_t switch_len;
   10817            0 :   const char *switch_value = NULL;
   10818            0 :   int nargs = 1, i;
   10819            0 :   bool result;
   10820              : 
   10821            0 :   if (argc < 3)
   10822            0 :     fatal_error (input_location, "too few arguments to %%:version-compare");
   10823            0 :   if (argv[0][0] == '\0')
   10824            0 :     abort ();
   10825            0 :   if ((argv[0][1] == '<' || argv[0][1] == '>') && argv[0][0] != '!')
   10826            0 :     nargs = 2;
   10827            0 :   if (argc != nargs + 3)
   10828            0 :     fatal_error (input_location, "too many arguments to %%:version-compare");
   10829              : 
   10830            0 :   switch_len = strlen (argv[nargs + 1]);
   10831            0 :   for (i = 0; i < n_switches; i++)
   10832            0 :     if (!strncmp (switches[i].part1, argv[nargs + 1], switch_len)
   10833            0 :         && check_live_switch (i, switch_len))
   10834            0 :       switch_value = switches[i].part1 + switch_len;
   10835              : 
   10836            0 :   if (switch_value == NULL)
   10837              :     comp1 = comp2 = -1;
   10838              :   else
   10839              :     {
   10840            0 :       comp1 = compare_version_strings (switch_value, argv[1]);
   10841            0 :       if (nargs == 2)
   10842            0 :         comp2 = compare_version_strings (switch_value, argv[2]);
   10843              :       else
   10844              :         comp2 = -1;  /* This value unused.  */
   10845              :     }
   10846              : 
   10847            0 :   switch (argv[0][0] << 8 | argv[0][1])
   10848              :     {
   10849            0 :     case '>' << 8 | '=':
   10850            0 :       result = comp1 >= 0;
   10851            0 :       break;
   10852            0 :     case '!' << 8 | '<':
   10853            0 :       result = comp1 >= 0 || switch_value == NULL;
   10854            0 :       break;
   10855            0 :     case '<' << 8:
   10856            0 :       result = comp1 < 0;
   10857            0 :       break;
   10858            0 :     case '!' << 8 | '>':
   10859            0 :       result = comp1 < 0 || switch_value == NULL;
   10860            0 :       break;
   10861            0 :     case '>' << 8 | '<':
   10862            0 :       result = comp1 >= 0 && comp2 < 0;
   10863            0 :       break;
   10864            0 :     case '<' << 8 | '>':
   10865            0 :       result = comp1 < 0 || comp2 >= 0;
   10866            0 :       break;
   10867              : 
   10868            0 :     default:
   10869            0 :       fatal_error (input_location,
   10870              :                    "unknown operator %qs in %%:version-compare", argv[0]);
   10871              :     }
   10872            0 :   if (! result)
   10873              :     return NULL;
   10874              : 
   10875            0 :   return argv[nargs + 2];
   10876              : }
   10877              : 
   10878              : /* %:include builtin spec function.  This differs from %include in that it
   10879              :    can be nested inside a spec, and thus be conditionalized.  It takes
   10880              :    one argument, the filename, and looks for it in the startfile path.
   10881              :    The result is always NULL, i.e. an empty expansion.  */
   10882              : 
   10883              : static const char *
   10884        31401 : include_spec_function (int argc, const char **argv)
   10885              : {
   10886        31401 :   char *file;
   10887              : 
   10888        31401 :   if (argc != 1)
   10889            0 :     abort ();
   10890              : 
   10891        31401 :   file = find_a_file (&startfile_prefixes, argv[0], true);
   10892        31401 :   read_specs (file ? file : argv[0], false, false);
   10893              : 
   10894        31401 :   return NULL;
   10895              : }
   10896              : 
   10897              : /* %:find-file spec function.  This function replaces its argument by
   10898              :     the file found through find_file, that is the -print-file-name gcc
   10899              :     program option. */
   10900              : static const char *
   10901            0 : find_file_spec_function (int argc, const char **argv)
   10902              : {
   10903            0 :   const char *file;
   10904              : 
   10905            0 :   if (argc != 1)
   10906            0 :     abort ();
   10907              : 
   10908            0 :   file = find_file (argv[0]);
   10909            0 :   return file;
   10910              : }
   10911              : 
   10912              : 
   10913              : /* %:find-plugindir spec function.  This function replaces its argument
   10914              :     by the -iplugindir=<dir> option.  `dir' is found through find_file, that
   10915              :     is the -print-file-name gcc program option. */
   10916              : static const char *
   10917          428 : find_plugindir_spec_function (int argc, const char **argv ATTRIBUTE_UNUSED)
   10918              : {
   10919          428 :   const char *option;
   10920              : 
   10921          428 :   if (argc != 0)
   10922            0 :     abort ();
   10923              : 
   10924          428 :   option = concat ("-iplugindir=", find_file ("plugin"), NULL);
   10925          428 :   return option;
   10926              : }
   10927              : 
   10928              : 
   10929              : /* %:print-asm-header spec function.  Print a banner to say that the
   10930              :    following output is from the assembler.  */
   10931              : 
   10932              : static const char *
   10933            0 : print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
   10934              :                                 const char **argv ATTRIBUTE_UNUSED)
   10935              : {
   10936            0 :   printf (_("Assembler options\n=================\n\n"));
   10937            0 :   printf (_("Use \"-Wa,OPTION\" to pass \"OPTION\" to the assembler.\n\n"));
   10938            0 :   fflush (stdout);
   10939            0 :   return NULL;
   10940              : }
   10941              : 
   10942              : /* Get a random number for -frandom-seed */
   10943              : 
   10944              : static unsigned HOST_WIDE_INT
   10945          636 : get_random_number (void)
   10946              : {
   10947          636 :   unsigned HOST_WIDE_INT ret = 0;
   10948          636 :   int fd;
   10949              : 
   10950          636 :   fd = open ("/dev/urandom", O_RDONLY);
   10951          636 :   if (fd >= 0)
   10952              :     {
   10953          636 :       read (fd, &ret, sizeof (HOST_WIDE_INT));
   10954          636 :       close (fd);
   10955          636 :       if (ret)
   10956              :         return ret;
   10957              :     }
   10958              : 
   10959              :   /* Get some more or less random data.  */
   10960              : #ifdef HAVE_GETTIMEOFDAY
   10961            0 :   {
   10962            0 :     struct timeval tv;
   10963              : 
   10964            0 :     gettimeofday (&tv, NULL);
   10965            0 :     ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
   10966              :   }
   10967              : #else
   10968              :   {
   10969              :     time_t now = time (NULL);
   10970              : 
   10971              :     if (now != (time_t)-1)
   10972              :       ret = (unsigned) now;
   10973              :   }
   10974              : #endif
   10975              : 
   10976            0 :   return ret ^ getpid ();
   10977              : }
   10978              : 
   10979              : /* %:compare-debug-dump-opt spec function.  Save the last argument,
   10980              :    expected to be the last -fdump-final-insns option, or generate a
   10981              :    temporary.  */
   10982              : 
   10983              : static const char *
   10984         1265 : compare_debug_dump_opt_spec_function (int arg,
   10985              :                                       const char **argv ATTRIBUTE_UNUSED)
   10986              : {
   10987         1265 :   char *ret;
   10988         1265 :   char *name;
   10989         1265 :   int which;
   10990         1265 :   static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
   10991              : 
   10992         1265 :   if (arg != 0)
   10993            0 :     fatal_error (input_location,
   10994              :                  "too many arguments to %%:compare-debug-dump-opt");
   10995              : 
   10996         1265 :   do_spec_2 ("%{fdump-final-insns=*:%*}", NULL);
   10997         1265 :   do_spec_1 (" ", 0, NULL);
   10998              : 
   10999         1265 :   if (argbuf.length () > 0
   11000         1265 :       && strcmp (argv[argbuf.length () - 1], ".") != 0)
   11001              :     {
   11002            0 :       if (!compare_debug)
   11003              :         return NULL;
   11004              : 
   11005            0 :       name = xstrdup (argv[argbuf.length () - 1]);
   11006            0 :       ret = NULL;
   11007              :     }
   11008              :   else
   11009              :     {
   11010         1265 :       if (argbuf.length () > 0)
   11011            6 :         do_spec_2 ("%B.gkd", NULL);
   11012         1259 :       else if (!compare_debug)
   11013              :         return NULL;
   11014              :       else
   11015         1259 :         do_spec_2 ("%{!save-temps*:%g.gkd}%{save-temps*:%B.gkd}", NULL);
   11016              : 
   11017         1265 :       do_spec_1 (" ", 0, NULL);
   11018              : 
   11019         1265 :       gcc_assert (argbuf.length () > 0);
   11020              : 
   11021         1265 :       name = xstrdup (argbuf.last ());
   11022              : 
   11023         1265 :       char *arg = quote_spec (xstrdup (name));
   11024         1265 :       ret = concat ("-fdump-final-insns=", arg, NULL);
   11025         1265 :       free (arg);
   11026              :     }
   11027              : 
   11028         1265 :   which = compare_debug < 0;
   11029         1265 :   debug_check_temp_file[which] = name;
   11030              : 
   11031         1265 :   if (!which)
   11032              :     {
   11033          636 :       unsigned HOST_WIDE_INT value = get_random_number ();
   11034              : 
   11035          636 :       sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
   11036              :     }
   11037              : 
   11038         1265 :   if (*random_seed)
   11039              :     {
   11040         1265 :       char *tmp = ret;
   11041         1265 :       ret = concat ("%{!frandom-seed=*:-frandom-seed=", random_seed, "} ",
   11042              :                     ret, NULL);
   11043         1265 :       free (tmp);
   11044              :     }
   11045              : 
   11046         1265 :   if (which)
   11047          629 :     *random_seed = 0;
   11048              : 
   11049              :   return ret;
   11050              : }
   11051              : 
   11052              : /* %:compare-debug-self-opt spec function.  Expands to the options
   11053              :     that are to be passed in the second compilation of
   11054              :     compare-debug.  */
   11055              : 
   11056              : static const char *
   11057         1270 : compare_debug_self_opt_spec_function (int arg,
   11058              :                                       const char **argv ATTRIBUTE_UNUSED)
   11059              : {
   11060         1270 :   if (arg != 0)
   11061            0 :     fatal_error (input_location,
   11062              :                  "too many arguments to %%:compare-debug-self-opt");
   11063              : 
   11064         1270 :   if (compare_debug >= 0)
   11065              :     return NULL;
   11066              : 
   11067          635 :   return concat ("\
   11068              : %<o %<MD %<MMD %<MF* %<MG %<MP %<MQ* %<MT* \
   11069              : %<fdump-final-insns=* -w -S -o %j \
   11070              : %{!fcompare-debug-second:-fcompare-debug-second} \
   11071          635 : ", compare_debug_opt, NULL);
   11072              : }
   11073              : 
   11074              : /* %:pass-through-libs spec function.  Finds all -l options and input
   11075              :    file names in the lib spec passed to it, and makes a list of them
   11076              :    prepended with the plugin option to cause them to be passed through
   11077              :    to the final link after all the new object files have been added.  */
   11078              : 
   11079              : const char *
   11080        90524 : pass_through_libs_spec_func (int argc, const char **argv)
   11081              : {
   11082        90524 :   char *prepended = xstrdup (" ");
   11083        90524 :   int n;
   11084              :   /* Shlemiel the painter's algorithm.  Innately horrible, but at least
   11085              :      we know that there will never be more than a handful of strings to
   11086              :      concat, and it's only once per run, so it's not worth optimising.  */
   11087       725821 :   for (n = 0; n < argc; n++)
   11088              :     {
   11089       635297 :       char *old = prepended;
   11090              :       /* Anything that isn't an option is a full path to an output
   11091              :          file; pass it through if it ends in '.a'.  Among options,
   11092              :          pass only -l.  */
   11093       635297 :       if (argv[n][0] == '-' && argv[n][1] == 'l')
   11094              :         {
   11095       592193 :           const char *lopt = argv[n] + 2;
   11096              :           /* Handle both joined and non-joined -l options.  If for any
   11097              :              reason there's a trailing -l with no joined or following
   11098              :              arg just discard it.  */
   11099       592193 :           if (!*lopt && ++n >= argc)
   11100              :             break;
   11101       592193 :           else if (!*lopt)
   11102            0 :             lopt = argv[n];
   11103       592193 :           prepended = concat (prepended, "-plugin-opt=-pass-through=-l",
   11104              :                 lopt, " ", NULL);
   11105       592193 :         }
   11106        43104 :       else if (!strcmp (".a", argv[n] + strlen (argv[n]) - 2))
   11107              :         {
   11108            0 :           prepended = concat (prepended, "-plugin-opt=-pass-through=",
   11109              :                 argv[n], " ", NULL);
   11110              :         }
   11111       635297 :       if (prepended != old)
   11112       592193 :         free (old);
   11113              :     }
   11114        90524 :   return prepended;
   11115              : }
   11116              : 
   11117              : static bool
   11118       527539 : not_actual_file_p (const char *name)
   11119              : {
   11120       527539 :   return (strcmp (name, "-") == 0
   11121       527539 :           || strcmp (name, HOST_BIT_BUCKET) == 0);
   11122              : }
   11123              : 
   11124              : /* %:dumps spec function.  Take an optional argument that overrides
   11125              :    the default extension for -dumpbase and -dumpbase-ext.
   11126              :    Return -dumpdir, -dumpbase and -dumpbase-ext, if needed.  */
   11127              : const char *
   11128       287312 : dumps_spec_func (int argc, const char **argv ATTRIBUTE_UNUSED)
   11129              : {
   11130       287312 :   const char *ext = dumpbase_ext;
   11131       287312 :   char *p;
   11132              : 
   11133       287312 :   char *args[3] = { NULL, NULL, NULL };
   11134       287312 :   int nargs = 0;
   11135              : 
   11136              :   /* Do not compute a default for -dumpbase-ext when -dumpbase was
   11137              :      given explicitly.  */
   11138       287312 :   if (dumpbase && *dumpbase && !ext)
   11139       287312 :     ext = "";
   11140              : 
   11141       287312 :   if (argc == 1)
   11142              :     {
   11143              :       /* Do not override the explicitly-specified -dumpbase-ext with
   11144              :          the specs-provided overrider.  */
   11145            0 :       if (!ext)
   11146            0 :         ext = argv[0];
   11147              :     }
   11148       287312 :   else if (argc != 0)
   11149            0 :     fatal_error (input_location, "too many arguments for %%:dumps");
   11150              : 
   11151       287312 :   if (dumpdir)
   11152              :     {
   11153       107530 :       p = quote_spec_arg (xstrdup (dumpdir));
   11154       107530 :       args[nargs++] = concat (" -dumpdir ", p, NULL);
   11155       107530 :       free (p);
   11156              :     }
   11157              : 
   11158       287312 :   if (!ext)
   11159       267107 :     ext = input_basename + basename_length;
   11160              : 
   11161              :   /* Use the precomputed outbase, or compute dumpbase from
   11162              :      input_basename, just like %b would.  */
   11163       287312 :   char *base;
   11164              : 
   11165       287312 :   if (dumpbase && *dumpbase)
   11166              :     {
   11167        20205 :       base = xstrdup (dumpbase);
   11168        20205 :       p = base + outbase_length;
   11169        20205 :       gcc_checking_assert (strncmp (base, outbase, outbase_length) == 0);
   11170        20205 :       gcc_checking_assert (strcmp (p, ext) == 0);
   11171              :     }
   11172       267107 :   else if (outbase_length)
   11173              :     {
   11174       166726 :       base = xstrndup (outbase, outbase_length);
   11175       166726 :       p = NULL;
   11176              :     }
   11177              :   else
   11178              :     {
   11179       100381 :       base = xstrndup (input_basename, suffixed_basename_length);
   11180       100381 :       p = base + basename_length;
   11181              :     }
   11182              : 
   11183       287312 :   if (compare_debug < 0 || !p || strcmp (p, ext) != 0)
   11184              :     {
   11185          629 :       if (p)
   11186            9 :         *p = '\0';
   11187              : 
   11188       166735 :       const char *gk;
   11189       166735 :       if (compare_debug < 0)
   11190              :         gk = ".gk";
   11191              :       else
   11192       166106 :         gk = "";
   11193              : 
   11194       166735 :       p = concat (base, gk, ext, NULL);
   11195              : 
   11196       166735 :       free (base);
   11197       166735 :       base = p;
   11198              :     }
   11199              : 
   11200       287312 :   base = quote_spec_arg (base);
   11201       287312 :   args[nargs++] = concat (" -dumpbase ", base, NULL);
   11202       287312 :   free (base);
   11203              : 
   11204       287312 :   if (*ext)
   11205              :     {
   11206       266066 :       p = quote_spec_arg (xstrdup (ext));
   11207       266066 :       args[nargs++] = concat (" -dumpbase-ext ", p, NULL);
   11208       266066 :       free (p);
   11209              :     }
   11210              : 
   11211       287312 :   const char *ret = concat (args[0], args[1], args[2], NULL);
   11212      1235532 :   while (nargs > 0)
   11213       660908 :     free (args[--nargs]);
   11214              : 
   11215       287312 :   return ret;
   11216              : }
   11217              : 
   11218              : /* Returns "" if ARGV[ARGC - 2] is greater than ARGV[ARGC-1].
   11219              :    Otherwise, return NULL.  */
   11220              : 
   11221              : static const char *
   11222       400114 : greater_than_spec_func (int argc, const char **argv)
   11223              : {
   11224       400114 :   char *converted;
   11225              : 
   11226       400114 :   if (argc == 1)
   11227              :     return NULL;
   11228              : 
   11229          252 :   gcc_assert (argc >= 2);
   11230              : 
   11231          252 :   long arg = strtol (argv[argc - 2], &converted, 10);
   11232          252 :   gcc_assert (converted != argv[argc - 2]);
   11233              : 
   11234          252 :   long lim = strtol (argv[argc - 1], &converted, 10);
   11235          252 :   gcc_assert (converted != argv[argc - 1]);
   11236              : 
   11237          252 :   if (arg > lim)
   11238              :     return "";
   11239              : 
   11240              :   return NULL;
   11241              : }
   11242              : 
   11243              : /* Returns "" if debug_info_level is greater than ARGV[ARGC-1].
   11244              :    Otherwise, return NULL.  */
   11245              : 
   11246              : static const char *
   11247       256228 : debug_level_greater_than_spec_func (int argc, const char **argv)
   11248              : {
   11249       256228 :   char *converted;
   11250              : 
   11251       256228 :   if (argc != 1)
   11252            0 :     fatal_error (input_location,
   11253              :                  "wrong number of arguments to %%:debug-level-gt");
   11254              : 
   11255       256228 :   long arg = strtol (argv[0], &converted, 10);
   11256       256228 :   gcc_assert (converted != argv[0]);
   11257              : 
   11258       256228 :   if (debug_info_level > arg)
   11259        45924 :     return "";
   11260              : 
   11261              :   return NULL;
   11262              : }
   11263              : 
   11264              : /* Returns "" if dwarf_version is greater than ARGV[ARGC-1].
   11265              :    Otherwise, return NULL.  */
   11266              : 
   11267              : static const char *
   11268       130122 : dwarf_version_greater_than_spec_func (int argc, const char **argv)
   11269              : {
   11270       130122 :   char *converted;
   11271              : 
   11272       130122 :   if (argc != 1)
   11273            0 :     fatal_error (input_location,
   11274              :                  "wrong number of arguments to %%:dwarf-version-gt");
   11275              : 
   11276       130122 :   long arg = strtol (argv[0], &converted, 10);
   11277       130122 :   gcc_assert (converted != argv[0]);
   11278              : 
   11279       130122 :   if (dwarf_version > arg)
   11280       129251 :     return "";
   11281              : 
   11282              :   return NULL;
   11283              : }
   11284              : 
   11285              : static void
   11286        35292 : path_prefix_reset (path_prefix *prefix)
   11287              : {
   11288        35292 :   struct prefix_list *iter, *next;
   11289        35292 :   iter = prefix->plist;
   11290       140024 :   while (iter)
   11291              :     {
   11292       104732 :       next = iter->next;
   11293       104732 :       free (const_cast <char *> (iter->prefix));
   11294       104732 :       XDELETE (iter);
   11295       104732 :       iter = next;
   11296              :     }
   11297        35292 :   prefix->plist = 0;
   11298        35292 :   prefix->max_len = 0;
   11299        35292 : }
   11300              : 
   11301              : /* The function takes 3 arguments: OPTION name, file name and location
   11302              :    where we search for Fortran modules.
   11303              :    When the FILE is found by find_file, return OPTION=path_to_file.  */
   11304              : 
   11305              : static const char *
   11306        31860 : find_fortran_preinclude_file (int argc, const char **argv)
   11307              : {
   11308        31860 :   char *result = NULL;
   11309        31860 :   if (argc != 3)
   11310              :     return NULL;
   11311              : 
   11312        31860 :   struct path_prefix prefixes = { 0, 0, "preinclude" };
   11313              : 
   11314              :   /* Search first for 'finclude' folder location for a header file
   11315              :      installed by the compiler (similar to omp_lib.h).  */
   11316        31860 :   add_prefix (&prefixes, argv[2], NULL, 0, 0, 0);
   11317              : #ifdef TOOL_INCLUDE_DIR
   11318              :   /* Then search: <prefix>/<target>/<include>/finclude */
   11319        31860 :   add_prefix (&prefixes, TOOL_INCLUDE_DIR "/finclude/",
   11320              :               NULL, 0, 0, 0);
   11321              : #endif
   11322              : #ifdef NATIVE_SYSTEM_HEADER_DIR
   11323              :   /* Then search: <sysroot>/usr/include/finclude/<multilib> */
   11324        31860 :   add_sysrooted_hdrs_prefix (&prefixes, NATIVE_SYSTEM_HEADER_DIR "/finclude/",
   11325              :                              NULL, 0, 0, 0);
   11326              : #endif
   11327              : 
   11328        31860 :   const char *path = find_a_file (&include_prefixes, argv[1], false);
   11329        31860 :   if (path != NULL)
   11330            0 :     result = concat (argv[0], path, NULL);
   11331              :   else
   11332              :     {
   11333        31860 :       path = find_a_file (&prefixes, argv[1], false);
   11334        31860 :       if (path != NULL)
   11335        31860 :         result = concat (argv[0], path, NULL);
   11336              :     }
   11337              : 
   11338        31860 :   path_prefix_reset (&prefixes);
   11339        31860 :   return result;
   11340              : }
   11341              : 
   11342              : /* The function takes any number of arguments and joins them together,
   11343              :    escaping any special characters.
   11344              : 
   11345              :    This seems to be necessary to build "-fjoined=foo.b" from "-fseparate foo.a"
   11346              :    with a %{fseparate*:-fjoined=%.b$*} rule without adding undesired spaces:
   11347              :    when doing $* replacement we first replace $* with the rest of the switch
   11348              :    (in this case ""), and then add any arguments as arguments after the result,
   11349              :    resulting in "-fjoined= foo.b".  Using this function with e.g.
   11350              :    %{fseparate*:-fjoined=%:join(%.b$*)} gets multiple words as separate argv
   11351              :    elements instead of separated by spaces, and we paste them together.  */
   11352              : 
   11353              : static const char *
   11354           39 : join_spec_func (int argc, const char **argv)
   11355              : {
   11356           39 :   const char *result = argv[0];
   11357           39 :   if (argc != 1)
   11358              :     {
   11359          117 :       for (int i = 0; i < argc; ++i)
   11360           78 :         obstack_grow (&obstack, argv[i], strlen (argv[i]));
   11361           39 :       obstack_1grow (&obstack, '\0');
   11362           39 :       result = XOBFINISH (&obstack, const char *);
   11363              :     }
   11364           39 :   return quote_spec (xstrdup (result));
   11365              : }
   11366              : 
   11367              : /* If any character in ORIG fits QUOTE_P (_, P), reallocate the string
   11368              :    so as to precede every one of them with a backslash.  Return the
   11369              :    original string or the reallocated one.  */
   11370              : 
   11371              : static inline char *
   11372       862936 : quote_string (char *orig, bool (*quote_p)(char, void *), void *p)
   11373              : {
   11374       862936 :   int len, number_of_space = 0;
   11375              : 
   11376     19499689 :   for (len = 0; orig[len]; len++)
   11377     18636753 :     if (quote_p (orig[len], p))
   11378            0 :       number_of_space++;
   11379              : 
   11380       862936 :   if (number_of_space)
   11381              :     {
   11382            0 :       char *new_spec = (char *) xmalloc (len + number_of_space + 1);
   11383            0 :       int j, k;
   11384            0 :       for (j = 0, k = 0; j <= len; j++, k++)
   11385              :         {
   11386            0 :           if (quote_p (orig[j], p))
   11387            0 :             new_spec[k++] = '\\';
   11388            0 :           new_spec[k] = orig[j];
   11389              :         }
   11390            0 :       free (orig);
   11391            0 :       return new_spec;
   11392              :     }
   11393              :   else
   11394              :     return orig;
   11395              : }
   11396              : 
   11397              : /* Return true iff C is any of the characters convert_white_space
   11398              :    should quote.  */
   11399              : 
   11400              : static inline bool
   11401     12412805 : whitespace_to_convert_p (char c, void *)
   11402              : {
   11403     12412805 :   return (c == ' ' || c == '\t');
   11404              : }
   11405              : 
   11406              : /* Insert backslash before spaces in ORIG (usually a file path), to
   11407              :    avoid being broken by spec parser.
   11408              : 
   11409              :    This function is needed as do_spec_1 treats white space (' ' and '\t')
   11410              :    as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
   11411              :    the file name should be treated as a single argument rather than being
   11412              :    broken into multiple. Solution is to insert '\\' before the space in a
   11413              :    file name.
   11414              : 
   11415              :    This function converts and only converts all occurrence of ' '
   11416              :    to '\\' + ' ' and '\t' to '\\' + '\t'.  For example:
   11417              :    "a b"  -> "a\\ b"
   11418              :    "a  b" -> "a\\ \\ b"
   11419              :    "a\tb" -> "a\\\tb"
   11420              :    "a\\ b" -> "a\\\\ b"
   11421              : 
   11422              :    orig: input null-terminating string that was allocated by xalloc. The
   11423              :    memory it points to might be freed in this function. Behavior undefined
   11424              :    if ORIG wasn't xalloced or was freed already at entry.
   11425              : 
   11426              :    Return: ORIG if no conversion needed. Otherwise a newly allocated string
   11427              :    that was converted from ORIG.  */
   11428              : 
   11429              : static char *
   11430       200733 : convert_white_space (char *orig)
   11431              : {
   11432       200733 :   return quote_string (orig, whitespace_to_convert_p, NULL);
   11433              : }
   11434              : 
   11435              : /* Return true iff C matches any of the spec active characters.  */
   11436              : static inline bool
   11437      6223948 : quote_spec_char_p (char c, void *)
   11438              : {
   11439      6223948 :   switch (c)
   11440              :     {
   11441              :     case ' ':
   11442              :     case '\t':
   11443              :     case '\n':
   11444              :     case '|':
   11445              :     case '%':
   11446              :     case '\\':
   11447              :       return true;
   11448              : 
   11449      6223948 :     default:
   11450      6223948 :       return false;
   11451              :     }
   11452              : }
   11453              : 
   11454              : /* Like convert_white_space, but deactivate all active spec chars by
   11455              :    quoting them.  */
   11456              : 
   11457              : static inline char *
   11458       662203 : quote_spec (char *orig)
   11459              : {
   11460         1304 :   return quote_string (orig, quote_spec_char_p, NULL);
   11461              : }
   11462              : 
   11463              : /* Like quote_spec, but also turn an empty string into the spec for an
   11464              :    empty argument.  */
   11465              : 
   11466              : static inline char *
   11467       660908 : quote_spec_arg (char *orig)
   11468              : {
   11469       660908 :   if (!*orig)
   11470              :     {
   11471            9 :       free (orig);
   11472            9 :       return xstrdup ("%\"");
   11473              :     }
   11474              : 
   11475       660899 :   return quote_spec (orig);
   11476              : }
   11477              : 
   11478              : /* Restore all state within gcc.cc to the initial state, so that the driver
   11479              :    code can be safely re-run in-process.
   11480              : 
   11481              :    Many const char * variables are referenced by static specs (see
   11482              :    INIT_STATIC_SPEC above).  These variables are restored to their default
   11483              :    values by a simple loop over the static specs.
   11484              : 
   11485              :    For other variables, we directly restore them all to their initial
   11486              :    values (often implicitly 0).
   11487              : 
   11488              :    Free the various obstacks in this file, along with "opts_obstack"
   11489              :    from opts.cc.
   11490              : 
   11491              :    This function also restores any environment variables that were changed.  */
   11492              : 
   11493              : void
   11494         1144 : driver::finalize ()
   11495              : {
   11496         1144 :   env.restore ();
   11497         1144 :   diagnostic_finish (global_dc);
   11498              : 
   11499         1144 :   is_cpp_driver = 0;
   11500         1144 :   at_file_supplied = 0;
   11501         1144 :   print_help_list = 0;
   11502         1144 :   print_version = 0;
   11503         1144 :   verbose_only_flag = 0;
   11504         1144 :   print_subprocess_help = 0;
   11505         1144 :   use_ld = NULL;
   11506         1144 :   report_times_to_file = NULL;
   11507         1144 :   target_system_root = DEFAULT_TARGET_SYSTEM_ROOT;
   11508         1144 :   target_system_root_changed = 0;
   11509         1144 :   target_sysroot_suffix = 0;
   11510         1144 :   target_sysroot_hdrs_suffix = 0;
   11511         1144 :   save_temps_flag = SAVE_TEMPS_NONE;
   11512         1144 :   save_temps_overrides_dumpdir = false;
   11513         1144 :   dumpdir_trailing_dash_added = false;
   11514         1144 :   free (dumpdir);
   11515         1144 :   free (dumpbase);
   11516         1144 :   free (dumpbase_ext);
   11517         1144 :   free (outbase);
   11518         1144 :   dumpdir = dumpbase = dumpbase_ext = outbase = NULL;
   11519         1144 :   dumpdir_length = outbase_length = 0;
   11520         1144 :   spec_machine = DEFAULT_TARGET_MACHINE;
   11521         1144 :   greatest_status = 1;
   11522              : 
   11523         1144 :   obstack_free (&obstack, NULL);
   11524         1144 :   obstack_free (&opts_obstack, NULL); /* in opts.cc */
   11525         1144 :   obstack_free (&collect_obstack, NULL);
   11526              : 
   11527         1144 :   link_command_spec = LINK_COMMAND_SPEC;
   11528              : 
   11529         1144 :   obstack_free (&multilib_obstack, NULL);
   11530              : 
   11531         1144 :   user_specs_head = NULL;
   11532         1144 :   user_specs_tail = NULL;
   11533              : 
   11534              :   /* Within the "compilers" vec, the fields "suffix" and "spec" were
   11535              :      statically allocated for the default compilers, but dynamically
   11536              :      allocated for additional compilers.  Delete them for the latter. */
   11537         1144 :   for (int i = n_default_compilers; i < n_compilers; i++)
   11538              :     {
   11539            0 :       free (const_cast <char *> (compilers[i].suffix));
   11540            0 :       free (const_cast <char *> (compilers[i].spec));
   11541              :     }
   11542         1144 :   XDELETEVEC (compilers);
   11543         1144 :   compilers = NULL;
   11544         1144 :   n_compilers = 0;
   11545              : 
   11546         1144 :   linker_options.truncate (0);
   11547         1144 :   assembler_options.truncate (0);
   11548         1144 :   preprocessor_options.truncate (0);
   11549              : 
   11550         1144 :   path_prefix_reset (&exec_prefixes);
   11551         1144 :   path_prefix_reset (&startfile_prefixes);
   11552         1144 :   path_prefix_reset (&include_prefixes);
   11553              : 
   11554         1144 :   machine_suffix = 0;
   11555         1144 :   just_machine_suffix = 0;
   11556         1144 :   gcc_exec_prefix = 0;
   11557         1144 :   gcc_libexec_prefix = 0;
   11558         1144 :   set_static_spec_shared (&md_exec_prefix, MD_EXEC_PREFIX);
   11559         1144 :   set_static_spec_shared (&md_startfile_prefix, MD_STARTFILE_PREFIX);
   11560         1144 :   set_static_spec_shared (&md_startfile_prefix_1, MD_STARTFILE_PREFIX_1);
   11561         1144 :   multilib_dir = 0;
   11562         1144 :   multilib_os_dir = 0;
   11563         1144 :   multiarch_dir = 0;
   11564              : 
   11565              :   /* Free any specs dynamically-allocated by set_spec.
   11566              :      These will be at the head of the list, before the
   11567              :      statically-allocated ones.  */
   11568         1144 :   if (specs)
   11569              :     {
   11570         2288 :       while (specs != static_specs)
   11571              :         {
   11572         1144 :           spec_list *next = specs->next;
   11573         1144 :           free (const_cast <char *> (specs->name));
   11574         1144 :           XDELETE (specs);
   11575         1144 :           specs = next;
   11576              :         }
   11577         1144 :       specs = 0;
   11578              :     }
   11579        52624 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
   11580              :     {
   11581        51480 :       spec_list *sl = &static_specs[i];
   11582        51480 :       if (sl->alloc_p)
   11583              :         {
   11584        45770 :           free (const_cast <char *> (*(sl->ptr_spec)));
   11585        45770 :           sl->alloc_p = false;
   11586              :         }
   11587        51480 :       *(sl->ptr_spec) = sl->default_ptr;
   11588              :     }
   11589              : #ifdef EXTRA_SPECS
   11590         1144 :   extra_specs = NULL;
   11591              : #endif
   11592              : 
   11593         1144 :   processing_spec_function = 0;
   11594              : 
   11595         1144 :   clear_args ();
   11596              : 
   11597         1144 :   have_c = 0;
   11598         1144 :   have_o = 0;
   11599              : 
   11600         1144 :   temp_names = NULL;
   11601         1144 :   execution_count = 0;
   11602         1144 :   signal_count = 0;
   11603              : 
   11604         1144 :   temp_filename = NULL;
   11605         1144 :   temp_filename_length = 0;
   11606         1144 :   always_delete_queue = NULL;
   11607         1144 :   failure_delete_queue = NULL;
   11608              : 
   11609         1144 :   XDELETEVEC (switches);
   11610         1144 :   switches = NULL;
   11611         1144 :   n_switches = 0;
   11612         1144 :   n_switches_alloc = 0;
   11613              : 
   11614         1144 :   compare_debug = 0;
   11615         1144 :   compare_debug_second = 0;
   11616         1144 :   compare_debug_opt = NULL;
   11617         3432 :   for (int i = 0; i < 2; i++)
   11618              :     {
   11619         2288 :       switches_debug_check[i] = NULL;
   11620         2288 :       n_switches_debug_check[i] = 0;
   11621         2288 :       n_switches_alloc_debug_check[i] = 0;
   11622         2288 :       debug_check_temp_file[i] = NULL;
   11623              :     }
   11624              : 
   11625         1144 :   XDELETEVEC (infiles);
   11626         1144 :   infiles = NULL;
   11627         1144 :   n_infiles = 0;
   11628         1144 :   n_infiles_alloc = 0;
   11629              : 
   11630         1144 :   combine_inputs = false;
   11631         1144 :   added_libraries = 0;
   11632         1144 :   XDELETEVEC (outfiles);
   11633         1144 :   outfiles = NULL;
   11634         1144 :   spec_lang = 0;
   11635         1144 :   last_language_n_infiles = 0;
   11636         1144 :   gcc_input_filename = NULL;
   11637         1144 :   input_file_number = 0;
   11638         1144 :   input_filename_length = 0;
   11639         1144 :   basename_length = 0;
   11640         1144 :   suffixed_basename_length = 0;
   11641         1144 :   input_basename = NULL;
   11642         1144 :   input_suffix = NULL;
   11643              :   /* We don't need to purge "input_stat", just to unset "input_stat_set".  */
   11644         1144 :   input_stat_set = 0;
   11645         1144 :   input_file_compiler = NULL;
   11646         1144 :   arg_going = 0;
   11647         1144 :   delete_this_arg = 0;
   11648         1144 :   this_is_output_file = 0;
   11649         1144 :   this_is_library_file = 0;
   11650         1144 :   this_is_linker_script = 0;
   11651         1144 :   input_from_pipe = 0;
   11652         1144 :   suffix_subst = NULL;
   11653              : 
   11654         1144 :   XDELETEVEC (mdswitches);
   11655         1144 :   mdswitches = NULL;
   11656         1144 :   n_mdswitches = 0;
   11657              : 
   11658         1144 :   used_arg.finalize ();
   11659         1144 : }
   11660              : 
   11661              : /* PR jit/64810.
   11662              :    Targets can provide configure-time default options in
   11663              :    OPTION_DEFAULT_SPECS.  The jit needs to access these, but
   11664              :    they are expressed in the spec language.
   11665              : 
   11666              :    Run just enough of the driver to be able to expand these
   11667              :    specs, and then call the callback CB on each
   11668              :    such option.  The options strings are *without* a leading
   11669              :    '-' character e.g. ("march=x86-64").  Finally, clean up.  */
   11670              : 
   11671              : void
   11672          132 : driver_get_configure_time_options (void (*cb) (const char *option,
   11673              :                                                void *user_data),
   11674              :                                    void *user_data)
   11675              : {
   11676          132 :   size_t i;
   11677              : 
   11678          132 :   obstack_init (&obstack);
   11679          132 :   init_opts_obstack ();
   11680          132 :   n_switches = 0;
   11681              : 
   11682         1452 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
   11683         1320 :     do_option_spec (option_default_specs[i].name,
   11684         1320 :                     option_default_specs[i].spec);
   11685              : 
   11686          396 :   for (i = 0; (int) i < n_switches; i++)
   11687              :     {
   11688          264 :       gcc_assert (switches[i].part1);
   11689          264 :       (*cb) (switches[i].part1, user_data);
   11690              :     }
   11691              : 
   11692          132 :   obstack_free (&opts_obstack, NULL);
   11693          132 :   obstack_free (&obstack, NULL);
   11694          132 :   n_switches = 0;
   11695          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.