LCOV - code coverage report
Current view: top level - gcc - gcc.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 74.2 % 4381 3249
Test Date: 2026-02-28 14:20:25 Functions: 85.4 % 158 135
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              : 
      58              : #ifndef MATH_LIBRARY
      59              : #define MATH_LIBRARY "m"
      60              : #endif
      61              : 
      62              : 
      63              : /* Manage the manipulation of env vars.
      64              : 
      65              :    We poison "getenv" and "putenv", so that all enviroment-handling is
      66              :    done through this class.  Note that poisoning happens in the
      67              :    preprocessor at the identifier level, and doesn't distinguish between
      68              :      env.getenv ();
      69              :    and
      70              :      getenv ();
      71              :    Hence we need to use "get" for the accessor method, not "getenv".  */
      72              : 
      73              : struct env_manager
      74              : {
      75              :  public:
      76              :   void init (bool can_restore, bool debug);
      77              :   const char *get (const char *name);
      78              :   void xput (const char *string);
      79              :   void restore ();
      80              : 
      81              :  private:
      82              :   bool m_can_restore;
      83              :   bool m_debug;
      84              :   struct kv
      85              :   {
      86              :     char *m_key;
      87              :     char *m_value;
      88              :   };
      89              :   vec<kv> m_keys;
      90              : 
      91              : };
      92              : 
      93              : /* The singleton instance of class env_manager.  */
      94              : 
      95              : static env_manager env;
      96              : 
      97              : /* Initializer for class env_manager.
      98              : 
      99              :    We can't do this as a constructor since we have a statically
     100              :    allocated instance ("env" above).  */
     101              : 
     102              : void
     103       293985 : env_manager::init (bool can_restore, bool debug)
     104              : {
     105       293985 :   m_can_restore = can_restore;
     106       293985 :   m_debug = debug;
     107       293985 : }
     108              : 
     109              : /* Get the value of NAME within the environment.  Essentially
     110              :    a wrapper for ::getenv, but adding logging, and the possibility
     111              :    of caching results.  */
     112              : 
     113              : const char *
     114      1469008 : env_manager::get (const char *name)
     115              : {
     116      1469008 :   const char *result = ::getenv (name);
     117      1469008 :   if (m_debug)
     118            0 :     fprintf (stderr, "env_manager::getenv (%s) -> %s\n", name, result);
     119      1469008 :   return result;
     120              : }
     121              : 
     122              : /* Put the given KEY=VALUE entry STRING into the environment.
     123              :    If the env_manager was initialized with CAN_RESTORE set, then
     124              :    also record the old value of KEY within the environment, so that it
     125              :    can be later restored.  */
     126              : 
     127              : void
     128      1745427 : env_manager::xput (const char *string)
     129              : {
     130      1745427 :   if (m_debug)
     131            0 :     fprintf (stderr, "env_manager::xput (%s)\n", string);
     132      1745427 :   if (verbose_flag)
     133         6184 :     fnotice (stderr, "%s\n", string);
     134              : 
     135      1745427 :   if (m_can_restore)
     136              :     {
     137         6799 :       char *equals = strchr (const_cast <char *> (string), '=');
     138         6799 :       gcc_assert (equals);
     139              : 
     140         6799 :       struct kv kv;
     141         6799 :       kv.m_key = xstrndup (string, equals - string);
     142         6799 :       const char *cur_value = ::getenv (kv.m_key);
     143         6799 :       if (m_debug)
     144            0 :         fprintf (stderr, "saving old value: %s\n",cur_value);
     145         6799 :       kv.m_value = cur_value ? xstrdup (cur_value) : NULL;
     146         6799 :       m_keys.safe_push (kv);
     147              :     }
     148              : 
     149      1745427 :   ::putenv (const_cast<char *> (string));
     150      1745427 : }
     151              : 
     152              : /* Undo any xputenv changes made since last restore.
     153              :    Can only be called if the env_manager was initialized with
     154              :    CAN_RESTORE enabled.  */
     155              : 
     156              : void
     157         1134 : env_manager::restore ()
     158              : {
     159         1134 :   unsigned int i;
     160         1134 :   struct kv *item;
     161              : 
     162         1134 :   gcc_assert (m_can_restore);
     163              : 
     164         9067 :   FOR_EACH_VEC_ELT_REVERSE (m_keys, i, item)
     165              :     {
     166         6799 :       if (m_debug)
     167            0 :         printf ("restoring saved key: %s value: %s\n", item->m_key, item->m_value);
     168         6799 :       if (item->m_value)
     169         3397 :         ::setenv (item->m_key, item->m_value, 1);
     170              :       else
     171         3402 :         ::unsetenv (item->m_key);
     172         6799 :       free (item->m_key);
     173         6799 :       free (item->m_value);
     174              :     }
     175              : 
     176         1134 :   m_keys.truncate (0);
     177         1134 : }
     178              : 
     179              : /* Forbid other uses of getenv and putenv.  */
     180              : #if (GCC_VERSION >= 3000)
     181              : #pragma GCC poison getenv putenv
     182              : #endif
     183              : 
     184              : 
     185              : 
     186              : /* By default there is no special suffix for target executables.  */
     187              : #ifdef TARGET_EXECUTABLE_SUFFIX
     188              : #define HAVE_TARGET_EXECUTABLE_SUFFIX
     189              : #else
     190              : #define TARGET_EXECUTABLE_SUFFIX ""
     191              : #endif
     192              : 
     193              : /* By default there is no special suffix for host executables.  */
     194              : #ifdef HOST_EXECUTABLE_SUFFIX
     195              : #define HAVE_HOST_EXECUTABLE_SUFFIX
     196              : #else
     197              : #define HOST_EXECUTABLE_SUFFIX ""
     198              : #endif
     199              : 
     200              : /* By default, the suffix for target object files is ".o".  */
     201              : #ifdef TARGET_OBJECT_SUFFIX
     202              : #define HAVE_TARGET_OBJECT_SUFFIX
     203              : #else
     204              : #define TARGET_OBJECT_SUFFIX ".o"
     205              : #endif
     206              : 
     207              : static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
     208              : 
     209              : /* Most every one is fine with LIBRARY_PATH.  For some, it conflicts.  */
     210              : #ifndef LIBRARY_PATH_ENV
     211              : #define LIBRARY_PATH_ENV "LIBRARY_PATH"
     212              : #endif
     213              : 
     214              : /* If a stage of compilation returns an exit status >= 1,
     215              :    compilation of that file ceases.  */
     216              : 
     217              : #define MIN_FATAL_STATUS 1
     218              : 
     219              : /* Flag set by cppspec.cc to 1.  */
     220              : int is_cpp_driver;
     221              : 
     222              : /* Flag set to nonzero if an @file argument has been supplied to gcc.  */
     223              : static bool at_file_supplied;
     224              : 
     225              : /* Definition of string containing the arguments given to configure.  */
     226              : #include "configargs.h"
     227              : 
     228              : /* Flag saying to print the command line options understood by gcc and its
     229              :    sub-processes.  */
     230              : 
     231              : static int print_help_list;
     232              : 
     233              : /* Flag saying to print the version of gcc and its sub-processes.  */
     234              : 
     235              : static int print_version;
     236              : 
     237              : /* Flag that stores string prefix for which we provide bash completion.  */
     238              : 
     239              : static const char *completion = NULL;
     240              : 
     241              : /* Flag indicating whether we should ONLY print the command and
     242              :    arguments (like verbose_flag) without executing the command.
     243              :    Displayed arguments are quoted so that the generated command
     244              :    line is suitable for execution.  This is intended for use in
     245              :    shell scripts to capture the driver-generated command line.  */
     246              : static int verbose_only_flag;
     247              : 
     248              : /* Flag indicating how to print command line options of sub-processes.  */
     249              : 
     250              : static int print_subprocess_help;
     251              : 
     252              : /* Linker suffix passed to -fuse-ld=... */
     253              : static const char *use_ld;
     254              : 
     255              : /* Whether we should report subprocess execution times to a file.  */
     256              : 
     257              : FILE *report_times_to_file = NULL;
     258              : 
     259              : /* Nonzero means place this string before uses of /, so that include
     260              :    and library files can be found in an alternate location.  */
     261              : 
     262              : #ifdef TARGET_SYSTEM_ROOT
     263              : #define DEFAULT_TARGET_SYSTEM_ROOT (TARGET_SYSTEM_ROOT)
     264              : #else
     265              : #define DEFAULT_TARGET_SYSTEM_ROOT (0)
     266              : #endif
     267              : static const char *target_system_root = DEFAULT_TARGET_SYSTEM_ROOT;
     268              : 
     269              : /* Nonzero means pass the updated target_system_root to the compiler.  */
     270              : 
     271              : static int target_system_root_changed;
     272              : 
     273              : /* Nonzero means append this string to target_system_root.  */
     274              : 
     275              : static const char *target_sysroot_suffix = 0;
     276              : 
     277              : /* Nonzero means append this string to target_system_root for headers.  */
     278              : 
     279              : static const char *target_sysroot_hdrs_suffix = 0;
     280              : 
     281              : /* Nonzero means write "temp" files in source directory
     282              :    and use the source file's name in them, and don't delete them.  */
     283              : 
     284              : static enum save_temps {
     285              :   SAVE_TEMPS_NONE,              /* no -save-temps */
     286              :   SAVE_TEMPS_CWD,               /* -save-temps in current directory */
     287              :   SAVE_TEMPS_DUMP,              /* -save-temps in dumpdir */
     288              :   SAVE_TEMPS_OBJ                /* -save-temps in object directory */
     289              : } save_temps_flag;
     290              : 
     291              : /* Set this iff the dumppfx implied by a -save-temps=* option is to
     292              :    override a -dumpdir option, if any.  */
     293              : static bool save_temps_overrides_dumpdir = false;
     294              : 
     295              : /* -dumpdir, -dumpbase and -dumpbase-ext flags passed in, possibly
     296              :    rearranged as they are to be passed down, e.g., dumpbase and
     297              :    dumpbase_ext may be cleared if integrated with dumpdir or
     298              :    dropped.  */
     299              : static char *dumpdir, *dumpbase, *dumpbase_ext;
     300              : 
     301              : /* Usually the length of the string in dumpdir.  However, during
     302              :    linking, it may be shortened to omit a driver-added trailing dash,
     303              :    by then replaced with a trailing period, that is still to be passed
     304              :    to sub-processes in -dumpdir, but not to be generally used in spec
     305              :    filename expansions.  See maybe_run_linker.  */
     306              : static size_t dumpdir_length = 0;
     307              : 
     308              : /* Set if the last character in dumpdir is (or was) a dash that the
     309              :    driver added to dumpdir after dumpbase or linker output name.  */
     310              : static bool dumpdir_trailing_dash_added = false;
     311              : 
     312              : /* True if -r, -shared, -pie, -no-pie, -z lazy, or -z norelro were
     313              :    specified on the command line, and therefore -fhardened should not
     314              :    add -z now/relro.  */
     315              : static bool avoid_linker_hardening_p;
     316              : 
     317              : /* True if -static was specified on the command line.  */
     318              : static bool static_p;
     319              : 
     320              : /* Basename of dump and aux outputs, computed from dumpbase (given or
     321              :    derived from output name), to override input_basename in non-%w %b
     322              :    et al.  */
     323              : static char *outbase;
     324              : static size_t outbase_length = 0;
     325              : 
     326              : /* The compiler version.  */
     327              : 
     328              : static const char *compiler_version;
     329              : 
     330              : /* The target version.  */
     331              : 
     332              : static const char *const spec_version = DEFAULT_TARGET_VERSION;
     333              : 
     334              : /* The target machine.  */
     335              : 
     336              : static const char *spec_machine = DEFAULT_TARGET_MACHINE;
     337              : static const char *spec_host_machine = DEFAULT_REAL_TARGET_MACHINE;
     338              : 
     339              : /* List of offload targets.  Separated by colon.  Empty string for
     340              :    -foffload=disable.  */
     341              : 
     342              : static char *offload_targets = NULL;
     343              : 
     344              : #if OFFLOAD_DEFAULTED
     345              : /* Set to true if -foffload has not been used and offload_targets
     346              :    is set to the configured in default.  */
     347              : static bool offload_targets_default;
     348              : #endif
     349              : 
     350              : /* Nonzero if cross-compiling.
     351              :    When -b is used, the value comes from the `specs' file.  */
     352              : 
     353              : #ifdef CROSS_DIRECTORY_STRUCTURE
     354              : static const char *cross_compile = "1";
     355              : #else
     356              : static const char *cross_compile = "0";
     357              : #endif
     358              : 
     359              : /* Greatest exit code of sub-processes that has been encountered up to
     360              :    now.  */
     361              : static int greatest_status = 1;
     362              : 
     363              : /* This is the obstack which we use to allocate many strings.  */
     364              : 
     365              : static struct obstack obstack;
     366              : 
     367              : /* This is the obstack to build an environment variable to pass to
     368              :    collect2 that describes all of the relevant switches of what to
     369              :    pass the compiler in building the list of pointers to constructors
     370              :    and destructors.  */
     371              : 
     372              : static struct obstack collect_obstack;
     373              : 
     374              : /* Forward declaration for prototypes.  */
     375              : struct path_prefix;
     376              : struct prefix_list;
     377              : 
     378              : static void init_spec (void);
     379              : static void store_arg (const char *, int, int);
     380              : static void insert_wrapper (const char *);
     381              : static char *load_specs (const char *);
     382              : static void read_specs (const char *, bool, bool);
     383              : static void set_spec (const char *, const char *, bool);
     384              : static struct compiler *lookup_compiler (const char *, size_t, const char *);
     385              : static char *build_search_list (const struct path_prefix *, const char *,
     386              :                                 bool, bool);
     387              : static void xputenv (const char *);
     388              : static void putenv_from_prefixes (const struct path_prefix *, const char *,
     389              :                                   bool);
     390              : static int access_check (const char *, int);
     391              : static char *find_a_file (const struct path_prefix *, const char *, int, bool);
     392              : static char *find_a_program (const char *);
     393              : static void add_prefix (struct path_prefix *, const char *, const char *,
     394              :                         int, int, int);
     395              : static void add_sysrooted_prefix (struct path_prefix *, const char *,
     396              :                                   const char *, int, int, int);
     397              : static char *skip_whitespace (char *);
     398              : static void delete_if_ordinary (const char *);
     399              : static void delete_temp_files (void);
     400              : static void delete_failure_queue (void);
     401              : static void clear_failure_queue (void);
     402              : static int check_live_switch (int, int);
     403              : static const char *handle_braces (const char *);
     404              : static inline bool input_suffix_matches (const char *, const char *);
     405              : static inline bool switch_matches (const char *, const char *, int);
     406              : static inline void mark_matching_switches (const char *, const char *, int);
     407              : static inline void process_marked_switches (void);
     408              : static const char *process_brace_body (const char *, const char *, const char *, int, int);
     409              : static const struct spec_function *lookup_spec_function (const char *);
     410              : static const char *eval_spec_function (const char *, const char *, const char *);
     411              : static const char *handle_spec_function (const char *, bool *, const char *);
     412              : static char *save_string (const char *, int);
     413              : static void set_collect_gcc_options (void);
     414              : static int do_spec_1 (const char *, int, const char *);
     415              : static int do_spec_2 (const char *, const char *);
     416              : static void do_option_spec (const char *, const char *);
     417              : static void do_self_spec (const char *);
     418              : static const char *find_file (const char *);
     419              : static int is_directory (const char *);
     420              : static const char *validate_switches (const char *, bool, bool);
     421              : static void validate_all_switches (void);
     422              : static inline void validate_switches_from_spec (const char *, bool);
     423              : static void give_switch (int, int);
     424              : static int default_arg (const char *, int);
     425              : static void set_multilib_dir (void);
     426              : static void print_multilib_info (void);
     427              : static void display_help (void);
     428              : static void add_preprocessor_option (const char *, int);
     429              : static void add_assembler_option (const char *, int);
     430              : static void add_linker_option (const char *, int);
     431              : static void process_command (unsigned int, struct cl_decoded_option *);
     432              : static int execute (void);
     433              : static void alloc_args (void);
     434              : static void clear_args (void);
     435              : static void fatal_signal (int);
     436              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
     437              : static void init_gcc_specs (struct obstack *, const char *, const char *,
     438              :                             const char *);
     439              : #endif
     440              : #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
     441              : static const char *convert_filename (const char *, int, int);
     442              : #endif
     443              : 
     444              : static void try_generate_repro (const char **argv);
     445              : static const char *getenv_spec_function (int, const char **);
     446              : static const char *if_exists_spec_function (int, const char **);
     447              : static const char *if_exists_else_spec_function (int, const char **);
     448              : static const char *if_exists_then_else_spec_function (int, const char **);
     449              : static const char *sanitize_spec_function (int, const char **);
     450              : static const char *replace_outfile_spec_function (int, const char **);
     451              : static const char *remove_outfile_spec_function (int, const char **);
     452              : static const char *version_compare_spec_function (int, const char **);
     453              : static const char *include_spec_function (int, const char **);
     454              : static const char *find_file_spec_function (int, const char **);
     455              : static const char *find_plugindir_spec_function (int, const char **);
     456              : static const char *print_asm_header_spec_function (int, const char **);
     457              : static const char *compare_debug_dump_opt_spec_function (int, const char **);
     458              : static const char *compare_debug_self_opt_spec_function (int, const char **);
     459              : static const char *pass_through_libs_spec_func (int, const char **);
     460              : static const char *dumps_spec_func (int, const char **);
     461              : static const char *greater_than_spec_func (int, const char **);
     462              : static const char *debug_level_greater_than_spec_func (int, const char **);
     463              : static const char *dwarf_version_greater_than_spec_func (int, const char **);
     464              : static const char *find_fortran_preinclude_file (int, const char **);
     465              : static const char *join_spec_func (int, const char **);
     466              : static char *convert_white_space (char *);
     467              : static char *quote_spec (char *);
     468              : static char *quote_spec_arg (char *);
     469              : static bool not_actual_file_p (const char *);
     470              : 
     471              : 
     472              : /* The Specs Language
     473              : 
     474              : Specs are strings containing lines, each of which (if not blank)
     475              : is made up of a program name, and arguments separated by spaces.
     476              : The program name must be exact and start from root, since no path
     477              : is searched and it is unreliable to depend on the current working directory.
     478              : Redirection of input or output is not supported; the subprograms must
     479              : accept filenames saying what files to read and write.
     480              : 
     481              : In addition, the specs can contain %-sequences to substitute variable text
     482              : or for conditional text.  Here is a table of all defined %-sequences.
     483              : Note that spaces are not generated automatically around the results of
     484              : expanding these sequences; therefore, you can concatenate them together
     485              : or with constant text in a single argument.
     486              : 
     487              :  %%     substitute one % into the program name or argument.
     488              :  %"     substitute an empty argument.
     489              :  %i     substitute the name of the input file being processed.
     490              :  %b     substitute the basename for outputs related with the input file
     491              :         being processed.  This is often a substring of the input file name,
     492              :         up to (and not including) the last period but, unless %w is active,
     493              :         it is affected by the directory selected by -save-temps=*, by
     494              :         -dumpdir, and, in case of multiple compilations, even by -dumpbase
     495              :         and -dumpbase-ext and, in case of linking, by the linker output
     496              :         name.  When %w is active, it derives the main output name only from
     497              :         the input file base name; when it is not, it names aux/dump output
     498              :         file.
     499              :  %B     same as %b, but include the input file suffix (text after the last
     500              :         period).
     501              :  %gSUFFIX
     502              :         substitute a file name that has suffix SUFFIX and is chosen
     503              :         once per compilation, and mark the argument a la %d.  To reduce
     504              :         exposure to denial-of-service attacks, the file name is now
     505              :         chosen in a way that is hard to predict even when previously
     506              :         chosen file names are known.  For example, `%g.s ... %g.o ... %g.s'
     507              :         might turn into `ccUVUUAU.s ccXYAXZ12.o ccUVUUAU.s'.  SUFFIX matches
     508              :         the regexp "[.0-9A-Za-z]*%O"; "%O" is treated exactly as if it
     509              :         had been pre-processed.  Previously, %g was simply substituted
     510              :         with a file name chosen once per compilation, without regard
     511              :         to any appended suffix (which was therefore treated just like
     512              :         ordinary text), making such attacks more likely to succeed.
     513              :  %|SUFFIX
     514              :         like %g, but if -pipe is in effect, expands simply to "-".
     515              :  %mSUFFIX
     516              :         like %g, but if -pipe is in effect, expands to nothing.  (We have both
     517              :         %| and %m to accommodate differences between system assemblers; see
     518              :         the AS_NEEDS_DASH_FOR_PIPED_INPUT target macro.)
     519              :  %uSUFFIX
     520              :         like %g, but generates a new temporary file name even if %uSUFFIX
     521              :         was already seen.
     522              :  %USUFFIX
     523              :         substitutes the last file name generated with %uSUFFIX, generating a
     524              :         new one if there is no such last file name.  In the absence of any
     525              :         %uSUFFIX, this is just like %gSUFFIX, except they don't share
     526              :         the same suffix "space", so `%g.s ... %U.s ... %g.s ... %U.s'
     527              :         would involve the generation of two distinct file names, one
     528              :         for each `%g.s' and another for each `%U.s'.  Previously, %U was
     529              :         simply substituted with a file name chosen for the previous %u,
     530              :         without regard to any appended suffix.
     531              :  %jSUFFIX
     532              :         substitutes the name of the HOST_BIT_BUCKET, if any, and if it is
     533              :         writable, and if save-temps is off; otherwise, substitute the name
     534              :         of a temporary file, just like %u.  This temporary file is not
     535              :         meant for communication between processes, but rather as a junk
     536              :         disposal mechanism.
     537              :  %.SUFFIX
     538              :         substitutes .SUFFIX for the suffixes of a matched switch's args when
     539              :         it is subsequently output with %*. SUFFIX is terminated by the next
     540              :         space or %.
     541              :  %d     marks the argument containing or following the %d as a
     542              :         temporary file name, so that file will be deleted if GCC exits
     543              :         successfully.  Unlike %g, this contributes no text to the argument.
     544              :  %w     marks the argument containing or following the %w as the
     545              :         "output file" of this compilation.  This puts the argument
     546              :         into the sequence of arguments that %o will substitute later.
     547              :  %V     indicates that this compilation produces no "output file".
     548              :  %W{...}
     549              :         like %{...} but marks the last argument supplied within as a file
     550              :         to be deleted on failure.
     551              :  %@{...}
     552              :         like %{...} but puts the result into a FILE and substitutes @FILE
     553              :         if an @file argument has been supplied.
     554              :  %o     substitutes the names of all the output files, with spaces
     555              :         automatically placed around them.  You should write spaces
     556              :         around the %o as well or the results are undefined.
     557              :         %o is for use in the specs for running the linker.
     558              :         Input files whose names have no recognized suffix are not compiled
     559              :         at all, but they are included among the output files, so they will
     560              :         be linked.
     561              :  %O     substitutes the suffix for object files.  Note that this is
     562              :         handled specially when it immediately follows %g, %u, or %U
     563              :         (with or without a suffix argument) because of the need for
     564              :         those to form complete file names.  The handling is such that
     565              :         %O is treated exactly as if it had already been substituted,
     566              :         except that %g, %u, and %U do not currently support additional
     567              :         SUFFIX characters following %O as they would following, for
     568              :         example, `.o'.
     569              :  %I     Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
     570              :         (made from TARGET_SYSTEM_ROOT), -isystem (made from COMPILER_PATH
     571              :         and -B options) and -imultilib as necessary.
     572              :  %s     current argument is the name of a library or startup file of some sort.
     573              :         Search for that file in a standard list of directories
     574              :         and substitute the full name found.
     575              :  %T     current argument is the name of a linker script.
     576              :         Search for that file in the current list of directories to scan for
     577              :         libraries.  If the file is located, insert a --script option into the
     578              :         command line followed by the full path name found.  If the file is
     579              :         not found then generate an error message.
     580              :         Note: the current working directory is not searched.
     581              :  %eSTR  Print STR as an error message.  STR is terminated by a newline.
     582              :         Use this when inconsistent options are detected.
     583              :  %nSTR  Print STR as a notice.  STR is terminated by a newline.
     584              :  %x{OPTION}     Accumulate an option for %X.
     585              :  %X     Output the accumulated linker options specified by compilations.
     586              :  %Y     Output the accumulated assembler options specified by compilations.
     587              :  %Z     Output the accumulated preprocessor options specified by compilations.
     588              :  %a     process ASM_SPEC as a spec.
     589              :         This allows config.h to specify part of the spec for running as.
     590              :  %A     process ASM_FINAL_SPEC as a spec.  A capital A is actually
     591              :         used here.  This can be used to run a post-processor after the
     592              :         assembler has done its job.
     593              :  %D     Dump out a -L option for each directory in startfile_prefixes.
     594              :         If multilib_dir is set, extra entries are generated with it affixed.
     595              :  %l     process LINK_SPEC as a spec.
     596              :  %L     process LIB_SPEC as a spec.
     597              :  %M     Output multilib_os_dir.
     598              :  %P     Output a RUNPATH_OPTION for each directory in startfile_prefixes.
     599              :  %G     process LIBGCC_SPEC as a spec.
     600              :  %R     Output the concatenation of target_system_root and
     601              :         target_sysroot_suffix.
     602              :  %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
     603              :  %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
     604              :  %C     process CPP_SPEC as a spec.
     605              :  %1     process CC1_SPEC as a spec.
     606              :  %2     process CC1PLUS_SPEC as a spec.
     607              :  %*     substitute the variable part of a matched option.  (See below.)
     608              :         Note that each comma in the substituted string is replaced by
     609              :         a single space.  A space is appended after the last substition
     610              :         unless there is more text in current sequence.
     611              :  %<S    remove all occurrences of -S from the command line.
     612              :         Note - this command is position dependent.  % commands in the
     613              :         spec string before this one will see -S, % commands in the
     614              :         spec string after this one will not.
     615              :  %>S Similar to "%<S", but keep it in the GCC command line.
     616              :  %<S*        remove all occurrences of all switches beginning with -S from the
     617              :         command line.
     618              :  %:function(args)
     619              :         Call the named function FUNCTION, passing it ARGS.  ARGS is
     620              :         first processed as a nested spec string, then split into an
     621              :         argument vector in the usual fashion.  The function returns
     622              :         a string which is processed as if it had appeared literally
     623              :         as part of the current spec.
     624              :  %{S}   substitutes the -S switch, if that switch was given to GCC.
     625              :         If that switch was not specified, this substitutes nothing.
     626              :         Here S is a metasyntactic variable.
     627              :  %{S*}  substitutes all the switches specified to GCC whose names start
     628              :         with -S.  This is used for -o, -I, etc; switches that take
     629              :         arguments.  GCC considers `-o foo' as being one switch whose
     630              :         name starts with `o'.  %{o*} would substitute this text,
     631              :         including the space; thus, two arguments would be generated.
     632              :  %{S*&T*} likewise, but preserve order of S and T options (the order
     633              :         of S and T in the spec is not significant).  Can be any number
     634              :         of ampersand-separated variables; for each the wild card is
     635              :         optional.  Useful for CPP as %{D*&U*&A*}.
     636              : 
     637              :  %{S:X}   substitutes X, if the -S switch was given to GCC.
     638              :  %{!S:X}  substitutes X, if the -S switch was NOT given to GCC.
     639              :  %{S*:X}  substitutes X if one or more switches whose names start
     640              :           with -S was given to GCC.  Normally X is substituted only
     641              :           once, no matter how many such switches appeared.  However,
     642              :           if %* appears somewhere in X, then X will be substituted
     643              :           once for each matching switch, with the %* replaced by the
     644              :           part of that switch that matched the '*'.  A space will be
     645              :           appended after the last substition unless there is more
     646              :           text in current sequence.
     647              :  %{.S:X}  substitutes X, if processing a file with suffix S.
     648              :  %{!.S:X} substitutes X, if NOT processing a file with suffix S.
     649              :  %{,S:X}  substitutes X, if processing a file which will use spec S.
     650              :  %{!,S:X} substitutes X, if NOT processing a file which will use spec S.
     651              : 
     652              :  %{S|T:X} substitutes X if either -S or -T was given to GCC.  This may be
     653              :           combined with '!', '.', ',', and '*' as above binding stronger
     654              :           than the OR.
     655              :           If %* appears in X, all of the alternatives must be starred, and
     656              :           only the first matching alternative is substituted.
     657              :  %{%:function(args):X}
     658              :           Call function named FUNCTION with args ARGS.  If the function
     659              :           returns non-NULL, then X is substituted, if it returns
     660              :           NULL, it isn't substituted.
     661              :  %{S:X;   if S was given to GCC, substitutes X;
     662              :    T:Y;   else if T was given to GCC, substitutes Y;
     663              :     :D}   else substitutes D.  There can be as many clauses as you need.
     664              :           This may be combined with '.', '!', ',', '|', and '*' as above.
     665              : 
     666              :  %(Spec) processes a specification defined in a specs file as *Spec:
     667              : 
     668              : The switch matching text S in a %{S}, %{S:X}, or similar construct can use
     669              : a backslash to ignore the special meaning of the character following it,
     670              : thus allowing literal matching of a character that is otherwise specially
     671              : treated.  For example, %{std=iso9899\:1999:X} substitutes X if the
     672              : -std=iso9899:1999 option is given.
     673              : 
     674              : The conditional text X in a %{S:X} or similar construct may contain
     675              : other nested % constructs or spaces, or even newlines.  They are
     676              : processed as usual, as described above.  Trailing white space in X is
     677              : ignored.  White space may also appear anywhere on the left side of the
     678              : colon in these constructs, except between . or * and the corresponding
     679              : word.
     680              : 
     681              : The -O, -f, -g, -m, and -W switches are handled specifically in these
     682              : constructs.  If another value of -O or the negated form of a -f, -m, or
     683              : -W switch is found later in the command line, the earlier switch
     684              : value is ignored, except with {S*} where S is just one letter; this
     685              : passes all matching options.
     686              : 
     687              : The character | at the beginning of the predicate text is used to indicate
     688              : that a command should be piped to the following command, but only if -pipe
     689              : is specified.
     690              : 
     691              : Note that it is built into GCC which switches take arguments and which
     692              : do not.  You might think it would be useful to generalize this to
     693              : allow each compiler's spec to say which switches take arguments.  But
     694              : this cannot be done in a consistent fashion.  GCC cannot even decide
     695              : which input files have been specified without knowing which switches
     696              : take arguments, and it must know which input files to compile in order
     697              : to tell which compilers to run.
     698              : 
     699              : GCC also knows implicitly that arguments starting in `-l' are to be
     700              : treated as compiler output files, and passed to the linker in their
     701              : proper position among the other output files.  */
     702              : 
     703              : /* Define the macros used for specs %a, %l, %L, %S, %C, %1.  */
     704              : 
     705              : /* config.h can define ASM_SPEC to provide extra args to the assembler
     706              :    or extra switch-translations.  */
     707              : #ifndef ASM_SPEC
     708              : #define ASM_SPEC ""
     709              : #endif
     710              : 
     711              : /* config.h can define ASM_FINAL_SPEC to run a post processor after
     712              :    the assembler has run.  */
     713              : #ifndef ASM_FINAL_SPEC
     714              : #define ASM_FINAL_SPEC \
     715              :   "%{gsplit-dwarf: \n\
     716              :        objcopy --extract-dwo \
     717              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     718              :          %b.dwo \n\
     719              :        objcopy --strip-dwo \
     720              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     721              :     }"
     722              : #endif
     723              : 
     724              : /* config.h can define CPP_SPEC to provide extra args to the C preprocessor
     725              :    or extra switch-translations.  */
     726              : #ifndef CPP_SPEC
     727              : #define CPP_SPEC ""
     728              : #endif
     729              : 
     730              : /* libc can define LIBC_CPP_SPEC to provide extra args to the C preprocessor
     731              :    or extra switch-translations. */
     732              : 
     733              : #ifndef LIBC_CPP_SPEC
     734              : #define LIBC_CPP_SPEC ""
     735              : #endif
     736              : 
     737              : /* Operating systems can define OS_CC1_SPEC to provide extra args to cc1 and
     738              :    cc1plus or extra switch-translations.  The OS_CC1_SPEC is appended
     739              :    to CC1_SPEC in the initialization of cc1_spec.  */
     740              : #ifndef OS_CC1_SPEC
     741              : #define OS_CC1_SPEC ""
     742              : #endif
     743              : 
     744              : /* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
     745              :    or extra switch-translations.  */
     746              : #ifndef CC1_SPEC
     747              : #define CC1_SPEC ""
     748              : #endif
     749              : 
     750              : /* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
     751              :    or extra switch-translations.  */
     752              : #ifndef CC1PLUS_SPEC
     753              : #define CC1PLUS_SPEC ""
     754              : #endif
     755              : 
     756              : /* config.h can define LINK_SPEC to provide extra args to the linker
     757              :    or extra switch-translations.  */
     758              : #ifndef LINK_SPEC
     759              : #define LINK_SPEC ""
     760              : #endif
     761              : 
     762              : /* libc can define LIBC_LINK_SPEC to provide extra args to the linker
     763              :    or extra switch-translations.  */
     764              : #ifndef LIBC_LINK_SPEC
     765              : #define LIBC_LINK_SPEC ""
     766              : #endif
     767              : 
     768              : /* config.h can define LIB_SPEC to override the default libraries.  */
     769              : #ifndef LIB_SPEC
     770              : #define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
     771              : #endif
     772              : 
     773              : /* When using -fsplit-stack we need to wrap pthread_create, in order
     774              :    to initialize the stack guard.  We always use wrapping, rather than
     775              :    shared library ordering, and we keep the wrapper function in
     776              :    libgcc.  This is not yet a real spec, though it could become one;
     777              :    it is currently just stuffed into LINK_SPEC.  FIXME: This wrapping
     778              :    only works with GNU ld and gold.  */
     779              : #ifdef HAVE_GOLD_NON_DEFAULT_SPLIT_STACK
     780              : #define STACK_SPLIT_SPEC " %{fsplit-stack: -fuse-ld=gold --wrap=pthread_create}"
     781              : #else
     782              : #define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
     783              : #endif
     784              : 
     785              : #ifndef LIBASAN_SPEC
     786              : #define STATIC_LIBASAN_LIBS \
     787              :   " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}"
     788              : #ifdef LIBASAN_EARLY_SPEC
     789              : #define LIBASAN_SPEC STATIC_LIBASAN_LIBS
     790              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     791              : #define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
     792              :                      "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
     793              :                      STATIC_LIBASAN_LIBS
     794              : #else
     795              : #define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS
     796              : #endif
     797              : #endif
     798              : 
     799              : #ifndef LIBASAN_EARLY_SPEC
     800              : #define LIBASAN_EARLY_SPEC ""
     801              : #endif
     802              : 
     803              : #ifndef LIBHWASAN_SPEC
     804              : #define STATIC_LIBHWASAN_LIBS \
     805              :   " %{static-libhwasan|static:%:include(libsanitizer.spec)%(link_libhwasan)}"
     806              : #ifdef LIBHWASAN_EARLY_SPEC
     807              : #define LIBHWASAN_SPEC STATIC_LIBHWASAN_LIBS
     808              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     809              : #define LIBHWASAN_SPEC "%{static-libhwasan:" LD_STATIC_OPTION \
     810              :                      "} -lhwasan %{static-libhwasan:" LD_DYNAMIC_OPTION "}" \
     811              :                      STATIC_LIBHWASAN_LIBS
     812              : #else
     813              : #define LIBHWASAN_SPEC "-lhwasan" STATIC_LIBHWASAN_LIBS
     814              : #endif
     815              : #endif
     816              : 
     817              : #ifndef LIBHWASAN_EARLY_SPEC
     818              : #define LIBHWASAN_EARLY_SPEC ""
     819              : #endif
     820              : 
     821              : #ifndef LIBTSAN_SPEC
     822              : #define STATIC_LIBTSAN_LIBS \
     823              :   " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}"
     824              : #ifdef LIBTSAN_EARLY_SPEC
     825              : #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS
     826              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     827              : #define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
     828              :                      "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \
     829              :                      STATIC_LIBTSAN_LIBS
     830              : #else
     831              : #define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS
     832              : #endif
     833              : #endif
     834              : 
     835              : #ifndef LIBTSAN_EARLY_SPEC
     836              : #define LIBTSAN_EARLY_SPEC ""
     837              : #endif
     838              : 
     839              : #ifndef LIBLSAN_SPEC
     840              : #define STATIC_LIBLSAN_LIBS \
     841              :   " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}"
     842              : #ifdef LIBLSAN_EARLY_SPEC
     843              : #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS
     844              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     845              : #define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION \
     846              :                      "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \
     847              :                      STATIC_LIBLSAN_LIBS
     848              : #else
     849              : #define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS
     850              : #endif
     851              : #endif
     852              : 
     853              : #ifndef LIBLSAN_EARLY_SPEC
     854              : #define LIBLSAN_EARLY_SPEC ""
     855              : #endif
     856              : 
     857              : #ifndef LIBUBSAN_SPEC
     858              : #define STATIC_LIBUBSAN_LIBS \
     859              :   " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}"
     860              : #ifdef HAVE_LD_STATIC_DYNAMIC
     861              : #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
     862              :                      "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
     863              :                      STATIC_LIBUBSAN_LIBS
     864              : #else
     865              : #define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS
     866              : #endif
     867              : #endif
     868              : 
     869              : /* Linker options for compressed debug sections.  */
     870              : #if HAVE_LD_COMPRESS_DEBUG == 0
     871              : /* No linker support.  */
     872              : #define LINK_COMPRESS_DEBUG_SPEC \
     873              :         " %{gz*:%e-gz is not supported in this configuration} "
     874              : #elif HAVE_LD_COMPRESS_DEBUG == 1
     875              : /* ELF gABI style.  */
     876              : #define LINK_COMPRESS_DEBUG_SPEC \
     877              :         " %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
     878              :         " %{gz=none:"   LD_COMPRESS_DEBUG_OPTION "=none}" \
     879              :         " %{gz=zstd:%e-gz=zstd is not supported in this configuration} " \
     880              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     881              : #elif HAVE_LD_COMPRESS_DEBUG == 2
     882              : /* ELF gABI style and ZSTD.  */
     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:"   LD_COMPRESS_DEBUG_OPTION "=zstd}" \
     887              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     888              : #else
     889              : #error Unknown value for HAVE_LD_COMPRESS_DEBUG.
     890              : #endif
     891              : 
     892              : /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
     893              :    included.  */
     894              : #ifndef LIBGCC_SPEC
     895              : #if defined(REAL_LIBGCC_SPEC)
     896              : #define LIBGCC_SPEC REAL_LIBGCC_SPEC
     897              : #elif defined(LINK_LIBGCC_SPECIAL_1)
     898              : /* Have gcc do the search for libgcc.a.  */
     899              : #define LIBGCC_SPEC "libgcc.a%s"
     900              : #else
     901              : #define LIBGCC_SPEC "-lgcc"
     902              : #endif
     903              : #endif
     904              : 
     905              : /* config.h can define STARTFILE_SPEC to override the default crt0 files.  */
     906              : #ifndef STARTFILE_SPEC
     907              : #define STARTFILE_SPEC  \
     908              :   "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
     909              : #endif
     910              : 
     911              : /* config.h can define ENDFILE_SPEC to override the default crtn files.  */
     912              : #ifndef ENDFILE_SPEC
     913              : #define ENDFILE_SPEC ""
     914              : #endif
     915              : 
     916              : #ifndef LINKER_NAME
     917              : #define LINKER_NAME "collect2"
     918              : #endif
     919              : 
     920              : #ifdef HAVE_AS_DEBUG_PREFIX_MAP
     921              : #define ASM_MAP " %{ffile-prefix-map=*:--debug-prefix-map %*} %{fdebug-prefix-map=*:--debug-prefix-map %*}"
     922              : #else
     923              : #define ASM_MAP ""
     924              : #endif
     925              : 
     926              : /* Assembler options for compressed debug sections.  */
     927              : #if HAVE_LD_COMPRESS_DEBUG == 0
     928              : /* Reject if the linker cannot write compressed debug sections.  */
     929              : #define ASM_COMPRESS_DEBUG_SPEC \
     930              :         " %{gz*:%e-gz is not supported in this configuration} "
     931              : #else /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     932              : #if HAVE_AS_COMPRESS_DEBUG == 0
     933              : /* No assembler support.  Ignore silently.  */
     934              : #define ASM_COMPRESS_DEBUG_SPEC \
     935              :         " %{gz*:} "
     936              : #elif HAVE_AS_COMPRESS_DEBUG == 1
     937              : /* ELF gABI style.  */
     938              : #define ASM_COMPRESS_DEBUG_SPEC \
     939              :         " %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
     940              :         " %{gz=none:"   AS_COMPRESS_DEBUG_OPTION "=none}" \
     941              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     942              : #elif HAVE_AS_COMPRESS_DEBUG == 2
     943              : /* ELF gABI style and ZSTD.  */
     944              : #define ASM_COMPRESS_DEBUG_SPEC \
     945              :         " %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
     946              :         " %{gz=none:"   AS_COMPRESS_DEBUG_OPTION "=none}" \
     947              :         " %{gz=zstd:"   AS_COMPRESS_DEBUG_OPTION "=zstd}" \
     948              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     949              : #else
     950              : #error Unknown value for HAVE_AS_COMPRESS_DEBUG.
     951              : #endif
     952              : #endif /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     953              : 
     954              : /* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
     955              :    to the assembler, when compiling assembly sources only.  */
     956              : #ifndef ASM_DEBUG_SPEC
     957              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     958              : /* If --gdwarf-N is supported and as can handle even compiler generated
     959              :    .debug_line with it, supply --gdwarf-N in ASM_DEBUG_OPTION_SPEC rather
     960              :    than in ASM_DEBUG_SPEC, so that it applies to both .s and .c etc.
     961              :    compilations.  */
     962              : #  define ASM_DEBUG_DWARF_OPTION ""
     963              : # elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && !defined(HAVE_LD_BROKEN_PE_DWARF5)
     964              : #  define ASM_DEBUG_DWARF_OPTION "%{%:dwarf-version-gt(4):--gdwarf-5;" \
     965              :         "%:dwarf-version-gt(3):--gdwarf-4;"                           \
     966              :         "%:dwarf-version-gt(2):--gdwarf-3;"                           \
     967              :         ":--gdwarf2}"
     968              : # else
     969              : #  define ASM_DEBUG_DWARF_OPTION "--gdwarf2"
     970              : # endif
     971              : #  if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
     972              : #   define ASM_DEBUG_SPEC "%{g*:%{%:debug-level-gt(0):" \
     973              :         ASM_DEBUG_DWARF_OPTION "}}" ASM_MAP
     974              : #  endif
     975              : # endif
     976              : #ifndef ASM_DEBUG_SPEC
     977              : # define ASM_DEBUG_SPEC ""
     978              : #endif
     979              : 
     980              : /* Define ASM_DEBUG_OPTION_SPEC to be a spec suitable for translating '-g'
     981              :    to the assembler when compiling all sources.  */
     982              : #ifndef ASM_DEBUG_OPTION_SPEC
     983              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     984              : #  define ASM_DEBUG_OPTION_DWARF_OPT                                    \
     985              :         "%{%:dwarf-version-gt(4):--gdwarf-5 ;"                                \
     986              :         "%:dwarf-version-gt(3):--gdwarf-4 ;"                          \
     987              :         "%:dwarf-version-gt(2):--gdwarf-3 ;"                          \
     988              :         ":--gdwarf2 }"
     989              : # if defined(DWARF2_DEBUGGING_INFO)
     990              : #   define ASM_DEBUG_OPTION_SPEC "%{g*:%{%:debug-level-gt(0):" \
     991              :         ASM_DEBUG_OPTION_DWARF_OPT "}}"
     992              : #  endif
     993              : # endif
     994              : #endif
     995              : #ifndef ASM_DEBUG_OPTION_SPEC
     996              : # define ASM_DEBUG_OPTION_SPEC ""
     997              : #endif
     998              : 
     999              : /* Here is the spec for running the linker, after compiling all files.  */
    1000              : 
    1001              : #if defined(TARGET_PROVIDES_LIBATOMIC) && defined(USE_LD_AS_NEEDED)
    1002              : #ifdef USE_LD_AS_NEEDED_LDSCRIPT
    1003              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:-latomic_asneeded} "
    1004              : #else
    1005              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:" LD_AS_NEEDED_OPTION \
    1006              :                             " -latomic " LD_NO_AS_NEEDED_OPTION "} "
    1007              : #endif
    1008              : #else
    1009              : #define LINK_LIBATOMIC_SPEC ""
    1010              : #endif
    1011              : 
    1012              : /* This is overridable by the target in case they need to specify the
    1013              :    -lgcc and -lc order specially, yet not require them to override all
    1014              :    of LINK_COMMAND_SPEC.  */
    1015              : #ifndef LINK_GCC_C_SEQUENCE_SPEC
    1016              : #define LINK_GCC_C_SEQUENCE_SPEC "%G %{!nolibc:%L %G}"
    1017              : #endif
    1018              : 
    1019              : #ifndef LINK_SSP_SPEC
    1020              : #ifdef TARGET_LIBC_PROVIDES_SSP
    1021              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1022              :                        "|fstack-protector-strong|fstack-protector-explicit:}"
    1023              : #else
    1024              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1025              :                        "|fstack-protector-strong|fstack-protector-explicit" \
    1026              :                        ":-lssp_nonshared -lssp}"
    1027              : #endif
    1028              : #endif
    1029              : 
    1030              : #ifdef ENABLE_DEFAULT_PIE
    1031              : #define PIE_SPEC                "!no-pie"
    1032              : #define NO_FPIE1_SPEC           "fno-pie"
    1033              : #define FPIE1_SPEC              NO_FPIE1_SPEC ":;"
    1034              : #define NO_FPIE2_SPEC           "fno-PIE"
    1035              : #define FPIE2_SPEC              NO_FPIE2_SPEC ":;"
    1036              : #define NO_FPIE_SPEC            NO_FPIE1_SPEC "|" NO_FPIE2_SPEC
    1037              : #define FPIE_SPEC               NO_FPIE_SPEC ":;"
    1038              : #define NO_FPIC1_SPEC           "fno-pic"
    1039              : #define FPIC1_SPEC              NO_FPIC1_SPEC ":;"
    1040              : #define NO_FPIC2_SPEC           "fno-PIC"
    1041              : #define FPIC2_SPEC              NO_FPIC2_SPEC ":;"
    1042              : #define NO_FPIC_SPEC            NO_FPIC1_SPEC "|" NO_FPIC2_SPEC
    1043              : #define FPIC_SPEC               NO_FPIC_SPEC ":;"
    1044              : #define NO_FPIE1_AND_FPIC1_SPEC NO_FPIE1_SPEC "|" NO_FPIC1_SPEC
    1045              : #define FPIE1_OR_FPIC1_SPEC     NO_FPIE1_AND_FPIC1_SPEC ":;"
    1046              : #define NO_FPIE2_AND_FPIC2_SPEC NO_FPIE2_SPEC "|" NO_FPIC2_SPEC
    1047              : #define FPIE2_OR_FPIC2_SPEC     NO_FPIE2_AND_FPIC2_SPEC ":;"
    1048              : #define NO_FPIE_AND_FPIC_SPEC   NO_FPIE_SPEC "|" NO_FPIC_SPEC
    1049              : #define FPIE_OR_FPIC_SPEC       NO_FPIE_AND_FPIC_SPEC ":;"
    1050              : #else
    1051              : #define PIE_SPEC                "pie"
    1052              : #define FPIE1_SPEC              "fpie"
    1053              : #define NO_FPIE1_SPEC           FPIE1_SPEC ":;"
    1054              : #define FPIE2_SPEC              "fPIE"
    1055              : #define NO_FPIE2_SPEC           FPIE2_SPEC ":;"
    1056              : #define FPIE_SPEC               FPIE1_SPEC "|" FPIE2_SPEC
    1057              : #define NO_FPIE_SPEC            FPIE_SPEC ":;"
    1058              : #define FPIC1_SPEC              "fpic"
    1059              : #define NO_FPIC1_SPEC           FPIC1_SPEC ":;"
    1060              : #define FPIC2_SPEC              "fPIC"
    1061              : #define NO_FPIC2_SPEC           FPIC2_SPEC ":;"
    1062              : #define FPIC_SPEC               FPIC1_SPEC "|" FPIC2_SPEC
    1063              : #define NO_FPIC_SPEC            FPIC_SPEC ":;"
    1064              : #define FPIE1_OR_FPIC1_SPEC     FPIE1_SPEC "|" FPIC1_SPEC
    1065              : #define NO_FPIE1_AND_FPIC1_SPEC FPIE1_OR_FPIC1_SPEC ":;"
    1066              : #define FPIE2_OR_FPIC2_SPEC     FPIE2_SPEC "|" FPIC2_SPEC
    1067              : #define NO_FPIE2_AND_FPIC2_SPEC FPIE1_OR_FPIC2_SPEC ":;"
    1068              : #define FPIE_OR_FPIC_SPEC       FPIE_SPEC "|" FPIC_SPEC
    1069              : #define NO_FPIE_AND_FPIC_SPEC   FPIE_OR_FPIC_SPEC ":;"
    1070              : #endif
    1071              : 
    1072              : #ifndef LINK_PIE_SPEC
    1073              : #ifdef HAVE_LD_PIE
    1074              : #ifndef LD_PIE_SPEC
    1075              : #define LD_PIE_SPEC "-pie"
    1076              : #endif
    1077              : #else
    1078              : #define LD_PIE_SPEC ""
    1079              : #endif
    1080              : #define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} "
    1081              : #endif
    1082              : 
    1083              : #ifndef LINK_BUILDID_SPEC
    1084              : # if defined(HAVE_LD_BUILDID) && defined(ENABLE_LD_BUILDID)
    1085              : #  define LINK_BUILDID_SPEC "%{!r:--build-id} "
    1086              : # endif
    1087              : #endif
    1088              : 
    1089              : #ifndef LTO_PLUGIN_SPEC
    1090              : #define LTO_PLUGIN_SPEC ""
    1091              : #endif
    1092              : 
    1093              : /* Conditional to test whether the LTO plugin is used or not.
    1094              :    FIXME: For slim LTO we will need to enable plugin unconditionally.  This
    1095              :    still cause problems with PLUGIN_LD != LD and when plugin is built but
    1096              :    not useable.  For GCC 4.6 we don't support slim LTO and thus we can enable
    1097              :    plugin only when LTO is enabled.  We still honor explicit
    1098              :    -fuse-linker-plugin if the linker used understands -plugin.  */
    1099              : 
    1100              : /* The linker has some plugin support.  */
    1101              : #if HAVE_LTO_PLUGIN > 0
    1102              : /* The linker used has full plugin support, use LTO plugin by default.  */
    1103              : #if HAVE_LTO_PLUGIN == 2
    1104              : #define PLUGIN_COND "!fno-use-linker-plugin:%{!fno-lto"
    1105              : #define PLUGIN_COND_CLOSE "}"
    1106              : #else
    1107              : /* The linker used has limited plugin support, use LTO plugin with explicit
    1108              :    -fuse-linker-plugin.  */
    1109              : #define PLUGIN_COND "fuse-linker-plugin"
    1110              : #define PLUGIN_COND_CLOSE ""
    1111              : #endif
    1112              : #define LINK_PLUGIN_SPEC \
    1113              :     "%{" PLUGIN_COND": \
    1114              :     -plugin %(linker_plugin_file) \
    1115              :     -plugin-opt=%(lto_wrapper) \
    1116              :     -plugin-opt=-fresolution=%u.res \
    1117              :     " LTO_PLUGIN_SPEC "\
    1118              :     %{flinker-output=*:-plugin-opt=-linker-output-known} \
    1119              :     %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
    1120              :     }" PLUGIN_COND_CLOSE
    1121              : #else
    1122              : /* The linker used doesn't support -plugin, reject -fuse-linker-plugin.  */
    1123              : #define LINK_PLUGIN_SPEC "%{fuse-linker-plugin:\
    1124              :     %e-fuse-linker-plugin is not supported in this configuration}"
    1125              : #endif
    1126              : 
    1127              : /* Linker command line options for -fsanitize= early on the command line.  */
    1128              : #ifndef SANITIZER_EARLY_SPEC
    1129              : #define SANITIZER_EARLY_SPEC "\
    1130              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
    1131              :     %{%:sanitize(hwaddress):" LIBHWASAN_EARLY_SPEC "} \
    1132              :     %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
    1133              :     %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}}"
    1134              : #endif
    1135              : 
    1136              : /* Linker command line options for -fsanitize= late on the command line.  */
    1137              : #ifndef SANITIZER_SPEC
    1138              : #define SANITIZER_SPEC "\
    1139              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
    1140              :     %{static:%ecannot specify -static with -fsanitize=address}}\
    1141              :     %{%:sanitize(hwaddress):" LIBHWASAN_SPEC "\
    1142              :         %{static:%ecannot specify -static with -fsanitize=hwaddress}}\
    1143              :     %{%:sanitize(thread):" LIBTSAN_SPEC "\
    1144              :     %{static:%ecannot specify -static with -fsanitize=thread}}\
    1145              :     %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
    1146              :     %{%:sanitize(leak):" LIBLSAN_SPEC "}}}}"
    1147              : #endif
    1148              : 
    1149              : #ifndef POST_LINK_SPEC
    1150              : #define POST_LINK_SPEC ""
    1151              : #endif
    1152              : 
    1153              : /*  This is the spec to use, once the code for creating the vtable
    1154              :     verification runtime library, libvtv.so, has been created.  Currently
    1155              :     the vtable verification runtime functions are in libstdc++, so we use
    1156              :     the spec just below this one.  */
    1157              : #ifndef VTABLE_VERIFICATION_SPEC
    1158              : #if ENABLE_VTABLE_VERIFY
    1159              : #define VTABLE_VERIFICATION_SPEC "\
    1160              : %{!nostdlib:%{!r:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
    1161              :     %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}}"
    1162              : #else
    1163              : #define VTABLE_VERIFICATION_SPEC "\
    1164              : %{fvtable-verify=none:} \
    1165              : %{fvtable-verify=std: \
    1166              :   %e-fvtable-verify=std is not supported in this configuration} \
    1167              : %{fvtable-verify=preinit: \
    1168              :   %e-fvtable-verify=preinit is not supported in this configuration}"
    1169              : #endif
    1170              : #endif
    1171              : 
    1172              : /* -u* was put back because both BSD and SysV seem to support it.  */
    1173              : /* %{static|no-pie|static-pie:} simply prevents an error message:
    1174              :    1. If the target machine doesn't handle -static.
    1175              :    2. If PIE isn't enabled by default.
    1176              :    3. If the target machine doesn't handle -static-pie.
    1177              :  */
    1178              : /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
    1179              :    scripts which exist in user specified directories, or in standard
    1180              :    directories.  */
    1181              : /* We pass any -flto flags on to the linker, which is expected
    1182              :    to understand them.  In practice, this means it had better be collect2.  */
    1183              : /* %{e*} includes -export-dynamic; see comment in common.opt.  */
    1184              : #ifndef LINK_COMMAND_SPEC
    1185              : #define LINK_COMMAND_SPEC "\
    1186              : %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
    1187              :     %(linker) " \
    1188              :     LINK_PLUGIN_SPEC \
    1189              :    "%{flto|flto=*:%<fcompare-debug*} \
    1190              :     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    1191              :    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    1192              :    "%X %{o*} %{e*} %{N} %{n} %{r}\
    1193              :     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
    1194              :     %{static|no-pie|static-pie:} %@{L*} %(link_libgcc) " \
    1195              :     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o "" \
    1196              :     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
    1197              :         %:include(libgomp.spec)%(link_gomp)}\
    1198              :     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
    1199              :     " STACK_SPLIT_SPEC "\
    1200              :     %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
    1201              :     %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\
    1202              :     %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*}  \n%(post_link) }}}}}}"
    1203              : #endif
    1204              : 
    1205              : #ifndef LINK_LIBGCC_SPEC
    1206              : /* Generate -L options for startfile prefix list.  */
    1207              : # define LINK_LIBGCC_SPEC "%D"
    1208              : #endif
    1209              : 
    1210              : #ifndef STARTFILE_PREFIX_SPEC
    1211              : # define STARTFILE_PREFIX_SPEC ""
    1212              : #endif
    1213              : 
    1214              : #ifndef SYSROOT_SPEC
    1215              : # define SYSROOT_SPEC "--sysroot=%R"
    1216              : #endif
    1217              : 
    1218              : #ifndef SYSROOT_SUFFIX_SPEC
    1219              : # define SYSROOT_SUFFIX_SPEC ""
    1220              : #endif
    1221              : 
    1222              : #ifndef SYSROOT_HEADERS_SUFFIX_SPEC
    1223              : # define SYSROOT_HEADERS_SUFFIX_SPEC ""
    1224              : #endif
    1225              : 
    1226              : #ifndef RUNPATH_OPTION
    1227              : # define RUNPATH_OPTION "-rpath"
    1228              : #endif
    1229              : 
    1230              : static const char *asm_debug = ASM_DEBUG_SPEC;
    1231              : static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC;
    1232              : static const char *cpp_spec = CPP_SPEC LIBC_CPP_SPEC;
    1233              : static const char *cc1_spec = CC1_SPEC OS_CC1_SPEC;
    1234              : static const char *cc1plus_spec = CC1PLUS_SPEC;
    1235              : static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
    1236              : static const char *link_ssp_spec = LINK_SSP_SPEC;
    1237              : static const char *asm_spec = ASM_SPEC;
    1238              : static const char *asm_final_spec = ASM_FINAL_SPEC;
    1239              : static const char *link_spec = LINK_SPEC LIBC_LINK_SPEC;
    1240              : static const char *lib_spec = LIB_SPEC;
    1241              : static const char *link_gomp_spec = "";
    1242              : static const char *libgcc_spec = LIBGCC_SPEC;
    1243              : static const char *endfile_spec = ENDFILE_SPEC;
    1244              : static const char *startfile_spec = STARTFILE_SPEC;
    1245              : static const char *linker_name_spec = LINKER_NAME;
    1246              : static const char *linker_plugin_file_spec = "";
    1247              : static const char *lto_wrapper_spec = "";
    1248              : static const char *lto_gcc_spec = "";
    1249              : static const char *post_link_spec = POST_LINK_SPEC;
    1250              : static const char *link_command_spec = LINK_COMMAND_SPEC;
    1251              : static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
    1252              : static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
    1253              : static const char *sysroot_spec = SYSROOT_SPEC;
    1254              : static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
    1255              : static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
    1256              : static const char *self_spec = "";
    1257              : 
    1258              : /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    1259              :    There should be no need to override these in target dependent files,
    1260              :    but we need to copy them to the specs file so that newer versions
    1261              :    of the GCC driver can correctly drive older tool chains with the
    1262              :    appropriate -B options.  */
    1263              : 
    1264              : /* When cpplib handles traditional preprocessing, get rid of this, and
    1265              :    call cc1 (or cc1obj in objc/lang-specs.h) from the main specs so
    1266              :    that we default the front end language better.  */
    1267              : static const char *trad_capable_cpp =
    1268              : "cc1 -E %{traditional|traditional-cpp:-traditional-cpp}";
    1269              : 
    1270              : /* We don't wrap .d files in %W{} since a missing .d file, and
    1271              :    therefore no dependency entry, confuses make into thinking a .o
    1272              :    file that happens to exist is up-to-date.  */
    1273              : static const char *cpp_unique_options =
    1274              : "%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %@{I*&F*} %{P} %I\
    1275              :  %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
    1276              :  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
    1277              :  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
    1278              :  %{Mmodules} %{Mno-modules}\
    1279              :  %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
    1280              :  %{remap} %{%:debug-level-gt(2):-dD}\
    1281              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1282              :  %{H} %C %{D*&U*&A*} %{i*} %Z %i\
    1283              :  %{E|M|MM:%W{o*}} %{-embed*}\
    1284              :  %{fdeps-format=*:%{!fdeps-file=*:-fdeps-file=%:join(%{!o:%b.ddi}%{o*:%.ddi%*})}}\
    1285              :  %{fdeps-format=*:%{!fdeps-target=*:-fdeps-target=%:join(%{!o:%b.o}%{o*:%.o%*})}}";
    1286              : 
    1287              : /* This contains cpp options which are common with cc1_options and are passed
    1288              :    only when preprocessing only to avoid duplication.  We pass the cc1 spec
    1289              :    options to the preprocessor so that it the cc1 spec may manipulate
    1290              :    options used to set target flags.  Those special target flags settings may
    1291              :    in turn cause preprocessor symbols to be defined specially.  */
    1292              : static const char *cpp_options =
    1293              : "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
    1294              :  %{f*} %{g*:%{%:debug-level-gt(0):%{g*}\
    1295              :  %{!fno-working-directory:-fworking-directory}}} %{O*}\
    1296              :  %{undef} %{save-temps*:-fpch-preprocess}";
    1297              : 
    1298              : /* Pass -d* flags, possibly modifying -dumpdir, -dumpbase et al.
    1299              : 
    1300              :    Make it easy for a language to override the argument for the
    1301              :    %:dumps specs function call.  */
    1302              : #define DUMPS_OPTIONS(EXTS) \
    1303              :   "%<dumpdir %<dumpbase %<dumpbase-ext %{d*} %:dumps(" EXTS ")"
    1304              : 
    1305              : /* This contains cpp options which are not passed when the preprocessor
    1306              :    output will be used by another program.  */
    1307              : static const char *cpp_debug_options = DUMPS_OPTIONS ("");
    1308              : 
    1309              : /* NB: This is shared amongst all front-ends, except for Ada.  */
    1310              : static const char *cc1_options =
    1311              : "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
    1312              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1313              :  %1 %{!Q:-quiet} %(cpp_debug_options) %{m*} %{aux-info*}\
    1314              :  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
    1315              :  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
    1316              :  %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
    1317              :  %{-target-help:--target-help}\
    1318              :  %{-version:--version}\
    1319              :  %{-help=*:--help=%*}\
    1320              :  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %w%b.s}}}\
    1321              :  %{fsyntax-only:-o %j} %{-param*}\
    1322              :  %{coverage:-fprofile-arcs -ftest-coverage}\
    1323              :  %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:\
    1324              :    %{!fprofile-update=single:\
    1325              :      %{pthread:-fprofile-update=prefer-atomic}}}";
    1326              : 
    1327              : static const char *asm_options =
    1328              : "%{-target-help:%:print-asm-header()} "
    1329              : #if HAVE_GNU_AS
    1330              : /* If GNU AS is used, then convert -w (no warnings), -I, and -v
    1331              :    to the assembler equivalents.  */
    1332              : "%{v} %{w:-W} %{I*} "
    1333              : #endif
    1334              : "%(asm_debug_option)"
    1335              : ASM_COMPRESS_DEBUG_SPEC
    1336              : "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
    1337              : 
    1338              : static const char *invoke_as =
    1339              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1340              : "%{!fwpa*:\
    1341              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1342              :    %{!S:-o %|.s |\n as %(asm_options) %|.s %A }\
    1343              :   }";
    1344              : #else
    1345              : "%{!fwpa*:\
    1346              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1347              :    %{!S:-o %|.s |\n as %(asm_options) %m.s %A }\
    1348              :   }";
    1349              : #endif
    1350              : 
    1351              : /* Some compilers have limits on line lengths, and the multilib_select
    1352              :    and/or multilib_matches strings can be very long, so we build them at
    1353              :    run time.  */
    1354              : static struct obstack multilib_obstack;
    1355              : static const char *multilib_select;
    1356              : static const char *multilib_matches;
    1357              : static const char *multilib_defaults;
    1358              : static const char *multilib_exclusions;
    1359              : static const char *multilib_reuse;
    1360              : 
    1361              : /* Check whether a particular argument is a default argument.  */
    1362              : 
    1363              : #ifndef MULTILIB_DEFAULTS
    1364              : #define MULTILIB_DEFAULTS { "" }
    1365              : #endif
    1366              : 
    1367              : static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
    1368              : 
    1369              : #ifndef DRIVER_SELF_SPECS
    1370              : #define DRIVER_SELF_SPECS ""
    1371              : #endif
    1372              : 
    1373              : /* Linking to libgomp implies pthreads.  This is particularly important
    1374              :    for targets that use different start files and suchlike.  */
    1375              : #ifndef GOMP_SELF_SPECS
    1376              : #define GOMP_SELF_SPECS \
    1377              :   "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): " \
    1378              :   "-pthread}"
    1379              : #endif
    1380              : 
    1381              : /* Likewise for -fgnu-tm.  */
    1382              : #ifndef GTM_SELF_SPECS
    1383              : #define GTM_SELF_SPECS "%{fgnu-tm: -pthread}"
    1384              : #endif
    1385              : 
    1386              : static const char *const driver_self_specs[] = {
    1387              :   "%{fdump-final-insns:-fdump-final-insns=.} %<fdump-final-insns",
    1388              :   DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS,
    1389              :   /* This discards -fmultiflags at the end of self specs processing in the
    1390              :      driver, so that it is effectively Ignored, without actually marking it as
    1391              :      Ignored, which would get it discarded before self specs could remap it.  */
    1392              :   "%<fmultiflags"
    1393              : };
    1394              : 
    1395              : #ifndef OPTION_DEFAULT_SPECS
    1396              : #define OPTION_DEFAULT_SPECS { "", "" }
    1397              : #endif
    1398              : 
    1399              : struct default_spec
    1400              : {
    1401              :   const char *name;
    1402              :   const char *spec;
    1403              : };
    1404              : 
    1405              : static const struct default_spec
    1406              :   option_default_specs[] = { OPTION_DEFAULT_SPECS };
    1407              : 
    1408              : struct user_specs
    1409              : {
    1410              :   struct user_specs *next;
    1411              :   const char *filename;
    1412              : };
    1413              : 
    1414              : static struct user_specs *user_specs_head, *user_specs_tail;
    1415              : 
    1416              : 
    1417              : /* Record the mapping from file suffixes for compilation specs.  */
    1418              : 
    1419              : struct compiler
    1420              : {
    1421              :   const char *suffix;           /* Use this compiler for input files
    1422              :                                    whose names end in this suffix.  */
    1423              : 
    1424              :   const char *spec;             /* To use this compiler, run this spec.  */
    1425              : 
    1426              :   const char *cpp_spec;         /* If non-NULL, substitute this spec
    1427              :                                    for `%C', rather than the usual
    1428              :                                    cpp_spec.  */
    1429              :   int combinable;               /* If nonzero, compiler can deal with
    1430              :                                     multiple source files at once (IMA).  */
    1431              :   int needs_preprocessing;       /* If nonzero, source files need to
    1432              :                                     be run through a preprocessor.  */
    1433              : };
    1434              : 
    1435              : /* Pointer to a vector of `struct compiler' that gives the spec for
    1436              :    compiling a file, based on its suffix.
    1437              :    A file that does not end in any of these suffixes will be passed
    1438              :    unchanged to the loader and nothing else will be done to it.
    1439              : 
    1440              :    An entry containing two 0s is used to terminate the vector.
    1441              : 
    1442              :    If multiple entries match a file, the last matching one is used.  */
    1443              : 
    1444              : static struct compiler *compilers;
    1445              : 
    1446              : /* Number of entries in `compilers', not counting the null terminator.  */
    1447              : 
    1448              : static int n_compilers;
    1449              : 
    1450              : /* The default list of file name suffixes and their compilation specs.  */
    1451              : 
    1452              : static const struct compiler default_compilers[] =
    1453              : {
    1454              :   /* Add lists of suffixes of known languages here.  If those languages
    1455              :      were not present when we built the driver, we will hit these copies
    1456              :      and be given a more meaningful error than "file not used since
    1457              :      linking is not done".  */
    1458              :   {".m",  "#Objective-C", 0, 0, 0}, {".mi",  "#Objective-C", 0, 0, 0},
    1459              :   {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
    1460              :   {".mii", "#Objective-C++", 0, 0, 0},
    1461              :   {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
    1462              :   {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
    1463              :   {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
    1464              :   {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
    1465              :   {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
    1466              :   {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
    1467              :   {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
    1468              :   {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0},
    1469              :   {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
    1470              :   {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0},
    1471              :   {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
    1472              :   {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0},
    1473              :   {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0},
    1474              :   {".r", "#Ratfor", 0, 0, 0},
    1475              :   {".go", "#Go", 0, 1, 0},
    1476              :   {".d", "#D", 0, 1, 0}, {".dd", "#D", 0, 1, 0}, {".di", "#D", 0, 1, 0},
    1477              :   {".mod", "#Modula-2", 0, 0, 0}, {".m2i", "#Modula-2", 0, 0, 0},
    1478              :   /* Next come the entries for C.  */
    1479              :   {".c", "@c", 0, 0, 1},
    1480              :   {"@c",
    1481              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1482              :       external preprocessor if -save-temps is given.  */
    1483              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1484              :       %{!E:%{!M:%{!MM:\
    1485              :           %{traditional:\
    1486              : %eGNU C no longer supports -traditional without -E}\
    1487              :       %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1488              :           %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1489              :             cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1490              :           %(cc1_options)}\
    1491              :       %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1492              :           cc1 %(cpp_unique_options) %(cc1_options)}}}\
    1493              :       %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
    1494              :   {"-",
    1495              :    "%{!E:%e-E or -x required when input is from standard input}\
    1496              :     %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
    1497              :   {".h", "@c-header", 0, 0, 0},
    1498              :   {"@c-header",
    1499              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1500              :       external preprocessor if -save-temps is given.  */
    1501              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1502              :       %{!E:%{!M:%{!MM:\
    1503              :           %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1504              :                 %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1505              :                     cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1506              :                         %(cc1_options)\
    1507              :                         %{!fsyntax-only:%{!S:-o %g.s} \
    1508              :                             %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1509              :                                                %W{o*:--output-pch %w%*}}%{!S:%V}}}\
    1510              :           %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1511              :                 cc1 %(cpp_unique_options) %(cc1_options)\
    1512              :                     %{!fsyntax-only:%{!S:-o %g.s} \
    1513              :                         %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1514              :                                            %W{o*:--output-pch %w%*}}%{!S:%V}}}}}}}}", 0, 0, 0},
    1515              :   {".i", "@cpp-output", 0, 0, 0},
    1516              :   {"@cpp-output",
    1517              :    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
    1518              :   {".s", "@assembler", 0, 0, 0},
    1519              :   {"@assembler",
    1520              :    "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
    1521              :   {".sx", "@assembler-with-cpp", 0, 0, 0},
    1522              :   {".S", "@assembler-with-cpp", 0, 0, 0},
    1523              :   {"@assembler-with-cpp",
    1524              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1525              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1526              :       %{E|M|MM:%(cpp_debug_options)}\
    1527              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1528              :        as %(asm_debug) %(asm_options) %|.s %A }}}}"
    1529              : #else
    1530              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1531              :       %{E|M|MM:%(cpp_debug_options)}\
    1532              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1533              :        as %(asm_debug) %(asm_options) %m.s %A }}}}"
    1534              : #endif
    1535              :    , 0, 0, 0},
    1536              : 
    1537              : #ifndef EXTRA_DEFAULT_COMPILERS
    1538              : #define EXTRA_DEFAULT_COMPILERS
    1539              : #endif
    1540              :   EXTRA_DEFAULT_COMPILERS
    1541              : 
    1542              : #include "specs.h"
    1543              :   /* Mark end of table.  */
    1544              :   {0, 0, 0, 0, 0}
    1545              : };
    1546              : 
    1547              : /* Number of elements in default_compilers, not counting the terminator.  */
    1548              : 
    1549              : static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
    1550              : 
    1551              : typedef char *char_p; /* For DEF_VEC_P.  */
    1552              : 
    1553              : /* A vector of options to give to the linker.
    1554              :    These options are accumulated by %x,
    1555              :    and substituted into the linker command with %X.  */
    1556              : static vec<char_p> linker_options;
    1557              : 
    1558              : /* A vector of options to give to the assembler.
    1559              :    These options are accumulated by -Wa,
    1560              :    and substituted into the assembler command with %Y.  */
    1561              : static vec<char_p> assembler_options;
    1562              : 
    1563              : /* A vector of options to give to the preprocessor.
    1564              :    These options are accumulated by -Wp,
    1565              :    and substituted into the preprocessor command with %Z.  */
    1566              : static vec<char_p> preprocessor_options;
    1567              : 
    1568              : static char *
    1569     27904855 : skip_whitespace (char *p)
    1570              : {
    1571     64675567 :   while (1)
    1572              :     {
    1573              :       /* A fully-blank line is a delimiter in the SPEC file and shouldn't
    1574              :          be considered whitespace.  */
    1575     64675567 :       if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
    1576      4681712 :         return p + 1;
    1577     59993855 :       else if (*p == '\n' || *p == ' ' || *p == '\t')
    1578     36652096 :         p++;
    1579     23341759 :       else if (*p == '#')
    1580              :         {
    1581      3681819 :           while (*p != '\n')
    1582      3563203 :             p++;
    1583       118616 :           p++;
    1584              :         }
    1585              :       else
    1586              :         break;
    1587              :     }
    1588              : 
    1589              :   return p;
    1590              : }
    1591              : /* Structures to keep track of prefixes to try when looking for files.  */
    1592              : 
    1593              : struct prefix_list
    1594              : {
    1595              :   const char *prefix;         /* String to prepend to the path.  */
    1596              :   struct prefix_list *next;   /* Next in linked list.  */
    1597              :   int require_machine_suffix; /* Don't use without machine_suffix.  */
    1598              :   /* 2 means try both machine_suffix and just_machine_suffix.  */
    1599              :   int priority;               /* Sort key - priority within list.  */
    1600              :   int os_multilib;            /* 1 if OS multilib scheme should be used,
    1601              :                                  0 for GCC multilib scheme.  */
    1602              : };
    1603              : 
    1604              : struct path_prefix
    1605              : {
    1606              :   struct prefix_list *plist;  /* List of prefixes to try */
    1607              :   int max_len;                /* Max length of a prefix in PLIST */
    1608              :   const char *name;           /* Name of this list (used in config stuff) */
    1609              : };
    1610              : 
    1611              : /* List of prefixes to try when looking for executables.  */
    1612              : 
    1613              : static struct path_prefix exec_prefixes = { 0, 0, "exec" };
    1614              : 
    1615              : /* List of prefixes to try when looking for startup (crt0) files.  */
    1616              : 
    1617              : static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };
    1618              : 
    1619              : /* List of prefixes to try when looking for include files.  */
    1620              : 
    1621              : static struct path_prefix include_prefixes = { 0, 0, "include" };
    1622              : 
    1623              : /* Suffix to attach to directories searched for commands.
    1624              :    This looks like `MACHINE/VERSION/'.  */
    1625              : 
    1626              : static const char *machine_suffix = 0;
    1627              : 
    1628              : /* Suffix to attach to directories searched for commands.
    1629              :    This is just `MACHINE/'.  */
    1630              : 
    1631              : static const char *just_machine_suffix = 0;
    1632              : 
    1633              : /* Adjusted value of GCC_EXEC_PREFIX envvar.  */
    1634              : 
    1635              : static const char *gcc_exec_prefix;
    1636              : 
    1637              : /* Adjusted value of standard_libexec_prefix.  */
    1638              : 
    1639              : static const char *gcc_libexec_prefix;
    1640              : 
    1641              : /* Default prefixes to attach to command names.  */
    1642              : 
    1643              : #ifndef STANDARD_STARTFILE_PREFIX_1
    1644              : #define STANDARD_STARTFILE_PREFIX_1 "/lib/"
    1645              : #endif
    1646              : #ifndef STANDARD_STARTFILE_PREFIX_2
    1647              : #define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
    1648              : #endif
    1649              : 
    1650              : #ifdef CROSS_DIRECTORY_STRUCTURE  /* Don't use these prefixes for a cross compiler.  */
    1651              : #undef MD_EXEC_PREFIX
    1652              : #undef MD_STARTFILE_PREFIX
    1653              : #undef MD_STARTFILE_PREFIX_1
    1654              : #endif
    1655              : 
    1656              : /* If no prefixes defined, use the null string, which will disable them.  */
    1657              : #ifndef MD_EXEC_PREFIX
    1658              : #define MD_EXEC_PREFIX ""
    1659              : #endif
    1660              : #ifndef MD_STARTFILE_PREFIX
    1661              : #define MD_STARTFILE_PREFIX ""
    1662              : #endif
    1663              : #ifndef MD_STARTFILE_PREFIX_1
    1664              : #define MD_STARTFILE_PREFIX_1 ""
    1665              : #endif
    1666              : 
    1667              : /* These directories are locations set at configure-time based on the
    1668              :    --prefix option provided to configure.  Their initializers are
    1669              :    defined in Makefile.in.  These paths are not *directly* used when
    1670              :    gcc_exec_prefix is set because, in that case, we know where the
    1671              :    compiler has been installed, and use paths relative to that
    1672              :    location instead.  */
    1673              : static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
    1674              : static const char *const standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
    1675              : static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
    1676              : static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
    1677              : 
    1678              : /* For native compilers, these are well-known paths containing
    1679              :    components that may be provided by the system.  For cross
    1680              :    compilers, these paths are not used.  */
    1681              : static const char *md_exec_prefix = MD_EXEC_PREFIX;
    1682              : static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
    1683              : static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
    1684              : static const char *const standard_startfile_prefix_1
    1685              :   = STANDARD_STARTFILE_PREFIX_1;
    1686              : static const char *const standard_startfile_prefix_2
    1687              :   = STANDARD_STARTFILE_PREFIX_2;
    1688              : 
    1689              : /* A relative path to be used in finding the location of tools
    1690              :    relative to the driver.  */
    1691              : static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
    1692              : 
    1693              : /* A prefix to be used when this is an accelerator compiler.  */
    1694              : static const char *const accel_dir_suffix = ACCEL_DIR_SUFFIX;
    1695              : 
    1696              : /* Subdirectory to use for locating libraries.  Set by
    1697              :    set_multilib_dir based on the compilation options.  */
    1698              : 
    1699              : static const char *multilib_dir;
    1700              : 
    1701              : /* Subdirectory to use for locating libraries in OS conventions.  Set by
    1702              :    set_multilib_dir based on the compilation options.  */
    1703              : 
    1704              : static const char *multilib_os_dir;
    1705              : 
    1706              : /* Subdirectory to use for locating libraries in multiarch conventions.  Set by
    1707              :    set_multilib_dir based on the compilation options.  */
    1708              : 
    1709              : static const char *multiarch_dir;
    1710              : 
    1711              : /* Structure to keep track of the specs that have been defined so far.
    1712              :    These are accessed using %(specname) in a compiler or link
    1713              :    spec.  */
    1714              : 
    1715              : struct spec_list
    1716              : {
    1717              :                                 /* The following 2 fields must be first */
    1718              :                                 /* to allow EXTRA_SPECS to be initialized */
    1719              :   const char *name;             /* name of the spec.  */
    1720              :   const char *ptr;              /* available ptr if no static pointer */
    1721              : 
    1722              :                                 /* The following fields are not initialized */
    1723              :                                 /* by EXTRA_SPECS */
    1724              :   const char **ptr_spec;        /* pointer to the spec itself.  */
    1725              :   struct spec_list *next;       /* Next spec in linked list.  */
    1726              :   int name_len;                 /* length of the name */
    1727              :   bool user_p;                  /* whether string come from file spec.  */
    1728              :   bool alloc_p;                 /* whether string was allocated */
    1729              :   const char *default_ptr;      /* The default value of *ptr_spec.  */
    1730              : };
    1731              : 
    1732              : #define INIT_STATIC_SPEC(NAME,PTR) \
    1733              :   { NAME, NULL, PTR, (struct spec_list *) 0, sizeof (NAME) - 1, false, false, \
    1734              :     *PTR }
    1735              : 
    1736              : /* List of statically defined specs.  */
    1737              : static struct spec_list static_specs[] =
    1738              : {
    1739              :   INIT_STATIC_SPEC ("asm",                    &asm_spec),
    1740              :   INIT_STATIC_SPEC ("asm_debug",              &asm_debug),
    1741              :   INIT_STATIC_SPEC ("asm_debug_option",               &asm_debug_option),
    1742              :   INIT_STATIC_SPEC ("asm_final",              &asm_final_spec),
    1743              :   INIT_STATIC_SPEC ("asm_options",            &asm_options),
    1744              :   INIT_STATIC_SPEC ("invoke_as",              &invoke_as),
    1745              :   INIT_STATIC_SPEC ("cpp",                    &cpp_spec),
    1746              :   INIT_STATIC_SPEC ("cpp_options",            &cpp_options),
    1747              :   INIT_STATIC_SPEC ("cpp_debug_options",      &cpp_debug_options),
    1748              :   INIT_STATIC_SPEC ("cpp_unique_options",     &cpp_unique_options),
    1749              :   INIT_STATIC_SPEC ("trad_capable_cpp",               &trad_capable_cpp),
    1750              :   INIT_STATIC_SPEC ("cc1",                    &cc1_spec),
    1751              :   INIT_STATIC_SPEC ("cc1_options",            &cc1_options),
    1752              :   INIT_STATIC_SPEC ("cc1plus",                        &cc1plus_spec),
    1753              :   INIT_STATIC_SPEC ("link_gcc_c_sequence",    &link_gcc_c_sequence_spec),
    1754              :   INIT_STATIC_SPEC ("link_ssp",                       &link_ssp_spec),
    1755              :   INIT_STATIC_SPEC ("endfile",                        &endfile_spec),
    1756              :   INIT_STATIC_SPEC ("link",                   &link_spec),
    1757              :   INIT_STATIC_SPEC ("lib",                    &lib_spec),
    1758              :   INIT_STATIC_SPEC ("link_gomp",              &link_gomp_spec),
    1759              :   INIT_STATIC_SPEC ("libgcc",                 &libgcc_spec),
    1760              :   INIT_STATIC_SPEC ("startfile",              &startfile_spec),
    1761              :   INIT_STATIC_SPEC ("cross_compile",          &cross_compile),
    1762              :   INIT_STATIC_SPEC ("version",                        &compiler_version),
    1763              :   INIT_STATIC_SPEC ("multilib",                       &multilib_select),
    1764              :   INIT_STATIC_SPEC ("multilib_defaults",      &multilib_defaults),
    1765              :   INIT_STATIC_SPEC ("multilib_extra",         &multilib_extra),
    1766              :   INIT_STATIC_SPEC ("multilib_matches",               &multilib_matches),
    1767              :   INIT_STATIC_SPEC ("multilib_exclusions",    &multilib_exclusions),
    1768              :   INIT_STATIC_SPEC ("multilib_options",               &multilib_options),
    1769              :   INIT_STATIC_SPEC ("multilib_reuse",         &multilib_reuse),
    1770              :   INIT_STATIC_SPEC ("linker",                 &linker_name_spec),
    1771              :   INIT_STATIC_SPEC ("linker_plugin_file",     &linker_plugin_file_spec),
    1772              :   INIT_STATIC_SPEC ("lto_wrapper",            &lto_wrapper_spec),
    1773              :   INIT_STATIC_SPEC ("lto_gcc",                        &lto_gcc_spec),
    1774              :   INIT_STATIC_SPEC ("post_link",              &post_link_spec),
    1775              :   INIT_STATIC_SPEC ("link_libgcc",            &link_libgcc_spec),
    1776              :   INIT_STATIC_SPEC ("md_exec_prefix",         &md_exec_prefix),
    1777              :   INIT_STATIC_SPEC ("md_startfile_prefix",    &md_startfile_prefix),
    1778              :   INIT_STATIC_SPEC ("md_startfile_prefix_1",  &md_startfile_prefix_1),
    1779              :   INIT_STATIC_SPEC ("startfile_prefix_spec",  &startfile_prefix_spec),
    1780              :   INIT_STATIC_SPEC ("sysroot_spec",             &sysroot_spec),
    1781              :   INIT_STATIC_SPEC ("sysroot_suffix_spec",    &sysroot_suffix_spec),
    1782              :   INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec",       &sysroot_hdrs_suffix_spec),
    1783              :   INIT_STATIC_SPEC ("self_spec",              &self_spec),
    1784              : };
    1785              : 
    1786              : #ifdef EXTRA_SPECS              /* additional specs needed */
    1787              : /* Structure to keep track of just the first two args of a spec_list.
    1788              :    That is all that the EXTRA_SPECS macro gives us.  */
    1789              : struct spec_list_1
    1790              : {
    1791              :   const char *const name;
    1792              :   const char *const ptr;
    1793              : };
    1794              : 
    1795              : static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
    1796              : static struct spec_list *extra_specs = (struct spec_list *) 0;
    1797              : #endif
    1798              : 
    1799              : /* List of dynamically allocates specs that have been defined so far.  */
    1800              : 
    1801              : static struct spec_list *specs = (struct spec_list *) 0;
    1802              : 
    1803              : /* List of static spec functions.  */
    1804              : 
    1805              : static const struct spec_function static_spec_functions[] =
    1806              : {
    1807              :   { "getenv",                   getenv_spec_function },
    1808              :   { "if-exists",              if_exists_spec_function },
    1809              :   { "if-exists-else",         if_exists_else_spec_function },
    1810              :   { "if-exists-then-else",    if_exists_then_else_spec_function },
    1811              :   { "sanitize",                       sanitize_spec_function },
    1812              :   { "replace-outfile",                replace_outfile_spec_function },
    1813              :   { "remove-outfile",         remove_outfile_spec_function },
    1814              :   { "version-compare",                version_compare_spec_function },
    1815              :   { "include",                        include_spec_function },
    1816              :   { "find-file",              find_file_spec_function },
    1817              :   { "find-plugindir",         find_plugindir_spec_function },
    1818              :   { "print-asm-header",               print_asm_header_spec_function },
    1819              :   { "compare-debug-dump-opt", compare_debug_dump_opt_spec_function },
    1820              :   { "compare-debug-self-opt", compare_debug_self_opt_spec_function },
    1821              :   { "pass-through-libs",      pass_through_libs_spec_func },
    1822              :   { "dumps",                    dumps_spec_func },
    1823              :   { "gt",                     greater_than_spec_func },
    1824              :   { "debug-level-gt",         debug_level_greater_than_spec_func },
    1825              :   { "dwarf-version-gt",               dwarf_version_greater_than_spec_func },
    1826              :   { "fortran-preinclude-file",        find_fortran_preinclude_file},
    1827              :   { "join",                   join_spec_func},
    1828              : #ifdef EXTRA_SPEC_FUNCTIONS
    1829              :   EXTRA_SPEC_FUNCTIONS
    1830              : #endif
    1831              :   { 0, 0 }
    1832              : };
    1833              : 
    1834              : static int processing_spec_function;
    1835              : 
    1836              : /* Add appropriate libgcc specs to OBSTACK, taking into account
    1837              :    various permutations of -shared-libgcc, -shared, and such.  */
    1838              : 
    1839              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1840              : 
    1841              : #ifndef USE_LD_AS_NEEDED
    1842              : #define USE_LD_AS_NEEDED 0
    1843              : #endif
    1844              : 
    1845              : static void
    1846         1093 : init_gcc_specs (struct obstack *obstack, const char *shared_name,
    1847              :                 const char *static_name, const char *eh_name)
    1848              : {
    1849         1093 :   char *buf;
    1850              : 
    1851              : #if USE_LD_AS_NEEDED
    1852              : #if defined(USE_LD_AS_NEEDED_LDSCRIPT) && !defined(USE_LIBUNWIND_EXCEPTIONS)
    1853         1093 :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1854              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1855              :                 "%{!shared-libgcc:",
    1856              :                 static_name, " ",
    1857              :                 shared_name, "_asneeded}"
    1858              :                 "%{shared-libgcc:",
    1859              :                 shared_name, "%{!shared: ", static_name, "}"
    1860              :                 "}}"
    1861              : #else
    1862              :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1863              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1864              :                 "%{!shared-libgcc:",
    1865              :                 static_name, " " LD_AS_NEEDED_OPTION " ",
    1866              :                 shared_name, " " LD_NO_AS_NEEDED_OPTION
    1867              :                 "}"
    1868              :                 "%{shared-libgcc:",
    1869              :                 shared_name, "%{!shared: ", static_name, "}"
    1870              :                 "}}"
    1871              : #endif
    1872              : #else
    1873              :   buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name, "}"
    1874              :                 "%{!static:%{!static-libgcc:"
    1875              :                 "%{!shared:"
    1876              :                 "%{!shared-libgcc:", static_name, " ", eh_name, "}"
    1877              :                 "%{shared-libgcc:", shared_name, " ", static_name, "}"
    1878              :                 "}"
    1879              : #ifdef LINK_EH_SPEC
    1880              :                 "%{shared:"
    1881              :                 "%{shared-libgcc:", shared_name, "}"
    1882              :                 "%{!shared-libgcc:", static_name, "}"
    1883              :                 "}"
    1884              : #else
    1885              :                 "%{shared:", shared_name, "}"
    1886              : #endif
    1887              : #endif
    1888              :                 "}}", NULL);
    1889              : 
    1890         1093 :   obstack_grow (obstack, buf, strlen (buf));
    1891         1093 :   free (buf);
    1892         1093 : }
    1893              : #endif /* ENABLE_SHARED_LIBGCC */
    1894              : 
    1895              : /* Initialize the specs lookup routines.  */
    1896              : 
    1897              : static void
    1898         1093 : init_spec (void)
    1899              : {
    1900         1093 :   struct spec_list *next = (struct spec_list *) 0;
    1901         1093 :   struct spec_list *sl   = (struct spec_list *) 0;
    1902         1093 :   int i;
    1903              : 
    1904         1093 :   if (specs)
    1905              :     return;                     /* Already initialized.  */
    1906              : 
    1907         1093 :   if (verbose_flag)
    1908           63 :     fnotice (stderr, "Using built-in specs.\n");
    1909              : 
    1910              : #ifdef EXTRA_SPECS
    1911         1093 :   extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1));
    1912              : 
    1913         2186 :   for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
    1914              :     {
    1915         1093 :       sl = &extra_specs[i];
    1916         1093 :       sl->name = extra_specs_1[i].name;
    1917         1093 :       sl->ptr = extra_specs_1[i].ptr;
    1918         1093 :       sl->next = next;
    1919         1093 :       sl->name_len = strlen (sl->name);
    1920         1093 :       sl->ptr_spec = &sl->ptr;
    1921         1093 :       gcc_assert (sl->ptr_spec != NULL);
    1922         1093 :       sl->default_ptr = sl->ptr;
    1923         1093 :       next = sl;
    1924              :     }
    1925              : #endif
    1926              : 
    1927        50278 :   for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    1928              :     {
    1929        49185 :       sl = &static_specs[i];
    1930        49185 :       sl->next = next;
    1931        49185 :       next = sl;
    1932              :     }
    1933              : 
    1934              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1935              :   /* ??? If neither -shared-libgcc nor --static-libgcc was
    1936              :      seen, then we should be making an educated guess.  Some proposed
    1937              :      heuristics for ELF include:
    1938              : 
    1939              :         (1) If "-Wl,--export-dynamic", then it's a fair bet that the
    1940              :             program will be doing dynamic loading, which will likely
    1941              :             need the shared libgcc.
    1942              : 
    1943              :         (2) If "-ldl", then it's also a fair bet that we're doing
    1944              :             dynamic loading.
    1945              : 
    1946              :         (3) For each ET_DYN we're linking against (either through -lfoo
    1947              :             or /some/path/foo.so), check to see whether it or one of
    1948              :             its dependencies depends on a shared libgcc.
    1949              : 
    1950              :         (4) If "-shared"
    1951              : 
    1952              :             If the runtime is fixed to look for program headers instead
    1953              :             of calling __register_frame_info at all, for each object,
    1954              :             use the shared libgcc if any EH symbol referenced.
    1955              : 
    1956              :             If crtstuff is fixed to not invoke __register_frame_info
    1957              :             automatically, for each object, use the shared libgcc if
    1958              :             any non-empty unwind section found.
    1959              : 
    1960              :      Doing any of this probably requires invoking an external program to
    1961              :      do the actual object file scanning.  */
    1962         1093 :   {
    1963         1093 :     const char *p = libgcc_spec;
    1964         1093 :     int in_sep = 1;
    1965              : 
    1966              :     /* Transform the extant libgcc_spec into one that uses the shared libgcc
    1967              :        when given the proper command line arguments.  */
    1968         2186 :     while (*p)
    1969              :       {
    1970         1093 :         if (in_sep && *p == '-' && startswith (p, "-lgcc"))
    1971              :           {
    1972         1093 :             init_gcc_specs (&obstack,
    1973              :                             "-lgcc_s"
    1974              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1975              :                             " -lunwind"
    1976              : #endif
    1977              :                             ,
    1978              :                             "-lgcc",
    1979              :                             "-lgcc_eh"
    1980              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1981              : # ifdef HAVE_LD_STATIC_DYNAMIC
    1982              :                             " %{!static:%{!static-pie:" LD_STATIC_OPTION "}} -lunwind"
    1983              :                             " %{!static:%{!static-pie:" LD_DYNAMIC_OPTION "}}"
    1984              : # else
    1985              :                             " -lunwind"
    1986              : # endif
    1987              : #endif
    1988              :                             );
    1989              : 
    1990         1093 :             p += 5;
    1991         1093 :             in_sep = 0;
    1992              :           }
    1993            0 :         else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
    1994              :           {
    1995              :             /* Ug.  We don't know shared library extensions.  Hope that
    1996              :                systems that use this form don't do shared libraries.  */
    1997            0 :             init_gcc_specs (&obstack,
    1998              :                             "-lgcc_s",
    1999              :                             "libgcc.a%s",
    2000              :                             "libgcc_eh.a%s"
    2001              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    2002              :                             " -lunwind"
    2003              : #endif
    2004              :                             );
    2005            0 :             p += 10;
    2006            0 :             in_sep = 0;
    2007              :           }
    2008              :         else
    2009              :           {
    2010            0 :             obstack_1grow (&obstack, *p);
    2011            0 :             in_sep = (*p == ' ');
    2012            0 :             p += 1;
    2013              :           }
    2014              :       }
    2015              : 
    2016         1093 :     obstack_1grow (&obstack, '\0');
    2017         1093 :     libgcc_spec = XOBFINISH (&obstack, const char *);
    2018              :   }
    2019              : #endif
    2020              : #ifdef USE_AS_TRADITIONAL_FORMAT
    2021              :   /* Prepend "--traditional-format" to whatever asm_spec we had before.  */
    2022              :   {
    2023              :     static const char tf[] = "--traditional-format ";
    2024              :     obstack_grow (&obstack, tf, sizeof (tf) - 1);
    2025              :     obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
    2026              :     asm_spec = XOBFINISH (&obstack, const char *);
    2027              :   }
    2028              : #endif
    2029              : 
    2030              : #if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC || \
    2031              :     defined LINKER_HASH_STYLE
    2032              : # ifdef LINK_BUILDID_SPEC
    2033              :   /* Prepend LINK_BUILDID_SPEC to whatever link_spec we had before.  */
    2034              :   obstack_grow (&obstack, LINK_BUILDID_SPEC, sizeof (LINK_BUILDID_SPEC) - 1);
    2035              : # endif
    2036              : # ifdef LINK_EH_SPEC
    2037              :   /* Prepend LINK_EH_SPEC to whatever link_spec we had before.  */
    2038         1093 :   obstack_grow (&obstack, LINK_EH_SPEC, sizeof (LINK_EH_SPEC) - 1);
    2039              : # endif
    2040              : # ifdef LINKER_HASH_STYLE
    2041              :   /* Prepend --hash-style=LINKER_HASH_STYLE to whatever link_spec we had
    2042              :      before.  */
    2043              :   {
    2044              :     static const char hash_style[] = "--hash-style=";
    2045              :     obstack_grow (&obstack, hash_style, sizeof (hash_style) - 1);
    2046              :     obstack_grow (&obstack, LINKER_HASH_STYLE, sizeof (LINKER_HASH_STYLE) - 1);
    2047              :     obstack_1grow (&obstack, ' ');
    2048              :   }
    2049              : # endif
    2050         1093 :   obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    2051         1093 :   link_spec = XOBFINISH (&obstack, const char *);
    2052              : #endif
    2053              : 
    2054         1093 :   specs = sl;
    2055              : }
    2056              : 
    2057              : /* Update the entry for SPEC in the static_specs table to point to VALUE,
    2058              :    ensuring that we free the previous value if necessary.  Set alloc_p for the
    2059              :    entry to ALLOC_P: this determines whether we take ownership of VALUE (i.e.
    2060              :    whether we need to free it later on).  */
    2061              : static void
    2062       204567 : set_static_spec (const char **spec, const char *value, bool alloc_p)
    2063              : {
    2064       204567 :   struct spec_list *sl = NULL;
    2065              : 
    2066      7064970 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
    2067              :     {
    2068      7064970 :       if (static_specs[i].ptr_spec == spec)
    2069              :         {
    2070       204567 :           sl = static_specs + i;
    2071       204567 :           break;
    2072              :         }
    2073              :     }
    2074              : 
    2075            0 :   gcc_assert (sl);
    2076              : 
    2077       204567 :   if (sl->alloc_p)
    2078              :     {
    2079       204567 :       const char *old = *spec;
    2080       204567 :       free (const_cast <char *> (old));
    2081              :     }
    2082              : 
    2083       204567 :   *spec = value;
    2084       204567 :   sl->alloc_p = alloc_p;
    2085       204567 : }
    2086              : 
    2087              : /* Update a static spec to a new string, taking ownership of that
    2088              :    string's memory.  */
    2089       105096 : static void set_static_spec_owned (const char **spec, const char *val)
    2090              : {
    2091            0 :   return set_static_spec (spec, val, true);
    2092              : }
    2093              : 
    2094              : /* Update a static spec to point to a new value, but don't take
    2095              :    ownership of (i.e. don't free) that string.  */
    2096        99471 : static void set_static_spec_shared (const char **spec, const char *val)
    2097              : {
    2098            0 :   return set_static_spec (spec, val, false);
    2099              : }
    2100              : 
    2101              : 
    2102              : /* Change the value of spec NAME to SPEC.  If SPEC is empty, then the spec is
    2103              :    removed; If the spec starts with a + then SPEC is added to the end of the
    2104              :    current spec.  */
    2105              : 
    2106              : static void
    2107     13508639 : set_spec (const char *name, const char *spec, bool user_p)
    2108              : {
    2109     13508639 :   struct spec_list *sl;
    2110     13508639 :   const char *old_spec;
    2111     13508639 :   int name_len = strlen (name);
    2112     13508639 :   int i;
    2113              : 
    2114              :   /* If this is the first call, initialize the statically allocated specs.  */
    2115     13508639 :   if (!specs)
    2116              :     {
    2117              :       struct spec_list *next = (struct spec_list *) 0;
    2118     13459922 :       for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    2119              :         {
    2120     13167315 :           sl = &static_specs[i];
    2121     13167315 :           sl->next = next;
    2122     13167315 :           next = sl;
    2123              :         }
    2124       292607 :       specs = sl;
    2125              :     }
    2126              : 
    2127              :   /* See if the spec already exists.  */
    2128    317887508 :   for (sl = specs; sl; sl = sl->next)
    2129    317573510 :     if (name_len == sl->name_len && !strcmp (sl->name, name))
    2130              :       break;
    2131              : 
    2132     13508639 :   if (!sl)
    2133              :     {
    2134              :       /* Not found - make it.  */
    2135       313998 :       sl = XNEW (struct spec_list);
    2136       313998 :       sl->name = xstrdup (name);
    2137       313998 :       sl->name_len = name_len;
    2138       313998 :       sl->ptr_spec = &sl->ptr;
    2139       313998 :       sl->alloc_p = 0;
    2140       313998 :       *(sl->ptr_spec) = "";
    2141       313998 :       sl->next = specs;
    2142       313998 :       sl->default_ptr = NULL;
    2143       313998 :       specs = sl;
    2144              :     }
    2145              : 
    2146     13508639 :   old_spec = *(sl->ptr_spec);
    2147     13508639 :   *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
    2148            1 :                      ? concat (old_spec, spec + 1, NULL)
    2149     13508638 :                      : xstrdup (spec));
    2150              : 
    2151              : #ifdef DEBUG_SPECS
    2152              :   if (verbose_flag)
    2153              :     fnotice (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
    2154              : #endif
    2155              : 
    2156              :   /* Free the old spec.  */
    2157     13508639 :   if (old_spec && sl->alloc_p)
    2158         6028 :     free (const_cast<char *> (old_spec));
    2159              : 
    2160     13508639 :   sl->user_p = user_p;
    2161     13508639 :   sl->alloc_p = true;
    2162     13508639 : }
    2163              : 
    2164              : /* Accumulate a command (program name and args), and run it.  */
    2165              : 
    2166              : typedef const char *const_char_p; /* For DEF_VEC_P.  */
    2167              : 
    2168              : /* Vector of pointers to arguments in the current line of specifications.  */
    2169              : static vec<const_char_p> argbuf;
    2170              : 
    2171              : /* Likewise, but for the current @file.  */
    2172              : static vec<const_char_p> at_file_argbuf;
    2173              : 
    2174              : /* Whether an @file is currently open.  */
    2175              : static bool in_at_file = false;
    2176              : 
    2177              : /* Were the options -c, -S or -E passed.  */
    2178              : static int have_c = 0;
    2179              : 
    2180              : /* Was the option -o passed.  */
    2181              : static int have_o = 0;
    2182              : 
    2183              : /* Was the option -E passed.  */
    2184              : static int have_E = 0;
    2185              : 
    2186              : /* Pointer to output file name passed in with -o. */
    2187              : static const char *output_file = 0;
    2188              : 
    2189              : /* Pointer to input file name passed in with -truncate.
    2190              :    This file should be truncated after linking. */
    2191              : static const char *totruncate_file = 0;
    2192              : 
    2193              : /* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
    2194              :    temp file.  If the HOST_BIT_BUCKET is used for %j, no entry is made for
    2195              :    it here.  */
    2196              : 
    2197              : static struct temp_name {
    2198              :   const char *suffix;   /* suffix associated with the code.  */
    2199              :   int length;           /* strlen (suffix).  */
    2200              :   int unique;           /* Indicates whether %g or %u/%U was used.  */
    2201              :   const char *filename; /* associated filename.  */
    2202              :   int filename_length;  /* strlen (filename).  */
    2203              :   struct temp_name *next;
    2204              : } *temp_names;
    2205              : 
    2206              : /* Number of commands executed so far.  */
    2207              : 
    2208              : static int execution_count;
    2209              : 
    2210              : /* Number of commands that exited with a signal.  */
    2211              : 
    2212              : static int signal_count;
    2213              : 
    2214              : /* Allocate the argument vector.  */
    2215              : 
    2216              : static void
    2217      2349838 : alloc_args (void)
    2218              : {
    2219      2349838 :   argbuf.create (10);
    2220      2349838 :   at_file_argbuf.create (10);
    2221      2349838 : }
    2222              : 
    2223              : /* Clear out the vector of arguments (after a command is executed).  */
    2224              : 
    2225              : static void
    2226      5518958 : clear_args (void)
    2227              : {
    2228      5518958 :   argbuf.truncate (0);
    2229      5518958 :   at_file_argbuf.truncate (0);
    2230      5518958 : }
    2231              : 
    2232              : /* Add one argument to the vector at the end.
    2233              :    This is done when a space is seen or at the end of the line.
    2234              :    If DELETE_ALWAYS is nonzero, the arg is a filename
    2235              :     and the file should be deleted eventually.
    2236              :    If DELETE_FAILURE is nonzero, the arg is a filename
    2237              :     and the file should be deleted if this compilation fails.  */
    2238              : 
    2239              : static void
    2240     19171988 : store_arg (const char *arg, int delete_always, int delete_failure)
    2241              : {
    2242     19171988 :   if (in_at_file)
    2243        13353 :     at_file_argbuf.safe_push (arg);
    2244              :   else
    2245     19158635 :     argbuf.safe_push (arg);
    2246              : 
    2247     19171988 :   if (delete_always || delete_failure)
    2248              :     {
    2249       514841 :       const char *p;
    2250              :       /* If the temporary file we should delete is specified as
    2251              :          part of a joined argument extract the filename.  */
    2252       514841 :       if (arg[0] == '-'
    2253       514841 :           && (p = strrchr (arg, '=')))
    2254        90347 :         arg = p + 1;
    2255       514841 :       record_temp_file (arg, delete_always, delete_failure);
    2256              :     }
    2257     19171988 : }
    2258              : 
    2259              : /* Open a temporary @file into which subsequent arguments will be stored.  */
    2260              : 
    2261              : static void
    2262        12301 : open_at_file (void)
    2263              : {
    2264        12301 :    if (in_at_file)
    2265            0 :      fatal_error (input_location, "cannot open nested response file");
    2266              :    else
    2267        12301 :      in_at_file = true;
    2268        12301 : }
    2269              : 
    2270              : /* Create a temporary @file name.  */
    2271              : 
    2272        12291 : static char *make_at_file (void)
    2273              : {
    2274        12291 :   static int fileno = 0;
    2275        12291 :   char filename[20];
    2276        12291 :   const char *base, *ext;
    2277              : 
    2278        12291 :   if (!save_temps_flag)
    2279        12253 :     return make_temp_file ("");
    2280              : 
    2281           38 :   base = dumpbase;
    2282           38 :   if (!(base && *base))
    2283           11 :     base = dumpdir;
    2284           38 :   if (!(base && *base))
    2285            0 :     base = "a";
    2286              : 
    2287           38 :   sprintf (filename, ".args.%d", fileno++);
    2288           38 :   ext = filename;
    2289              : 
    2290           38 :   if (base == dumpdir && dumpdir_trailing_dash_added)
    2291           38 :     ext++;
    2292              : 
    2293           38 :   return concat (base, ext, NULL);
    2294              : }
    2295              : 
    2296              : /* Close the temporary @file and add @file to the argument list.  */
    2297              : 
    2298              : static void
    2299        12301 : close_at_file (void)
    2300              : {
    2301        12301 :   if (!in_at_file)
    2302            0 :     fatal_error (input_location, "cannot close nonexistent response file");
    2303              : 
    2304        12301 :   in_at_file = false;
    2305              : 
    2306        12301 :   const unsigned int n_args = at_file_argbuf.length ();
    2307        12301 :   if (n_args == 0)
    2308              :     return;
    2309              : 
    2310        12291 :   char **argv = XALLOCAVEC (char *, n_args + 1);
    2311        12291 :   char *temp_file = make_at_file ();
    2312        12291 :   char *at_argument = concat ("@", temp_file, NULL);
    2313        12291 :   FILE *f = fopen (temp_file, "w");
    2314        12291 :   int status;
    2315        12291 :   unsigned int i;
    2316              : 
    2317              :   /* Copy the strings over.  */
    2318        37935 :   for (i = 0; i < n_args; i++)
    2319        13353 :     argv[i] = const_cast<char *> (at_file_argbuf[i]);
    2320        12291 :   argv[i] = NULL;
    2321              : 
    2322        12291 :   at_file_argbuf.truncate (0);
    2323              : 
    2324        12291 :   if (f == NULL)
    2325            0 :     fatal_error (input_location, "could not open temporary response file %s",
    2326              :                  temp_file);
    2327              : 
    2328        12291 :   status = writeargv (argv, f);
    2329              : 
    2330        12291 :   if (status)
    2331            0 :     fatal_error (input_location,
    2332              :                  "could not write to temporary response file %s",
    2333              :                  temp_file);
    2334              : 
    2335        12291 :   status = fclose (f);
    2336              : 
    2337        12291 :   if (status == EOF)
    2338            0 :     fatal_error (input_location, "could not close temporary response file %s",
    2339              :                  temp_file);
    2340              : 
    2341        12291 :   store_arg (at_argument, 0, 0);
    2342              : 
    2343        12291 :   record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
    2344              : }
    2345              : 
    2346              : /* Load specs from a file name named FILENAME, replacing occurrences of
    2347              :    various different types of line-endings, \r\n, \n\r and just \r, with
    2348              :    a single \n.  */
    2349              : 
    2350              : static char *
    2351       323662 : load_specs (const char *filename)
    2352              : {
    2353       323662 :   int desc;
    2354       323662 :   int readlen;
    2355       323662 :   struct stat statbuf;
    2356       323662 :   char *buffer;
    2357       323662 :   char *buffer_p;
    2358       323662 :   char *specs;
    2359       323662 :   char *specs_p;
    2360              : 
    2361       323662 :   if (verbose_flag)
    2362         1486 :     fnotice (stderr, "Reading specs from %s\n", filename);
    2363              : 
    2364              :   /* Open and stat the file.  */
    2365       323662 :   desc = open (filename, O_RDONLY, 0);
    2366       323662 :   if (desc < 0)
    2367              :     {
    2368            1 :     failed:
    2369              :       /* This leaves DESC open, but the OS will save us.  */
    2370            1 :       fatal_error (input_location, "cannot read spec file %qs: %m", filename);
    2371              :     }
    2372              : 
    2373       323661 :   if (stat (filename, &statbuf) < 0)
    2374            0 :     goto failed;
    2375              : 
    2376              :   /* Read contents of file into BUFFER.  */
    2377       323661 :   buffer = XNEWVEC (char, statbuf.st_size + 1);
    2378       323661 :   readlen = read (desc, buffer, (unsigned) statbuf.st_size);
    2379       323661 :   if (readlen < 0)
    2380            0 :     goto failed;
    2381       323661 :   buffer[readlen] = 0;
    2382       323661 :   close (desc);
    2383              : 
    2384       323661 :   specs = XNEWVEC (char, readlen + 1);
    2385       323661 :   specs_p = specs;
    2386   2942705386 :   for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
    2387              :     {
    2388   2942381725 :       int skip = 0;
    2389   2942381725 :       char c = *buffer_p;
    2390   2942381725 :       if (c == '\r')
    2391              :         {
    2392            0 :           if (buffer_p > buffer && *(buffer_p - 1) == '\n')  /* \n\r */
    2393              :             skip = 1;
    2394            0 :           else if (*(buffer_p + 1) == '\n')                     /* \r\n */
    2395              :             skip = 1;
    2396              :           else                                                  /* \r */
    2397              :             c = '\n';
    2398              :         }
    2399              :       if (! skip)
    2400   2942381725 :         *specs_p++ = c;
    2401              :     }
    2402       323661 :   *specs_p = '\0';
    2403              : 
    2404       323661 :   free (buffer);
    2405       323661 :   return (specs);
    2406              : }
    2407              : 
    2408              : /* Read compilation specs from a file named FILENAME,
    2409              :    replacing the default ones.
    2410              : 
    2411              :    A suffix which starts with `*' is a definition for
    2412              :    one of the machine-specific sub-specs.  The "suffix" should be
    2413              :    *asm, *cc1, *cpp, *link, *startfile, etc.
    2414              :    The corresponding spec is stored in asm_spec, etc.,
    2415              :    rather than in the `compilers' vector.
    2416              : 
    2417              :    Anything invalid in the file is a fatal error.  */
    2418              : 
    2419              : static void
    2420       323662 : read_specs (const char *filename, bool main_p, bool user_p)
    2421              : {
    2422       323662 :   char *buffer;
    2423       323662 :   char *p;
    2424              : 
    2425       323662 :   buffer = load_specs (filename);
    2426              : 
    2427              :   /* Scan BUFFER for specs, putting them in the vector.  */
    2428       323662 :   p = buffer;
    2429     14124907 :   while (1)
    2430              :     {
    2431     14124907 :       char *suffix;
    2432     14124907 :       char *spec;
    2433     14124907 :       char *in, *out, *p1, *p2, *p3;
    2434              : 
    2435              :       /* Advance P in BUFFER to the next nonblank nocomment line.  */
    2436     14124907 :       p = skip_whitespace (p);
    2437     14124907 :       if (*p == 0)
    2438              :         break;
    2439              : 
    2440              :       /* Is this a special command that starts with '%'? */
    2441              :       /* Don't allow this for the main specs file, since it would
    2442              :          encourage people to overwrite it.  */
    2443     13801246 :       if (*p == '%' && !main_p)
    2444              :         {
    2445       425960 :           p1 = p;
    2446       425960 :           while (*p && *p != '\n')
    2447       404662 :             p++;
    2448              : 
    2449              :           /* Skip '\n'.  */
    2450        21298 :           p++;
    2451              : 
    2452        21298 :           if (startswith (p1, "%include")
    2453        21298 :               && (p1[sizeof "%include" - 1] == ' '
    2454            0 :                   || p1[sizeof "%include" - 1] == '\t'))
    2455              :             {
    2456            0 :               char *new_filename;
    2457              : 
    2458            0 :               p1 += sizeof ("%include");
    2459            0 :               while (*p1 == ' ' || *p1 == '\t')
    2460            0 :                 p1++;
    2461              : 
    2462            0 :               if (*p1++ != '<' || p[-2] != '>')
    2463            0 :                 fatal_error (input_location,
    2464              :                              "specs %%include syntax malformed after "
    2465            0 :                              "%td characters", p1 - buffer + 1);
    2466              : 
    2467            0 :               p[-2] = '\0';
    2468            0 :               new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
    2469            0 :               read_specs (new_filename ? new_filename : p1, false, user_p);
    2470            0 :               continue;
    2471            0 :             }
    2472        21298 :           else if (startswith (p1, "%include_noerr")
    2473        21298 :                    && (p1[sizeof "%include_noerr" - 1] == ' '
    2474            0 :                        || p1[sizeof "%include_noerr" - 1] == '\t'))
    2475              :             {
    2476            0 :               char *new_filename;
    2477              : 
    2478            0 :               p1 += sizeof "%include_noerr";
    2479            0 :               while (*p1 == ' ' || *p1 == '\t')
    2480            0 :                 p1++;
    2481              : 
    2482            0 :               if (*p1++ != '<' || p[-2] != '>')
    2483            0 :                 fatal_error (input_location,
    2484              :                              "specs %%include syntax malformed after "
    2485            0 :                              "%td characters", p1 - buffer + 1);
    2486              : 
    2487            0 :               p[-2] = '\0';
    2488            0 :               new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
    2489            0 :               if (new_filename)
    2490            0 :                 read_specs (new_filename, false, user_p);
    2491            0 :               else if (verbose_flag)
    2492            0 :                 fnotice (stderr, "could not find specs file %s\n", p1);
    2493            0 :               continue;
    2494            0 :             }
    2495        21298 :           else if (startswith (p1, "%rename")
    2496        21298 :                    && (p1[sizeof "%rename" - 1] == ' '
    2497            0 :                        || p1[sizeof "%rename" - 1] == '\t'))
    2498              :             {
    2499        21298 :               int name_len;
    2500        21298 :               struct spec_list *sl;
    2501        21298 :               struct spec_list *newsl;
    2502              : 
    2503              :               /* Get original name.  */
    2504        21298 :               p1 += sizeof "%rename";
    2505        21298 :               while (*p1 == ' ' || *p1 == '\t')
    2506            0 :                 p1++;
    2507              : 
    2508        21298 :               if (! ISALPHA ((unsigned char) *p1))
    2509            0 :                 fatal_error (input_location,
    2510              :                              "specs %%rename syntax malformed after "
    2511              :                              "%td characters", p1 - buffer);
    2512              : 
    2513              :               p2 = p1;
    2514        85192 :               while (*p2 && !ISSPACE ((unsigned char) *p2))
    2515        63894 :                 p2++;
    2516              : 
    2517        21298 :               if (*p2 != ' ' && *p2 != '\t')
    2518            0 :                 fatal_error (input_location,
    2519              :                              "specs %%rename syntax malformed after "
    2520              :                              "%td characters", p2 - buffer);
    2521              : 
    2522        21298 :               name_len = p2 - p1;
    2523        21298 :               *p2++ = '\0';
    2524        21298 :               while (*p2 == ' ' || *p2 == '\t')
    2525            0 :                 p2++;
    2526              : 
    2527        21298 :               if (! ISALPHA ((unsigned char) *p2))
    2528            0 :                 fatal_error (input_location,
    2529              :                              "specs %%rename syntax malformed after "
    2530              :                              "%td characters", p2 - buffer);
    2531              : 
    2532              :               /* Get new spec name.  */
    2533              :               p3 = p2;
    2534       170384 :               while (*p3 && !ISSPACE ((unsigned char) *p3))
    2535       149086 :                 p3++;
    2536              : 
    2537        21298 :               if (p3 != p - 1)
    2538            0 :                 fatal_error (input_location,
    2539              :                              "specs %%rename syntax malformed after "
    2540              :                              "%td characters", p3 - buffer);
    2541        21298 :               *p3 = '\0';
    2542              : 
    2543       425960 :               for (sl = specs; sl; sl = sl->next)
    2544       425960 :                 if (name_len == sl->name_len && !strcmp (sl->name, p1))
    2545              :                   break;
    2546              : 
    2547        21298 :               if (!sl)
    2548            0 :                 fatal_error (input_location,
    2549              :                              "specs %s spec was not found to be renamed", p1);
    2550              : 
    2551        21298 :               if (strcmp (p1, p2) == 0)
    2552            0 :                 continue;
    2553              : 
    2554      1001006 :               for (newsl = specs; newsl; newsl = newsl->next)
    2555       979708 :                 if (strcmp (newsl->name, p2) == 0)
    2556            0 :                   fatal_error (input_location,
    2557              :                                "%s: attempt to rename spec %qs to "
    2558              :                                "already defined spec %qs",
    2559              :                     filename, p1, p2);
    2560              : 
    2561        21298 :               if (verbose_flag)
    2562              :                 {
    2563            0 :                   fnotice (stderr, "rename spec %s to %s\n", p1, p2);
    2564              : #ifdef DEBUG_SPECS
    2565              :                   fnotice (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
    2566              : #endif
    2567              :                 }
    2568              : 
    2569        21298 :               set_spec (p2, *(sl->ptr_spec), user_p);
    2570        21298 :               if (sl->alloc_p)
    2571        21298 :                 free (const_cast<char *> (*(sl->ptr_spec)));
    2572              : 
    2573        21298 :               *(sl->ptr_spec) = "";
    2574        21298 :               sl->alloc_p = 0;
    2575        21298 :               continue;
    2576        21298 :             }
    2577              :           else
    2578            0 :             fatal_error (input_location,
    2579              :                          "specs unknown %% command after %td characters",
    2580              :                          p1 - buffer);
    2581              :         }
    2582              : 
    2583              :       /* Find the colon that should end the suffix.  */
    2584              :       p1 = p;
    2585    189198183 :       while (*p1 && *p1 != ':' && *p1 != '\n')
    2586    175418235 :         p1++;
    2587              : 
    2588              :       /* The colon shouldn't be missing.  */
    2589     13779948 :       if (*p1 != ':')
    2590            0 :         fatal_error (input_location,
    2591              :                      "specs file malformed after %td characters",
    2592              :                      p1 - buffer);
    2593              : 
    2594              :       /* Skip back over trailing whitespace.  */
    2595              :       p2 = p1;
    2596     13779948 :       while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t'))
    2597            0 :         p2--;
    2598              : 
    2599              :       /* Copy the suffix to a string.  */
    2600     13779948 :       suffix = save_string (p, p2 - p);
    2601              :       /* Find the next line.  */
    2602     13779948 :       p = skip_whitespace (p1 + 1);
    2603     13779948 :       if (p[1] == 0)
    2604            0 :         fatal_error (input_location,
    2605              :                      "specs file malformed after %td characters",
    2606              :                      p - buffer);
    2607              : 
    2608              :       p1 = p;
    2609              :       /* Find next blank line or end of string.  */
    2610   2721521903 :       while (*p1 && !(*p1 == '\n' && (p1[1] == '\n' || p1[1] == '\0')))
    2611   2707741955 :         p1++;
    2612              : 
    2613              :       /* Specs end at the blank line and do not include the newline.  */
    2614     13779948 :       spec = save_string (p, p1 - p);
    2615     13779948 :       p = p1;
    2616              : 
    2617              :       /* Delete backslash-newline sequences from the spec.  */
    2618     13779948 :       in = spec;
    2619     13779948 :       out = spec;
    2620   2735301849 :       while (*in != 0)
    2621              :         {
    2622   2707741953 :           if (in[0] == '\\' && in[1] == '\n')
    2623            2 :             in += 2;
    2624   2707741951 :           else if (in[0] == '#')
    2625            0 :             while (*in && *in != '\n')
    2626            0 :               in++;
    2627              : 
    2628              :           else
    2629   2707741951 :             *out++ = *in++;
    2630              :         }
    2631     13779948 :       *out = 0;
    2632              : 
    2633     13779948 :       if (suffix[0] == '*')
    2634              :         {
    2635     13779948 :           if (! strcmp (suffix, "*link_command"))
    2636       292607 :             link_command_spec = spec;
    2637              :           else
    2638              :             {
    2639     13487341 :               set_spec (suffix + 1, spec, user_p);
    2640     13487341 :               free (spec);
    2641              :             }
    2642              :         }
    2643              :       else
    2644              :         {
    2645              :           /* Add this pair to the vector.  */
    2646            0 :           compilers
    2647            0 :             = XRESIZEVEC (struct compiler, compilers, n_compilers + 2);
    2648              : 
    2649            0 :           compilers[n_compilers].suffix = suffix;
    2650            0 :           compilers[n_compilers].spec = spec;
    2651            0 :           n_compilers++;
    2652            0 :           memset (&compilers[n_compilers], 0, sizeof compilers[n_compilers]);
    2653              :         }
    2654              : 
    2655     13779948 :       if (*suffix == 0)
    2656            0 :         link_command_spec = spec;
    2657              :     }
    2658              : 
    2659       323661 :   if (link_command_spec == 0)
    2660            0 :     fatal_error (input_location, "spec file has no spec for linking");
    2661              : 
    2662       323661 :   XDELETEVEC (buffer);
    2663       323661 : }
    2664              : 
    2665              : /* Record the names of temporary files we tell compilers to write,
    2666              :    and delete them at the end of the run.  */
    2667              : 
    2668              : /* This is the common prefix we use to make temp file names.
    2669              :    It is chosen once for each run of this program.
    2670              :    It is substituted into a spec by %g or %j.
    2671              :    Thus, all temp file names contain this prefix.
    2672              :    In practice, all temp file names start with this prefix.
    2673              : 
    2674              :    This prefix comes from the envvar TMPDIR if it is defined;
    2675              :    otherwise, from the P_tmpdir macro if that is defined;
    2676              :    otherwise, in /usr/tmp or /tmp;
    2677              :    or finally the current directory if all else fails.  */
    2678              : 
    2679              : static const char *temp_filename;
    2680              : 
    2681              : /* Length of the prefix.  */
    2682              : 
    2683              : static int temp_filename_length;
    2684              : 
    2685              : /* Define the list of temporary files to delete.  */
    2686              : 
    2687              : struct temp_file
    2688              : {
    2689              :   const char *name;
    2690              :   struct temp_file *next;
    2691              : };
    2692              : 
    2693              : /* Queue of files to delete on success or failure of compilation.  */
    2694              : static struct temp_file *always_delete_queue;
    2695              : /* Queue of files to delete on failure of compilation.  */
    2696              : static struct temp_file *failure_delete_queue;
    2697              : 
    2698              : /* Record FILENAME as a file to be deleted automatically.
    2699              :    ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
    2700              :    otherwise delete it in any case.
    2701              :    FAIL_DELETE nonzero means delete it if a compilation step fails;
    2702              :    otherwise delete it in any case.  */
    2703              : 
    2704              : void
    2705       697199 : record_temp_file (const char *filename, int always_delete, int fail_delete)
    2706              : {
    2707       697199 :   char *const name = xstrdup (filename);
    2708              : 
    2709       697199 :   if (always_delete)
    2710              :     {
    2711       524291 :       struct temp_file *temp;
    2712       912790 :       for (temp = always_delete_queue; temp; temp = temp->next)
    2713       551042 :         if (! filename_cmp (name, temp->name))
    2714              :           {
    2715       162543 :             free (name);
    2716       162543 :             goto already1;
    2717              :           }
    2718              : 
    2719       361748 :       temp = XNEW (struct temp_file);
    2720       361748 :       temp->next = always_delete_queue;
    2721       361748 :       temp->name = name;
    2722       361748 :       always_delete_queue = temp;
    2723              : 
    2724       697199 :     already1:;
    2725              :     }
    2726              : 
    2727       697199 :   if (fail_delete)
    2728              :     {
    2729       281708 :       struct temp_file *temp;
    2730       286771 :       for (temp = failure_delete_queue; temp; temp = temp->next)
    2731         5152 :         if (! filename_cmp (name, temp->name))
    2732              :           {
    2733           89 :             free (name);
    2734           89 :             goto already2;
    2735              :           }
    2736              : 
    2737       281619 :       temp = XNEW (struct temp_file);
    2738       281619 :       temp->next = failure_delete_queue;
    2739       281619 :       temp->name = name;
    2740       281619 :       failure_delete_queue = temp;
    2741              : 
    2742       697199 :     already2:;
    2743              :     }
    2744       697199 : }
    2745              : 
    2746              : /* Delete all the temporary files whose names we previously recorded.  */
    2747              : 
    2748              : #ifndef DELETE_IF_ORDINARY
    2749              : #define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG)        \
    2750              : do                                                      \
    2751              :   {                                                     \
    2752              :     if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode))  \
    2753              :       if (unlink (NAME) < 0)                            \
    2754              :         if (VERBOSE_FLAG)                               \
    2755              :           error ("%s: %m", (NAME));                   \
    2756              :   } while (0)
    2757              : #endif
    2758              : 
    2759              : static void
    2760       385337 : delete_if_ordinary (const char *name)
    2761              : {
    2762       385337 :   struct stat st;
    2763              : #ifdef DEBUG
    2764              :   int i, c;
    2765              : 
    2766              :   printf ("Delete %s? (y or n) ", name);
    2767              :   fflush (stdout);
    2768              :   i = getchar ();
    2769              :   if (i != '\n')
    2770              :     while ((c = getchar ()) != '\n' && c != EOF)
    2771              :       ;
    2772              : 
    2773              :   if (i == 'y' || i == 'Y')
    2774              : #endif /* DEBUG */
    2775       385337 :   DELETE_IF_ORDINARY (name, st, verbose_flag);
    2776       385337 : }
    2777              : 
    2778              : static void
    2779       575021 : delete_temp_files (void)
    2780              : {
    2781       575021 :   struct temp_file *temp;
    2782              : 
    2783       936769 :   for (temp = always_delete_queue; temp; temp = temp->next)
    2784       361748 :     delete_if_ordinary (temp->name);
    2785       575021 :   always_delete_queue = 0;
    2786       575021 : }
    2787              : 
    2788              : /* Delete all the files to be deleted on error.  */
    2789              : 
    2790              : static void
    2791        58686 : delete_failure_queue (void)
    2792              : {
    2793        58686 :   struct temp_file *temp;
    2794              : 
    2795        82275 :   for (temp = failure_delete_queue; temp; temp = temp->next)
    2796        23589 :     delete_if_ordinary (temp->name);
    2797        58686 : }
    2798              : 
    2799              : static void
    2800       538665 : clear_failure_queue (void)
    2801              : {
    2802       538665 :   failure_delete_queue = 0;
    2803       538665 : }
    2804              : 
    2805              : /* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
    2806              :    returns non-NULL.
    2807              :    If DO_MULTI is true iterate over the paths twice, first with multilib
    2808              :    suffix then without, otherwise iterate over the paths once without
    2809              :    adding a multilib suffix.  When DO_MULTI is true, some attempt is made
    2810              :    to avoid visiting the same path twice, but we could do better.  For
    2811              :    instance, /usr/lib/../lib is considered different from /usr/lib.
    2812              :    At least EXTRA_SPACE chars past the end of the path passed to
    2813              :    CALLBACK are available for use by the callback.
    2814              :    CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
    2815              : 
    2816              :    Returns the value returned by CALLBACK.  */
    2817              : 
    2818              : template<typename fun>
    2819              : auto *
    2820      2808472 : for_each_path (const struct path_prefix *paths,
    2821              :                bool do_multi,
    2822              :                size_t extra_space,
    2823              :                fun && callback)
    2824              : {
    2825              :   struct prefix_list *pl;
    2826      2808472 :   const char *multi_dir = NULL;
    2827      2808472 :   const char *multi_os_dir = NULL;
    2828      2808472 :   const char *multiarch_suffix = NULL;
    2829              :   const char *multi_suffix;
    2830              :   const char *just_multi_suffix;
    2831      2808472 :   char *path = NULL;
    2832      2808472 :   decltype (callback (nullptr)) ret = nullptr;
    2833      2808472 :   bool skip_multi_dir = false;
    2834      2808472 :   bool skip_multi_os_dir = false;
    2835              : 
    2836      2808472 :   multi_suffix = machine_suffix;
    2837      2808472 :   just_multi_suffix = just_machine_suffix;
    2838      2808472 :   if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
    2839              :     {
    2840        15892 :       multi_dir = concat (multilib_dir, dir_separator_str, NULL);
    2841        15892 :       multi_suffix = concat (multi_suffix, multi_dir, NULL);
    2842        15892 :       just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
    2843              :     }
    2844      1221663 :   if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
    2845       927962 :     multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
    2846      2808472 :   if (multiarch_dir)
    2847            0 :     multiarch_suffix = concat (multiarch_dir, dir_separator_str, NULL);
    2848              : 
    2849              :   while (1)
    2850              :     {
    2851      3229425 :       size_t multi_dir_len = 0;
    2852      3229425 :       size_t multi_os_dir_len = 0;
    2853      3229425 :       size_t multiarch_len = 0;
    2854              :       size_t suffix_len;
    2855              :       size_t just_suffix_len;
    2856              :       size_t len;
    2857              : 
    2858      3229425 :       if (multi_dir)
    2859        15892 :         multi_dir_len = strlen (multi_dir);
    2860      3229425 :       if (multi_os_dir)
    2861       927962 :         multi_os_dir_len = strlen (multi_os_dir);
    2862      3229425 :       if (multiarch_suffix)
    2863            0 :         multiarch_len = strlen (multiarch_suffix);
    2864      3229425 :       suffix_len = strlen (multi_suffix);
    2865      3229425 :       just_suffix_len = strlen (just_multi_suffix);
    2866              : 
    2867      3229425 :       if (path == NULL)
    2868              :         {
    2869      2808472 :           len = paths->max_len + extra_space + 1;
    2870      2808472 :           len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len);
    2871      2808472 :           path = XNEWVEC (char, len);
    2872              :         }
    2873              : 
    2874     12647918 :       for (pl = paths->plist; pl != 0; pl = pl->next)
    2875              :         {
    2876     11075989 :           len = strlen (pl->prefix);
    2877     11075989 :           memcpy (path, pl->prefix, len);
    2878              : 
    2879              :           /* Look first in MACHINE/VERSION subdirectory.  */
    2880     11075989 :           if (!skip_multi_dir)
    2881              :             {
    2882      8105171 :               memcpy (path + len, multi_suffix, suffix_len + 1);
    2883      8105171 :               ret = callback (path);
    2884      5234727 :               if (ret)
    2885              :                 break;
    2886              :             }
    2887              : 
    2888              :           /* Some paths are tried with just the machine (ie. target)
    2889              :              subdir.  This is used for finding as, ld, etc.  */
    2890              :           if (!skip_multi_dir
    2891      8105171 :               && pl->require_machine_suffix == 2)
    2892              :             {
    2893            0 :               memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
    2894            0 :               ret = callback (path);
    2895            0 :               if (ret)
    2896              :                 break;
    2897              :             }
    2898              : 
    2899              :           /* Now try the multiarch path.  */
    2900              :           if (!skip_multi_dir
    2901      8105171 :               && !pl->require_machine_suffix && multiarch_dir)
    2902              :             {
    2903            0 :               memcpy (path + len, multiarch_suffix, multiarch_len + 1);
    2904            0 :               ret = callback (path);
    2905            0 :               if (ret)
    2906              :                 break;
    2907              :             }
    2908              : 
    2909              :           /* Now try the base path.  */
    2910     11075989 :           if (!pl->require_machine_suffix
    2911     17621146 :               && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
    2912              :             {
    2913              :               const char *this_multi;
    2914              :               size_t this_multi_len;
    2915              : 
    2916      9898907 :               if (pl->os_multilib)
    2917              :                 {
    2918              :                   this_multi = multi_os_dir;
    2919              :                   this_multi_len = multi_os_dir_len;
    2920              :                 }
    2921              :               else
    2922              :                 {
    2923      5368075 :                   this_multi = multi_dir;
    2924      5368075 :                   this_multi_len = multi_dir_len;
    2925              :                 }
    2926              : 
    2927      9898907 :               if (this_multi_len)
    2928      2757554 :                 memcpy (path + len, this_multi, this_multi_len + 1);
    2929              :               else
    2930      7141353 :                 path[len] = '\0';
    2931              : 
    2932      9898907 :               ret = callback (path);
    2933      5895789 :               if (ret)
    2934              :                 break;
    2935              :             }
    2936              :         }
    2937      2475531 :       if (pl)
    2938              :         break;
    2939              : 
    2940      1571929 :       if (multi_dir == NULL && multi_os_dir == NULL)
    2941              :         break;
    2942              : 
    2943              :       /* Run through the paths again, this time without multilibs.
    2944              :          Don't repeat any we have already seen.  */
    2945       420953 :       if (multi_dir)
    2946              :         {
    2947        10165 :           free (const_cast<char *> (multi_dir));
    2948        10165 :           multi_dir = NULL;
    2949        10165 :           free (const_cast<char *> (multi_suffix));
    2950        10165 :           multi_suffix = machine_suffix;
    2951        10165 :           free (const_cast<char *> (just_multi_suffix));
    2952        10165 :           just_multi_suffix = just_machine_suffix;
    2953              :         }
    2954              :       else
    2955              :         skip_multi_dir = true;
    2956       420953 :       if (multi_os_dir)
    2957              :         {
    2958       420953 :           free (const_cast<char *> (multi_os_dir));
    2959       420953 :           multi_os_dir = NULL;
    2960              :         }
    2961              :       else
    2962              :         skip_multi_os_dir = true;
    2963              :     }
    2964              : 
    2965      2808472 :   if (multi_dir)
    2966              :     {
    2967         5727 :       free (const_cast<char *> (multi_dir));
    2968         5727 :       free (const_cast<char *> (multi_suffix));
    2969         5727 :       free (const_cast<char *> (just_multi_suffix));
    2970              :     }
    2971      2808472 :   if (multi_os_dir)
    2972       507009 :     free (const_cast<char *> (multi_os_dir));
    2973      2305876 :   if (ret != path)
    2974      1150976 :     free (path);
    2975      2808472 :   return ret;
    2976              : }
    2977              : 
    2978              : /* Add or change the value of an environment variable, outputting the
    2979              :    change to standard error if in verbose mode.  */
    2980              : static void
    2981      1745427 : xputenv (const char *string)
    2982              : {
    2983            0 :   env.xput (string);
    2984       134371 : }
    2985              : 
    2986              : /* Build a list of search directories from PATHS.
    2987              :    PREFIX is a string to prepend to the list.
    2988              :    If CHECK_DIR_P is true we ensure the directory exists.
    2989              :    If DO_MULTI is true, multilib paths are output first, then
    2990              :    non-multilib paths.
    2991              :    This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
    2992              :    It is also used by the --print-search-dirs flag.  */
    2993              : 
    2994              : static char *
    2995       502596 : build_search_list (const struct path_prefix *paths, const char *prefix,
    2996              :                    bool check_dir, bool do_multi)
    2997              : {
    2998       502596 :   struct obstack *const ob = &collect_obstack;
    2999       502596 :   bool first_time = true;
    3000              : 
    3001       502596 :   obstack_grow (&collect_obstack, prefix, strlen (prefix));
    3002       502596 :   obstack_1grow (&collect_obstack, '=');
    3003              : 
    3004              :   /* Callback adds path to obstack being built.  */
    3005       502596 :   for_each_path (paths, do_multi, 0, [&](char *path) -> void*
    3006              :     {
    3007      6873562 :       if (check_dir && !is_directory (path))
    3008              :         return NULL;
    3009              : 
    3010      2521018 :       if (!first_time)
    3011      2019556 :         obstack_1grow (ob, PATH_SEPARATOR);
    3012              : 
    3013      2521018 :       obstack_grow (ob, path, strlen (path));
    3014              : 
    3015      2521018 :       first_time = false;
    3016      2521018 :       return NULL;
    3017              :     });
    3018              : 
    3019       502596 :   obstack_1grow (&collect_obstack, '\0');
    3020       502596 :   return XOBFINISH (&collect_obstack, char *);
    3021              : }
    3022              : 
    3023              : /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    3024              :    for collect.  */
    3025              : 
    3026              : static void
    3027       502540 : putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
    3028              :                       bool do_multi)
    3029              : {
    3030       502540 :   xputenv (build_search_list (paths, env_var, true, do_multi));
    3031       502540 : }
    3032              : 
    3033              : /* Check whether NAME can be accessed in MODE.  This is like access,
    3034              :    except that it never considers directories to be executable.  */
    3035              : 
    3036              : static int
    3037      7810364 : access_check (const char *name, int mode)
    3038              : {
    3039      7810364 :   if (mode == X_OK)
    3040              :     {
    3041      1495290 :       struct stat st;
    3042              : 
    3043      1495290 :       if (stat (name, &st) < 0
    3044      1495290 :           || S_ISDIR (st.st_mode))
    3045       760395 :         return -1;
    3046              :     }
    3047              : 
    3048      7049969 :   return access (name, mode);
    3049              : }
    3050              : 
    3051              : 
    3052              : /* Search for NAME using the prefix list PREFIXES.  MODE is passed to
    3053              :    access to check permissions.  If DO_MULTI is true, search multilib
    3054              :    paths then non-multilib paths, otherwise do not search multilib paths.
    3055              :    Return 0 if not found, otherwise return its name, allocated with malloc.  */
    3056              : 
    3057              : static char *
    3058      1758522 : find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
    3059              :              bool do_multi)
    3060              : {
    3061              :   /* Find the filename in question (special case for absolute paths).  */
    3062              : 
    3063      1758522 :   if (IS_ABSOLUTE_PATH (name))
    3064              :     {
    3065            1 :       if (access (name, mode) == 0)
    3066            1 :         return xstrdup (name);
    3067              : 
    3068              :       return NULL;
    3069              :     }
    3070              : 
    3071      1758521 :   const char *suffix = (mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "";
    3072      1758521 :   const int name_len = strlen (name);
    3073      1758521 :   const int suffix_len = strlen (suffix);
    3074              : 
    3075              : 
    3076              :   /* Callback appends the file name to the directory path.  If the
    3077              :      resulting file exists in the right mode, return the full pathname
    3078              :      to the file.  */
    3079      1758521 :   return for_each_path (pprefix, do_multi,
    3080              :                         name_len + suffix_len,
    3081      1758521 :                         [=](char *path) -> char*
    3082              :     {
    3083      7810364 :       size_t len = strlen (path);
    3084              : 
    3085      7810364 :       memcpy (path + len, name, name_len);
    3086      7810364 :       len += name_len;
    3087              : 
    3088              :       /* Some systems have a suffix for executable files.
    3089              :          So try appending that first.  */
    3090      7810364 :       if (suffix_len)
    3091              :         {
    3092            0 :           memcpy (path + len, suffix, suffix_len + 1);
    3093            0 :           if (access_check (path, mode) == 0)
    3094              :             return path;
    3095              :         }
    3096              : 
    3097      7810364 :       path[len] = '\0';
    3098      7810364 :       if (access_check (path, mode) == 0)
    3099              :         return path;
    3100              : 
    3101              :       return NULL;
    3102              :     });
    3103              : }
    3104              : 
    3105              : /* Specialization of find_a_file for programs that also takes into account
    3106              :    configure-specified default programs. */
    3107              : 
    3108              : static char*
    3109       740955 : find_a_program (const char *name)
    3110              : {
    3111              :   /* Do not search if default matches query. */
    3112              : 
    3113              : #ifdef DEFAULT_ASSEMBLER
    3114              :   if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, X_OK) == 0)
    3115              :     return xstrdup (DEFAULT_ASSEMBLER);
    3116              : #endif
    3117              : 
    3118              : #ifdef DEFAULT_LINKER
    3119              :   if (! strcmp (name, "ld") && access (DEFAULT_LINKER, X_OK) == 0)
    3120              :     return xstrdup (DEFAULT_LINKER);
    3121              : #endif
    3122              : 
    3123              : #ifdef DEFAULT_DSYMUTIL
    3124              :   if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, X_OK) == 0)
    3125              :     return xstrdup (DEFAULT_DSYMUTIL);
    3126              : #endif
    3127              : 
    3128              : #ifdef DEFAULT_WINDRES
    3129              :   if (! strcmp (name, "windres") && access (DEFAULT_WINDRES, X_OK) == 0)
    3130              :     return xstrdup (DEFAULT_WINDRES);
    3131              : #endif
    3132              : 
    3133            0 :   return find_a_file (&exec_prefixes, name, X_OK, false);
    3134              : }
    3135              : 
    3136              : /* Ranking of prefixes in the sort list. -B prefixes are put before
    3137              :    all others.  */
    3138              : 
    3139              : enum path_prefix_priority
    3140              : {
    3141              :   PREFIX_PRIORITY_B_OPT,
    3142              :   PREFIX_PRIORITY_LAST
    3143              : };
    3144              : 
    3145              : /* Add an entry for PREFIX in PLIST.  The PLIST is kept in ascending
    3146              :    order according to PRIORITY.  Within each PRIORITY, new entries are
    3147              :    appended.
    3148              : 
    3149              :    If WARN is nonzero, we will warn if no file is found
    3150              :    through this prefix.  WARN should point to an int
    3151              :    which will be set to 1 if this entry is used.
    3152              : 
    3153              :    COMPONENT is the value to be passed to update_path.
    3154              : 
    3155              :    REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
    3156              :    the complete value of machine_suffix.
    3157              :    2 means try both machine_suffix and just_machine_suffix.  */
    3158              : 
    3159              : static void
    3160      3825335 : add_prefix (struct path_prefix *pprefix, const char *prefix,
    3161              :             const char *component, /* enum prefix_priority */ int priority,
    3162              :             int require_machine_suffix, int os_multilib)
    3163              : {
    3164      3825335 :   struct prefix_list *pl, **prev;
    3165      3825335 :   int len;
    3166              : 
    3167      3825335 :   for (prev = &pprefix->plist;
    3168     12057399 :        (*prev) != NULL && (*prev)->priority <= priority;
    3169      8232064 :        prev = &(*prev)->next)
    3170              :     ;
    3171              : 
    3172              :   /* Keep track of the longest prefix.  */
    3173              : 
    3174      3825335 :   prefix = update_path (prefix, component);
    3175      3825335 :   len = strlen (prefix);
    3176      3825335 :   if (len > pprefix->max_len)
    3177      2076303 :     pprefix->max_len = len;
    3178              : 
    3179      3825335 :   pl = XNEW (struct prefix_list);
    3180      3825335 :   pl->prefix = prefix;
    3181      3825335 :   pl->require_machine_suffix = require_machine_suffix;
    3182      3825335 :   pl->priority = priority;
    3183      3825335 :   pl->os_multilib = os_multilib;
    3184              : 
    3185              :   /* Insert after PREV.  */
    3186      3825335 :   pl->next = (*prev);
    3187      3825335 :   (*prev) = pl;
    3188      3825335 : }
    3189              : 
    3190              : /* Same as add_prefix, but prepending target_system_root to prefix.  */
    3191              : /* The target_system_root prefix has been relocated by gcc_exec_prefix.  */
    3192              : static void
    3193       587398 : add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
    3194              :                       const char *component,
    3195              :                       /* enum prefix_priority */ int priority,
    3196              :                       int require_machine_suffix, int os_multilib)
    3197              : {
    3198       587398 :   if (!IS_ABSOLUTE_PATH (prefix))
    3199            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3200              : 
    3201       587398 :   if (target_system_root)
    3202              :     {
    3203            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3204            0 :       size_t sysroot_len = strlen (target_system_root);
    3205              : 
    3206            0 :       if (sysroot_len > 0
    3207            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3208            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3209              : 
    3210            0 :       if (target_sysroot_suffix)
    3211            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3212              :                          target_sysroot_suffix, prefix, NULL);
    3213              :       else
    3214            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3215              : 
    3216            0 :       free (sysroot_no_trailing_dir_separator);
    3217              : 
    3218              :       /* We have to override this because GCC's notion of sysroot
    3219              :          moves along with GCC.  */
    3220            0 :       component = "GCC";
    3221              :     }
    3222              : 
    3223       587398 :   add_prefix (pprefix, prefix, component, priority,
    3224              :               require_machine_suffix, os_multilib);
    3225       587398 : }
    3226              : 
    3227              : /* Same as add_prefix, but prepending target_sysroot_hdrs_suffix to prefix.  */
    3228              : 
    3229              : static void
    3230        31286 : add_sysrooted_hdrs_prefix (struct path_prefix *pprefix, const char *prefix,
    3231              :                            const char *component,
    3232              :                            /* enum prefix_priority */ int priority,
    3233              :                            int require_machine_suffix, int os_multilib)
    3234              : {
    3235        31286 :   if (!IS_ABSOLUTE_PATH (prefix))
    3236            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3237              : 
    3238        31286 :   if (target_system_root)
    3239              :     {
    3240            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3241            0 :       size_t sysroot_len = strlen (target_system_root);
    3242              : 
    3243            0 :       if (sysroot_len > 0
    3244            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3245            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3246              : 
    3247            0 :       if (target_sysroot_hdrs_suffix)
    3248            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3249              :                          target_sysroot_hdrs_suffix, prefix, NULL);
    3250              :       else
    3251            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3252              : 
    3253            0 :       free (sysroot_no_trailing_dir_separator);
    3254              : 
    3255              :       /* We have to override this because GCC's notion of sysroot
    3256              :          moves along with GCC.  */
    3257            0 :       component = "GCC";
    3258              :     }
    3259              : 
    3260        31286 :   add_prefix (pprefix, prefix, component, priority,
    3261              :               require_machine_suffix, os_multilib);
    3262        31286 : }
    3263              : 
    3264              : 
    3265              : /* Execute the command specified by the arguments on the current line of spec.
    3266              :    When using pipes, this includes several piped-together commands
    3267              :    with `|' between them.
    3268              : 
    3269              :    Return 0 if successful, -1 if failed.  */
    3270              : 
    3271              : static int
    3272       538587 : execute (void)
    3273              : {
    3274       538587 :   int i;
    3275       538587 :   int n_commands;               /* # of command.  */
    3276       538587 :   char *string;
    3277       538587 :   struct pex_obj *pex;
    3278       538587 :   struct command
    3279              :   {
    3280              :     const char *prog;           /* program name.  */
    3281              :     const char **argv;          /* vector of args.  */
    3282              :   };
    3283       538587 :   const char *arg;
    3284              : 
    3285       538587 :   struct command *commands;     /* each command buffer with above info.  */
    3286              : 
    3287       538587 :   gcc_assert (!processing_spec_function);
    3288              : 
    3289       538587 :   if (wrapper_string)
    3290              :     {
    3291            0 :       string = find_a_program (argbuf[0]);
    3292            0 :       if (string)
    3293            0 :         argbuf[0] = string;
    3294            0 :       insert_wrapper (wrapper_string);
    3295              :     }
    3296              : 
    3297              :   /* Count # of piped commands.  */
    3298     16597567 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3299     16058980 :     if (strcmp (arg, "|") == 0)
    3300            0 :       n_commands++;
    3301              : 
    3302              :   /* Get storage for each command.  */
    3303       538587 :   commands = XALLOCAVEC (struct command, n_commands);
    3304              : 
    3305              :   /* Split argbuf into its separate piped processes,
    3306              :      and record info about each one.
    3307              :      Also search for the programs that are to be run.  */
    3308              : 
    3309       538587 :   argbuf.safe_push (0);
    3310              : 
    3311       538587 :   commands[0].prog = argbuf[0]; /* first command.  */
    3312       538587 :   commands[0].argv = argbuf.address ();
    3313              : 
    3314       538587 :   if (!wrapper_string)
    3315              :     {
    3316       538587 :       string = find_a_program(commands[0].prog);
    3317       538587 :       if (string)
    3318       535952 :         commands[0].argv[0] = string;
    3319              :     }
    3320              : 
    3321     17136154 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3322     16597567 :     if (arg && strcmp (arg, "|") == 0)
    3323              :       {                         /* each command.  */
    3324              : #if defined (__MSDOS__) || defined (OS2) || defined (VMS)
    3325              :         fatal_error (input_location, "%<-pipe%> not supported");
    3326              : #endif
    3327            0 :         argbuf[i] = 0; /* Termination of command args.  */
    3328            0 :         commands[n_commands].prog = argbuf[i + 1];
    3329            0 :         commands[n_commands].argv
    3330            0 :           = &(argbuf.address ())[i + 1];
    3331            0 :         string = find_a_program(commands[n_commands].prog);
    3332            0 :         if (string)
    3333            0 :           commands[n_commands].argv[0] = string;
    3334            0 :         n_commands++;
    3335              :       }
    3336              : 
    3337              :   /* If -v, print what we are about to do, and maybe query.  */
    3338              : 
    3339       538587 :   if (verbose_flag)
    3340              :     {
    3341              :       /* For help listings, put a blank line between sub-processes.  */
    3342         1404 :       if (print_help_list)
    3343            9 :         fputc ('\n', stderr);
    3344              : 
    3345              :       /* Print each piped command as a separate line.  */
    3346         2808 :       for (i = 0; i < n_commands; i++)
    3347              :         {
    3348         1404 :           const char *const *j;
    3349              : 
    3350         1404 :           if (verbose_only_flag)
    3351              :             {
    3352        18014 :               for (j = commands[i].argv; *j; j++)
    3353              :                 {
    3354              :                   const char *p;
    3355       430341 :                   for (p = *j; *p; ++p)
    3356       415854 :                     if (!ISALNUM ((unsigned char) *p)
    3357        98309 :                         && *p != '_' && *p != '/' && *p != '-' && *p != '.')
    3358              :                       break;
    3359        16989 :                   if (*p || !*j)
    3360              :                     {
    3361         2502 :                       fprintf (stderr, " \"");
    3362       130140 :                       for (p = *j; *p; ++p)
    3363              :                         {
    3364       127638 :                           if (*p == '"' || *p == '\\' || *p == '$')
    3365            0 :                             fputc ('\\', stderr);
    3366       127638 :                           fputc (*p, stderr);
    3367              :                         }
    3368         2502 :                       fputc ('"', stderr);
    3369              :                     }
    3370              :                   /* If it's empty, print "".  */
    3371        14487 :                   else if (!**j)
    3372            0 :                     fprintf (stderr, " \"\"");
    3373              :                   else
    3374        14487 :                     fprintf (stderr, " %s", *j);
    3375              :                 }
    3376              :             }
    3377              :           else
    3378        10225 :             for (j = commands[i].argv; *j; j++)
    3379              :               /* If it's empty, print "".  */
    3380         9846 :               if (!**j)
    3381            0 :                 fprintf (stderr, " \"\"");
    3382              :               else
    3383         9846 :                 fprintf (stderr, " %s", *j);
    3384              : 
    3385              :           /* Print a pipe symbol after all but the last command.  */
    3386         1404 :           if (i + 1 != n_commands)
    3387            0 :             fprintf (stderr, " |");
    3388         1404 :           fprintf (stderr, "\n");
    3389              :         }
    3390         1404 :       fflush (stderr);
    3391         1404 :       if (verbose_only_flag != 0)
    3392              :         {
    3393              :           /* verbose_only_flag should act as if the spec was
    3394              :              executed, so increment execution_count before
    3395              :              returning.  This prevents spurious warnings about
    3396              :              unused linker input files, etc.  */
    3397         1025 :           execution_count++;
    3398         1025 :           return 0;
    3399              :         }
    3400              : #ifdef DEBUG
    3401              :       fnotice (stderr, "\nGo ahead? (y or n) ");
    3402              :       fflush (stderr);
    3403              :       i = getchar ();
    3404              :       if (i != '\n')
    3405              :         while (getchar () != '\n')
    3406              :           ;
    3407              : 
    3408              :       if (i != 'y' && i != 'Y')
    3409              :         return 0;
    3410              : #endif /* DEBUG */
    3411              :     }
    3412              : 
    3413              : #ifdef ENABLE_VALGRIND_CHECKING
    3414              :   /* Run the each command through valgrind.  To simplify prepending the
    3415              :      path to valgrind and the option "-q" (for quiet operation unless
    3416              :      something triggers), we allocate a separate argv array.  */
    3417              : 
    3418              :   for (i = 0; i < n_commands; i++)
    3419              :     {
    3420              :       const char **argv;
    3421              :       int argc;
    3422              :       int j;
    3423              : 
    3424              :       for (argc = 0; commands[i].argv[argc] != NULL; argc++)
    3425              :         ;
    3426              : 
    3427              :       argv = XALLOCAVEC (const char *, argc + 3);
    3428              : 
    3429              :       argv[0] = VALGRIND_PATH;
    3430              :       argv[1] = "-q";
    3431              :       for (j = 2; j < argc + 2; j++)
    3432              :         argv[j] = commands[i].argv[j - 2];
    3433              :       argv[j] = NULL;
    3434              : 
    3435              :       commands[i].argv = argv;
    3436              :       commands[i].prog = argv[0];
    3437              :     }
    3438              : #endif
    3439              : 
    3440              :   /* Run each piped subprocess.  */
    3441              : 
    3442       537562 :   pex = pex_init (PEX_USE_PIPES | ((report_times || report_times_to_file)
    3443              :                                    ? PEX_RECORD_TIMES : 0),
    3444              :                   progname, temp_filename);
    3445       537562 :   if (pex == NULL)
    3446              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    3447              : 
    3448      1075124 :   for (i = 0; i < n_commands; i++)
    3449              :     {
    3450       537562 :       const char *errmsg;
    3451       537562 :       int err;
    3452       537562 :       const char *string = commands[i].argv[0];
    3453              : 
    3454       537562 :       errmsg = pex_run (pex,
    3455       537562 :                         ((i + 1 == n_commands ? PEX_LAST : 0)
    3456       537562 :                          | (string == commands[i].prog ? PEX_SEARCH : 0)),
    3457              :                         string, const_cast<char **> (commands[i].argv),
    3458              :                         NULL, NULL, &err);
    3459       537562 :       if (errmsg != NULL)
    3460              :         {
    3461            0 :           errno = err;
    3462            0 :           fatal_error (input_location,
    3463              :                        err ? G_("cannot execute %qs: %s: %m")
    3464              :                        : G_("cannot execute %qs: %s"),
    3465              :                        string, errmsg);
    3466              :         }
    3467              : 
    3468       537562 :       if (i && string != commands[i].prog)
    3469            0 :         free (const_cast<char *> (string));
    3470              :     }
    3471              : 
    3472       537562 :   execution_count++;
    3473              : 
    3474              :   /* Wait for all the subprocesses to finish.  */
    3475              : 
    3476       537562 :   {
    3477       537562 :     int *statuses;
    3478       537562 :     struct pex_time *times = NULL;
    3479       537562 :     int ret_code = 0;
    3480              : 
    3481       537562 :     statuses = XALLOCAVEC (int, n_commands);
    3482       537562 :     if (!pex_get_status (pex, n_commands, statuses))
    3483            0 :       fatal_error (input_location, "failed to get exit status: %m");
    3484              : 
    3485       537562 :     if (report_times || report_times_to_file)
    3486              :       {
    3487            0 :         times = XALLOCAVEC (struct pex_time, n_commands);
    3488            0 :         if (!pex_get_times (pex, n_commands, times))
    3489            0 :           fatal_error (input_location, "failed to get process times: %m");
    3490              :       }
    3491              : 
    3492       537562 :     pex_free (pex);
    3493              : 
    3494      1075124 :     for (i = 0; i < n_commands; ++i)
    3495              :       {
    3496       537562 :         int status = statuses[i];
    3497              : 
    3498       537562 :         if (WIFSIGNALED (status))
    3499            0 :           switch (WTERMSIG (status))
    3500              :             {
    3501            0 :             case SIGINT:
    3502            0 :             case SIGTERM:
    3503              :               /* SIGQUIT and SIGKILL are not available on MinGW.  */
    3504              : #ifdef SIGQUIT
    3505            0 :             case SIGQUIT:
    3506              : #endif
    3507              : #ifdef SIGKILL
    3508            0 :             case SIGKILL:
    3509              : #endif
    3510              :               /* The user (or environment) did something to the
    3511              :                  inferior.  Making this an ICE confuses the user into
    3512              :                  thinking there's a compiler bug.  Much more likely is
    3513              :                  the user or OOM killer nuked it.  */
    3514            0 :               fatal_error (input_location,
    3515              :                            "%s signal terminated program %s",
    3516              :                            strsignal (WTERMSIG (status)),
    3517            0 :                            commands[i].prog);
    3518            0 :               break;
    3519              : 
    3520              : #ifdef SIGPIPE
    3521            0 :             case SIGPIPE:
    3522              :               /* SIGPIPE is a special case.  It happens in -pipe mode
    3523              :                  when the compiler dies before the preprocessor is
    3524              :                  done, or the assembler dies before the compiler is
    3525              :                  done.  There's generally been an error already, and
    3526              :                  this is just fallout.  So don't generate another
    3527              :                  error unless we would otherwise have succeeded.  */
    3528            0 :               if (signal_count || greatest_status >= MIN_FATAL_STATUS)
    3529              :                 {
    3530            0 :                   signal_count++;
    3531            0 :                   ret_code = -1;
    3532            0 :                   break;
    3533              :                 }
    3534              : #endif
    3535              :               /* FALLTHROUGH */
    3536              : 
    3537            0 :             default:
    3538              :               /* The inferior failed to catch the signal.  */
    3539            0 :               internal_error_no_backtrace ("%s signal terminated program %s",
    3540              :                                            strsignal (WTERMSIG (status)),
    3541            0 :                                            commands[i].prog);
    3542              :             }
    3543       537562 :         else if (WIFEXITED (status)
    3544       537562 :                  && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
    3545              :           {
    3546              :             /* For ICEs in cc1, cc1obj, cc1plus see if it is
    3547              :                reproducible or not.  */
    3548        29394 :             const char *p;
    3549        29394 :             if (flag_report_bug
    3550            0 :                 && WEXITSTATUS (status) == ICE_EXIT_CODE
    3551            0 :                 && i == 0
    3552            0 :                 && (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
    3553        29394 :                 && startswith (p + 1, "cc1"))
    3554            0 :               try_generate_repro (commands[0].argv);
    3555        29394 :             if (WEXITSTATUS (status) > greatest_status)
    3556           22 :               greatest_status = WEXITSTATUS (status);
    3557              :             ret_code = -1;
    3558              :           }
    3559              : 
    3560       537562 :         if (report_times || report_times_to_file)
    3561              :           {
    3562            0 :             struct pex_time *pt = &times[i];
    3563            0 :             double ut, st;
    3564              : 
    3565            0 :             ut = ((double) pt->user_seconds
    3566            0 :                   + (double) pt->user_microseconds / 1.0e6);
    3567            0 :             st = ((double) pt->system_seconds
    3568            0 :                   + (double) pt->system_microseconds / 1.0e6);
    3569              : 
    3570            0 :             if (ut + st != 0)
    3571              :               {
    3572            0 :                 if (report_times)
    3573            0 :                   fnotice (stderr, "# %s %.2f %.2f\n",
    3574            0 :                            commands[i].prog, ut, st);
    3575              : 
    3576            0 :                 if (report_times_to_file)
    3577              :                   {
    3578            0 :                     int c = 0;
    3579            0 :                     const char *const *j;
    3580              : 
    3581            0 :                     fprintf (report_times_to_file, "%g %g", ut, st);
    3582              : 
    3583            0 :                     for (j = &commands[i].prog; *j; j = &commands[i].argv[++c])
    3584              :                       {
    3585              :                         const char *p;
    3586            0 :                         for (p = *j; *p; ++p)
    3587            0 :                           if (*p == '"' || *p == '\\' || *p == '$'
    3588            0 :                               || ISSPACE (*p))
    3589              :                             break;
    3590              : 
    3591            0 :                         if (*p)
    3592              :                           {
    3593            0 :                             fprintf (report_times_to_file, " \"");
    3594            0 :                             for (p = *j; *p; ++p)
    3595              :                               {
    3596            0 :                                 if (*p == '"' || *p == '\\' || *p == '$')
    3597            0 :                                   fputc ('\\', report_times_to_file);
    3598            0 :                                 fputc (*p, report_times_to_file);
    3599              :                               }
    3600            0 :                             fputc ('"', report_times_to_file);
    3601              :                           }
    3602              :                         else
    3603            0 :                           fprintf (report_times_to_file, " %s", *j);
    3604              :                       }
    3605              : 
    3606            0 :                     fputc ('\n', report_times_to_file);
    3607              :                   }
    3608              :               }
    3609              :           }
    3610              :       }
    3611              : 
    3612       537562 :    if (commands[0].argv[0] != commands[0].prog)
    3613       534927 :      free (const_cast<char *> (commands[0].argv[0]));
    3614              : 
    3615              :     return ret_code;
    3616              :   }
    3617              : }
    3618              : 
    3619              : static struct switchstr *switches;
    3620              : 
    3621              : static int n_switches;
    3622              : 
    3623              : static int n_switches_alloc;
    3624              : 
    3625              : /* Set to zero if -fcompare-debug is disabled, positive if it's
    3626              :    enabled and we're running the first compilation, negative if it's
    3627              :    enabled and we're running the second compilation.  For most of the
    3628              :    time, it's in the range -1..1, but it can be temporarily set to 2
    3629              :    or 3 to indicate that the -fcompare-debug flags didn't come from
    3630              :    the command-line, but rather from the GCC_COMPARE_DEBUG environment
    3631              :    variable, until a synthesized -fcompare-debug flag is added to the
    3632              :    command line.  */
    3633              : int compare_debug;
    3634              : 
    3635              : /* Set to nonzero if we've seen the -fcompare-debug-second flag.  */
    3636              : int compare_debug_second;
    3637              : 
    3638              : /* Set to the flags that should be passed to the second compilation in
    3639              :    a -fcompare-debug compilation.  */
    3640              : const char *compare_debug_opt;
    3641              : 
    3642              : static struct switchstr *switches_debug_check[2];
    3643              : 
    3644              : static int n_switches_debug_check[2];
    3645              : 
    3646              : static int n_switches_alloc_debug_check[2];
    3647              : 
    3648              : static char *debug_check_temp_file[2];
    3649              : 
    3650              : /* Language is one of three things:
    3651              : 
    3652              :    1) The name of a real programming language.
    3653              :    2) NULL, indicating that no one has figured out
    3654              :    what it is yet.
    3655              :    3) '*', indicating that the file should be passed
    3656              :    to the linker.  */
    3657              : struct infile
    3658              : {
    3659              :   const char *name;
    3660              :   const char *language;
    3661              :   struct compiler *incompiler;
    3662              :   bool compiled;
    3663              :   bool preprocessed;
    3664              :   bool artificial;
    3665              : };
    3666              : 
    3667              : /* Also a vector of input files specified.  */
    3668              : 
    3669              : static struct infile *infiles;
    3670              : 
    3671              : int n_infiles;
    3672              : 
    3673              : static int n_infiles_alloc;
    3674              : 
    3675              : /* True if undefined environment variables encountered during spec processing
    3676              :    are ok to ignore, typically when we're running for --help or --version.  */
    3677              : 
    3678              : static bool spec_undefvar_allowed;
    3679              : 
    3680              : /* True if multiple input files are being compiled to a single
    3681              :    assembly file.  */
    3682              : 
    3683              : static bool combine_inputs;
    3684              : 
    3685              : /* This counts the number of libraries added by lang_specific_driver, so that
    3686              :    we can tell if there were any user supplied any files or libraries.  */
    3687              : 
    3688              : static int added_libraries;
    3689              : 
    3690              : /* And a vector of corresponding output files is made up later.  */
    3691              : 
    3692              : const char **outfiles;
    3693              : 
    3694              : #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3695              : 
    3696              : /* Convert NAME to a new name if it is the standard suffix.  DO_EXE
    3697              :    is true if we should look for an executable suffix.  DO_OBJ
    3698              :    is true if we should look for an object suffix.  */
    3699              : 
    3700              : static const char *
    3701              : convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
    3702              :                   int do_obj ATTRIBUTE_UNUSED)
    3703              : {
    3704              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3705              :   int i;
    3706              : #endif
    3707              :   int len;
    3708              : 
    3709              :   if (name == NULL)
    3710              :     return NULL;
    3711              : 
    3712              :   len = strlen (name);
    3713              : 
    3714              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    3715              :   /* Convert x.o to x.obj if TARGET_OBJECT_SUFFIX is ".obj".  */
    3716              :   if (do_obj && len > 2
    3717              :       && name[len - 2] == '.'
    3718              :       && name[len - 1] == 'o')
    3719              :     {
    3720              :       obstack_grow (&obstack, name, len - 2);
    3721              :       obstack_grow0 (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    3722              :       name = XOBFINISH (&obstack, const char *);
    3723              :     }
    3724              : #endif
    3725              : 
    3726              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3727              :   /* If there is no filetype, make it the executable suffix (which includes
    3728              :      the ".").  But don't get confused if we have just "-o".  */
    3729              :   if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || not_actual_file_p (name))
    3730              :     return name;
    3731              : 
    3732              :   for (i = len - 1; i >= 0; i--)
    3733              :     if (IS_DIR_SEPARATOR (name[i]))
    3734              :       break;
    3735              : 
    3736              :   for (i++; i < len; i++)
    3737              :     if (name[i] == '.')
    3738              :       return name;
    3739              : 
    3740              :   obstack_grow (&obstack, name, len);
    3741              :   obstack_grow0 (&obstack, TARGET_EXECUTABLE_SUFFIX,
    3742              :                  strlen (TARGET_EXECUTABLE_SUFFIX));
    3743              :   name = XOBFINISH (&obstack, const char *);
    3744              : #endif
    3745              : 
    3746              :   return name;
    3747              : }
    3748              : #endif
    3749              : 
    3750              : /* Display the command line switches accepted by gcc.  */
    3751              : static void
    3752            4 : display_help (void)
    3753              : {
    3754            4 :   printf (_("Usage: %s [options] file...\n"), progname);
    3755            4 :   fputs (_("Options:\n"), stdout);
    3756              : 
    3757            4 :   fputs (_("  -pass-exit-codes         Exit with highest error code from a phase.\n"), stdout);
    3758            4 :   fputs (_("  --help                   Display this information.\n"), stdout);
    3759            4 :   fputs (_("  --target-help            Display target specific command line options "
    3760              :            "(including assembler and linker options).\n"), stdout);
    3761            4 :   fputs (_("  --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].\n"), stdout);
    3762            4 :   fputs (_("                           Display specific types of command line options.\n"), stdout);
    3763            4 :   if (! verbose_flag)
    3764            1 :     fputs (_("  (Use '-v --help' to display command line options of sub-processes).\n"), stdout);
    3765            4 :   fputs (_("  --version                Display compiler version information.\n"), stdout);
    3766            4 :   fputs (_("  -dumpspecs               Display all of the built in spec strings.\n"), stdout);
    3767            4 :   fputs (_("  -dumpversion             Display the version of the compiler.\n"), stdout);
    3768            4 :   fputs (_("  -dumpmachine             Display the compiler's target processor.\n"), stdout);
    3769            4 :   fputs (_("  -foffload=<targets>      Specify offloading targets.\n"), stdout);
    3770            4 :   fputs (_("  -print-search-dirs       Display the directories in the compiler's search path.\n"), stdout);
    3771            4 :   fputs (_("  -print-libgcc-file-name  Display the name of the compiler's companion library.\n"), stdout);
    3772            4 :   fputs (_("  -print-file-name=<lib>   Display the full path to library <lib>.\n"), stdout);
    3773            4 :   fputs (_("  -print-prog-name=<prog>  Display the full path to compiler component <prog>.\n"), stdout);
    3774            4 :   fputs (_("\
    3775              :   -print-multiarch         Display the target's normalized GNU triplet, used as\n\
    3776              :                            a component in the library path.\n"), stdout);
    3777            4 :   fputs (_("  -print-multi-directory   Display the root directory for versions of libgcc.\n"), stdout);
    3778            4 :   fputs (_("\
    3779              :   -print-multi-lib         Display the mapping between command line options and\n\
    3780              :                            multiple library search directories.\n"), stdout);
    3781            4 :   fputs (_("  -print-multi-os-directory Display the relative path to OS libraries.\n"), stdout);
    3782            4 :   fputs (_("  -print-sysroot           Display the target libraries directory.\n"), stdout);
    3783            4 :   fputs (_("  -print-sysroot-headers-suffix Display the sysroot suffix used to find headers.\n"), stdout);
    3784            4 :   fputs (_("  -Wa,<options>            Pass comma-separated <options> on to the assembler.\n"), stdout);
    3785            4 :   fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor.\n"), stdout);
    3786            4 :   fputs (_("  -Wl,<options>            Pass comma-separated <options> on to the linker.\n"), stdout);
    3787            4 :   fputs (_("  -Xassembler <arg>        Pass <arg> on to the assembler.\n"), stdout);
    3788            4 :   fputs (_("  -Xpreprocessor <arg>     Pass <arg> on to the preprocessor.\n"), stdout);
    3789            4 :   fputs (_("  -Xlinker <arg>           Pass <arg> on to the linker.\n"), stdout);
    3790            4 :   fputs (_("  -save-temps              Do not delete intermediate files.\n"), stdout);
    3791            4 :   fputs (_("  -save-temps=<arg>        Do not delete intermediate files.\n"), stdout);
    3792            4 :   fputs (_("\
    3793              :   -no-canonical-prefixes   Do not canonicalize paths when building relative\n\
    3794              :                            prefixes to other gcc components.\n"), stdout);
    3795            4 :   fputs (_("  -pipe                    Use pipes rather than intermediate files.\n"), stdout);
    3796            4 :   fputs (_("  -time                    Time the execution of each subprocess.\n"), stdout);
    3797            4 :   fputs (_("  -specs=<file>            Override built-in specs with the contents of <file>.\n"), stdout);
    3798            4 :   fputs (_("  -std=<standard>          Assume that the input sources are for <standard>.\n"), stdout);
    3799            4 :   fputs (_("\
    3800              :   --sysroot=<directory>    Use <directory> as the root directory for headers\n\
    3801              :                            and libraries.\n"), stdout);
    3802            4 :   fputs (_("  -B <directory>           Add <directory> to the compiler's search paths.\n"), stdout);
    3803            4 :   fputs (_("  -v                       Display the programs invoked by the compiler.\n"), stdout);
    3804            4 :   fputs (_("  -###                     Like -v but options quoted and commands not executed.\n"), stdout);
    3805            4 :   fputs (_("  -E                       Preprocess only; do not compile, assemble or link.\n"), stdout);
    3806            4 :   fputs (_("  -S                       Compile only; do not assemble or link.\n"), stdout);
    3807            4 :   fputs (_("  -c                       Compile and assemble, but do not link.\n"), stdout);
    3808            4 :   fputs (_("  -o <file>                Place the output into <file>.\n"), stdout);
    3809            4 :   fputs (_("  -pie                     Create a dynamically linked position independent\n\
    3810              :                            executable.\n"), stdout);
    3811            4 :   fputs (_("  -shared                  Create a shared library.\n"), stdout);
    3812            4 :   fputs (_("\
    3813              :   -x <language>            Specify the language of the following input files.\n\
    3814              :                            Permissible languages include: c c++ assembler none\n\
    3815              :                            'none' means revert to the default behavior of\n\
    3816              :                            guessing the language based on the file's extension.\n\
    3817              : "), stdout);
    3818              : 
    3819            4 :   printf (_("\
    3820              : \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
    3821              :  passed on to the various sub-processes invoked by %s.  In order to pass\n\
    3822              :  other options on to these processes the -W<letter> options must be used.\n\
    3823              : "), progname);
    3824              : 
    3825              :   /* The rest of the options are displayed by invocations of the various
    3826              :      sub-processes.  */
    3827            4 : }
    3828              : 
    3829              : static void
    3830            0 : add_preprocessor_option (const char *option, int len)
    3831              : {
    3832            0 :   preprocessor_options.safe_push (save_string (option, len));
    3833            0 : }
    3834              : 
    3835              : static void
    3836          195 : add_assembler_option (const char *option, int len)
    3837              : {
    3838          195 :   assembler_options.safe_push (save_string (option, len));
    3839          195 : }
    3840              : 
    3841              : static void
    3842           82 : add_linker_option (const char *option, int len)
    3843              : {
    3844           82 :   linker_options.safe_push (save_string (option, len));
    3845           82 : }
    3846              : 
    3847              : /* Allocate space for an input file in infiles.  */
    3848              : 
    3849              : static void
    3850       865697 : alloc_infile (void)
    3851              : {
    3852       865697 :   if (n_infiles_alloc == 0)
    3853              :     {
    3854       293700 :       n_infiles_alloc = 16;
    3855       293700 :       infiles = XNEWVEC (struct infile, n_infiles_alloc);
    3856              :     }
    3857       571997 :   else if (n_infiles_alloc == n_infiles)
    3858              :     {
    3859          247 :       n_infiles_alloc *= 2;
    3860          247 :       infiles = XRESIZEVEC (struct infile, infiles, n_infiles_alloc);
    3861              :     }
    3862       865697 : }
    3863              : 
    3864              : /* Store an input file with the given NAME and LANGUAGE in
    3865              :    infiles.  */
    3866              : 
    3867              : static void
    3868       571998 : add_infile (const char *name, const char *language, bool art = false)
    3869              : {
    3870       571998 :   alloc_infile ();
    3871       571998 :   infiles[n_infiles].name = name;
    3872       571998 :   infiles[n_infiles].artificial = art;
    3873       571998 :   infiles[n_infiles++].language = language;
    3874       571998 : }
    3875              : 
    3876              : /* Allocate space for a switch in switches.  */
    3877              : 
    3878              : static void
    3879      7498790 : alloc_switch (void)
    3880              : {
    3881      7498790 :   if (n_switches_alloc == 0)
    3882              :     {
    3883       294014 :       n_switches_alloc = 16;
    3884       294014 :       switches = XNEWVEC (struct switchstr, n_switches_alloc);
    3885              :     }
    3886      7204776 :   else if (n_switches_alloc == n_switches)
    3887              :     {
    3888       267622 :       n_switches_alloc *= 2;
    3889       267622 :       switches = XRESIZEVEC (struct switchstr, switches, n_switches_alloc);
    3890              :     }
    3891      7498790 : }
    3892              : 
    3893              : /* Save an option OPT with N_ARGS arguments in array ARGS, marking it
    3894              :    as validated if VALIDATED and KNOWN if it is an internal switch.  */
    3895              : 
    3896              : static void
    3897      6647089 : save_switch (const char *opt, size_t n_args, const char *const *args,
    3898              :              bool validated, bool known)
    3899              : {
    3900      6647089 :   alloc_switch ();
    3901      6647089 :   switches[n_switches].part1 = opt + 1;
    3902      6647089 :   if (n_args == 0)
    3903      5123774 :     switches[n_switches].args = 0;
    3904              :   else
    3905              :     {
    3906      1523315 :       switches[n_switches].args = XNEWVEC (const char *, n_args + 1);
    3907      1523315 :       memcpy (switches[n_switches].args, args, n_args * sizeof (const char *));
    3908      1523315 :       switches[n_switches].args[n_args] = NULL;
    3909              :     }
    3910              : 
    3911      6647089 :   switches[n_switches].live_cond = 0;
    3912      6647089 :   switches[n_switches].validated = validated;
    3913      6647089 :   switches[n_switches].known = known;
    3914      6647089 :   switches[n_switches].ordering = 0;
    3915      6647089 :   n_switches++;
    3916      6647089 : }
    3917              : 
    3918              : /* Set the SOURCE_DATE_EPOCH environment variable to the current time if it is
    3919              :    not set already.  */
    3920              : 
    3921              : static void
    3922          619 : set_source_date_epoch_envvar ()
    3923              : {
    3924              :   /* Array size is 21 = ceil(log_10(2^64)) + 1 to hold string representations
    3925              :      of 64 bit integers.  */
    3926          619 :   char source_date_epoch[21];
    3927          619 :   time_t tt;
    3928              : 
    3929          619 :   errno = 0;
    3930          619 :   tt = time (NULL);
    3931          619 :   if (tt < (time_t) 0 || errno != 0)
    3932            0 :     tt = (time_t) 0;
    3933              : 
    3934          619 :   snprintf (source_date_epoch, 21, "%llu", (unsigned long long) tt);
    3935              :   /* Using setenv instead of xputenv because we want the variable to remain
    3936              :      after finalizing so that it's still set in the second run when using
    3937              :      -fcompare-debug.  */
    3938          619 :   setenv ("SOURCE_DATE_EPOCH", source_date_epoch, 0);
    3939          619 : }
    3940              : 
    3941              : /* Handle an option DECODED that is unknown to the option-processing
    3942              :    machinery.  */
    3943              : 
    3944              : static bool
    3945          683 : driver_unknown_option_callback (const struct cl_decoded_option *decoded)
    3946              : {
    3947          683 :   const char *opt = decoded->arg;
    3948          683 :   if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
    3949           93 :       && !(decoded->errors & CL_ERR_NEGATIVE))
    3950              :     {
    3951              :       /* Leave unknown -Wno-* options for the compiler proper, to be
    3952              :          diagnosed only if there are warnings.  */
    3953           91 :       save_switch (decoded->canonical_option[0],
    3954           91 :                    decoded->canonical_option_num_elements - 1,
    3955              :                    &decoded->canonical_option[1], false, true);
    3956           91 :       return false;
    3957              :     }
    3958          592 :   if (decoded->opt_index == OPT_SPECIAL_unknown)
    3959              :     {
    3960              :       /* Give it a chance to define it a spec file.  */
    3961          592 :       save_switch (decoded->canonical_option[0],
    3962          592 :                    decoded->canonical_option_num_elements - 1,
    3963              :                    &decoded->canonical_option[1], false, false);
    3964          592 :       return false;
    3965              :     }
    3966              :   else
    3967              :     return true;
    3968              : }
    3969              : 
    3970              : /* Handle an option DECODED that is not marked as CL_DRIVER.
    3971              :    LANG_MASK will always be CL_DRIVER.  */
    3972              : 
    3973              : static void
    3974      4290606 : driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
    3975              :                             unsigned int lang_mask ATTRIBUTE_UNUSED)
    3976              : {
    3977              :   /* At this point, non-driver options are accepted (and expected to
    3978              :      be passed down by specs) unless marked to be rejected by the
    3979              :      driver.  Options to be rejected by the driver but accepted by the
    3980              :      compilers proper are treated just like completely unknown
    3981              :      options.  */
    3982      4290606 :   const struct cl_option *option = &cl_options[decoded->opt_index];
    3983              : 
    3984      4290606 :   if (option->cl_reject_driver)
    3985            0 :     error ("unrecognized command-line option %qs",
    3986            0 :            decoded->orig_option_with_args_text);
    3987              :   else
    3988      4290606 :     save_switch (decoded->canonical_option[0],
    3989      4290606 :                  decoded->canonical_option_num_elements - 1,
    3990              :                  &decoded->canonical_option[1], false, true);
    3991      4290606 : }
    3992              : 
    3993              : static const char *spec_lang = 0;
    3994              : static int last_language_n_infiles;
    3995              : 
    3996              : 
    3997              : /* Check that GCC is configured to support the offload target.  */
    3998              : 
    3999              : static bool
    4000          105 : check_offload_target_name (const char *target, ptrdiff_t len)
    4001              : {
    4002          105 :   const char *n, *c = OFFLOAD_TARGETS;
    4003          210 :   while (c)
    4004              :     {
    4005          105 :       n = strchr (c, ',');
    4006          105 :       if (n == NULL)
    4007          105 :         n = strchr (c, '\0');
    4008          105 :       if (len == n - c && strncmp (target, c, n - c) == 0)
    4009              :         break;
    4010          105 :       c = *n ? n + 1 : NULL;
    4011              :     }
    4012          105 :   if (!c)
    4013              :     {
    4014          105 :       auto_vec<const char*> candidates;
    4015          105 :       size_t olen = strlen (OFFLOAD_TARGETS) + 1;
    4016          105 :       char *cand = XALLOCAVEC (char, olen);
    4017          105 :       memcpy (cand, OFFLOAD_TARGETS, olen);
    4018          105 :       for (c = strtok (cand, ","); c; c = strtok (NULL, ","))
    4019            0 :         candidates.safe_push (c);
    4020          105 :       candidates.safe_push ("default");
    4021          105 :       candidates.safe_push ("disable");
    4022              : 
    4023          105 :       char *target2 = XALLOCAVEC (char, len + 1);
    4024          105 :       memcpy (target2, target, len);
    4025          105 :       target2[len] = '\0';
    4026              : 
    4027          105 :       error ("GCC is not configured to support %qs as %<-foffload=%> argument",
    4028              :              target2);
    4029              : 
    4030          105 :       char *s;
    4031          105 :       const char *hint = candidates_list_and_hint (target2, s, candidates);
    4032          105 :       if (hint)
    4033            0 :         inform (UNKNOWN_LOCATION,
    4034              :                 "valid %<-foffload=%> arguments are: %s; "
    4035              :                 "did you mean %qs?", s, hint);
    4036              :       else
    4037          105 :         inform (UNKNOWN_LOCATION, "valid %<-foffload=%> arguments are: %s", s);
    4038          105 :       XDELETEVEC (s);
    4039          105 :       return false;
    4040          105 :     }
    4041              :   return true;
    4042              : }
    4043              : 
    4044              : /* Sanity check for -foffload-options.  */
    4045              : 
    4046              : static void
    4047           27 : check_foffload_target_names (const char *arg)
    4048              : {
    4049           27 :   const char *cur, *next, *end;
    4050              :   /* If option argument starts with '-' then no target is specified and we
    4051              :      do not need to parse it.  */
    4052           27 :   if (arg[0] == '-')
    4053              :     return;
    4054            0 :   end = strchr (arg, '=');
    4055            0 :   if (end == NULL)
    4056              :     {
    4057            0 :       error ("%<=%>options missing after %<-foffload-options=%>target");
    4058            0 :       return;
    4059              :     }
    4060              : 
    4061              :   cur = arg;
    4062            0 :   while (cur < end)
    4063              :     {
    4064            0 :       next = strchr (cur, ',');
    4065            0 :       if (next == NULL)
    4066            0 :         next = end;
    4067            0 :       next = (next > end) ? end : next;
    4068              : 
    4069              :       /* Retain non-supported targets after printing an error as those will not
    4070              :          be processed; each enabled target only processes its triplet.  */
    4071            0 :       check_offload_target_name (cur, next - cur);
    4072            0 :       cur = next + 1;
    4073              :    }
    4074              : }
    4075              : 
    4076              : /* Parse -foffload option argument.  */
    4077              : 
    4078              : static void
    4079         2838 : handle_foffload_option (const char *arg)
    4080              : {
    4081         2838 :   const char *c, *cur, *n, *next, *end;
    4082         2838 :   char *target;
    4083              : 
    4084              :   /* If option argument starts with '-' then no target is specified and we
    4085              :      do not need to parse it.  */
    4086         2838 :   if (arg[0] == '-')
    4087              :     return;
    4088              : 
    4089         1999 :   end = strchr (arg, '=');
    4090         1999 :   if (end == NULL)
    4091         1999 :     end = strchr (arg, '\0');
    4092         1999 :   cur = arg;
    4093              : 
    4094         1999 :   while (cur < end)
    4095              :     {
    4096         1999 :       next = strchr (cur, ',');
    4097         1999 :       if (next == NULL)
    4098         1999 :         next = end;
    4099         1999 :       next = (next > end) ? end : next;
    4100              : 
    4101         1999 :       target = XNEWVEC (char, next - cur + 1);
    4102         1999 :       memcpy (target, cur, next - cur);
    4103         1999 :       target[next - cur] = '\0';
    4104              : 
    4105              :       /* Reset offloading list and continue.  */
    4106         1999 :       if (strcmp (target, "default") == 0)
    4107              :         {
    4108            0 :           free (offload_targets);
    4109            0 :           offload_targets = NULL;
    4110            0 :           goto next_item;
    4111              :         }
    4112              : 
    4113              :       /* If 'disable' is passed to the option, clean the list of
    4114              :          offload targets and return, even if more targets follow.
    4115              :          Likewise if GCC is not configured to support that offload target.  */
    4116         1999 :       if (strcmp (target, "disable") == 0
    4117         1999 :           || !check_offload_target_name (target, next - cur))
    4118              :         {
    4119         1999 :           free (offload_targets);
    4120         1999 :           offload_targets = xstrdup ("");
    4121         1999 :           return;
    4122              :         }
    4123              : 
    4124            0 :       if (!offload_targets)
    4125              :         {
    4126            0 :           offload_targets = target;
    4127            0 :           target = NULL;
    4128              :         }
    4129              :       else
    4130              :         {
    4131              :           /* Check that the target hasn't already presented in the list.  */
    4132              :           c = offload_targets;
    4133            0 :           do
    4134              :             {
    4135            0 :               n = strchr (c, ':');
    4136            0 :               if (n == NULL)
    4137            0 :                 n = strchr (c, '\0');
    4138              : 
    4139            0 :               if (next - cur == n - c && strncmp (c, target, n - c) == 0)
    4140              :                 break;
    4141              : 
    4142            0 :               c = n + 1;
    4143              :             }
    4144            0 :           while (*n);
    4145              : 
    4146              :           /* If duplicate is not found, append the target to the list.  */
    4147            0 :           if (c > n)
    4148              :             {
    4149            0 :               size_t offload_targets_len = strlen (offload_targets);
    4150            0 :               offload_targets
    4151            0 :                 = XRESIZEVEC (char, offload_targets,
    4152              :                               offload_targets_len + 1 + next - cur + 1);
    4153            0 :               offload_targets[offload_targets_len++] = ':';
    4154            0 :               memcpy (offload_targets + offload_targets_len, target, next - cur + 1);
    4155              :             }
    4156              :         }
    4157            0 : next_item:
    4158            0 :       cur = next + 1;
    4159            0 :       XDELETEVEC (target);
    4160              :     }
    4161              : }
    4162              : 
    4163              : /* Forward certain options to offloading compilation.  */
    4164              : 
    4165              : static void
    4166            0 : forward_offload_option (size_t opt_index, const char *arg, bool validated)
    4167              : {
    4168            0 :   switch (opt_index)
    4169              :     {
    4170            0 :     case OPT_l:
    4171              :       /* Use a '_GCC_' prefix and standard name ('-l_GCC_m' irrespective of the
    4172              :          host's 'MATH_LIBRARY', for example), so that the 'mkoffload's can tell
    4173              :          this has been synthesized here, and translate/drop as necessary.  */
    4174              :       /* Note that certain libraries ('-lc', '-lgcc', '-lgomp', for example)
    4175              :          are injected by default in offloading compilation, and therefore not
    4176              :          forwarded here.  */
    4177              :       /* GCC libraries.  */
    4178            0 :       if (/* '-lgfortran' */ strcmp (arg, "gfortran") == 0
    4179            0 :           || /* '-lstdc++' */ strcmp (arg, "stdc++") == 0)
    4180            0 :         save_switch (concat ("-foffload-options=-l_GCC_", arg, NULL),
    4181              :                      0, NULL, validated, true);
    4182              :       /* Other libraries.  */
    4183              :       else
    4184              :         {
    4185              :           /* The case will need special consideration where on the host
    4186              :              '!need_math', but for offloading compilation still need
    4187              :              '-foffload-options=-l_GCC_m'.  The problem is that we don't get
    4188              :              here anything like '-lm', because it's not synthesized in
    4189              :              'gcc/fortran/gfortranspec.cc:lang_specific_driver', for example.
    4190              :              Generally synthesizing '-foffload-options=-l_GCC_m' etc. in the
    4191              :              language specific drivers is non-trivial, needs very careful
    4192              :              review of their options handling.  However, this issue is not
    4193              :              actually relevant for the current set of supported host/offloading
    4194              :              configurations.  */
    4195            0 :           int need_math = (MATH_LIBRARY[0] != '\0');
    4196            0 :           if (/* '-lm' */ (need_math && strcmp (arg, MATH_LIBRARY) == 0))
    4197            0 :             save_switch ("-foffload-options=-l_GCC_m",
    4198              :                          0, NULL, validated, true);
    4199              :         }
    4200            0 :       break;
    4201            0 :     default:
    4202            0 :       gcc_unreachable ();
    4203              :     }
    4204            0 : }
    4205              : 
    4206              : /* Handle a driver option; arguments and return value as for
    4207              :    handle_option.  */
    4208              : 
    4209              : static bool
    4210      2678877 : driver_handle_option (struct gcc_options *opts,
    4211              :                       struct gcc_options *opts_set,
    4212              :                       const struct cl_decoded_option *decoded,
    4213              :                       unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
    4214              :                       location_t loc,
    4215              :                       const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
    4216              :                       diagnostics::context *dc,
    4217              :                       void (*) (void))
    4218              : {
    4219      2678877 :   size_t opt_index = decoded->opt_index;
    4220      2678877 :   const char *arg = decoded->arg;
    4221      2678877 :   const char *compare_debug_replacement_opt;
    4222      2678877 :   int value = decoded->value;
    4223      2678877 :   bool validated = false;
    4224      2678877 :   bool do_save = true;
    4225              : 
    4226      2678877 :   gcc_assert (opts == &global_options);
    4227      2678877 :   gcc_assert (opts_set == &global_options_set);
    4228      2678877 :   gcc_assert (static_cast<diagnostics::kind> (kind)
    4229              :               == diagnostics::kind::unspecified);
    4230      2678877 :   gcc_assert (loc == UNKNOWN_LOCATION);
    4231      2678877 :   gcc_assert (dc == global_dc);
    4232              : 
    4233      2678877 :   switch (opt_index)
    4234              :     {
    4235            1 :     case OPT_dumpspecs:
    4236            1 :       {
    4237            1 :         struct spec_list *sl;
    4238            1 :         init_spec ();
    4239           47 :         for (sl = specs; sl; sl = sl->next)
    4240           46 :           printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
    4241            1 :         if (link_command_spec)
    4242            1 :           printf ("*link_command:\n%s\n\n", link_command_spec);
    4243            1 :         exit (0);
    4244              :       }
    4245              : 
    4246          280 :     case OPT_dumpversion:
    4247          280 :       printf ("%s\n", spec_version);
    4248          280 :       exit (0);
    4249              : 
    4250            0 :     case OPT_dumpmachine:
    4251            0 :       printf ("%s\n", spec_machine);
    4252            0 :       exit (0);
    4253              : 
    4254            0 :     case OPT_dumpfullversion:
    4255            0 :       printf ("%s\n", BASEVER);
    4256            0 :       exit (0);
    4257              : 
    4258           78 :     case OPT__version:
    4259           78 :       print_version = 1;
    4260              : 
    4261              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4262           78 :       if (is_cpp_driver)
    4263            0 :         add_preprocessor_option ("--version", strlen ("--version"));
    4264           78 :       add_assembler_option ("--version", strlen ("--version"));
    4265           78 :       add_linker_option ("--version", strlen ("--version"));
    4266           78 :       break;
    4267              : 
    4268            5 :     case OPT__completion_:
    4269            5 :       validated = true;
    4270            5 :       completion = decoded->arg;
    4271            5 :       break;
    4272              : 
    4273            4 :     case OPT__help:
    4274            4 :       print_help_list = 1;
    4275              : 
    4276              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4277            4 :       if (is_cpp_driver)
    4278            0 :         add_preprocessor_option ("--help", 6);
    4279            4 :       add_assembler_option ("--help", 6);
    4280            4 :       add_linker_option ("--help", 6);
    4281            4 :       break;
    4282              : 
    4283           73 :     case OPT__help_:
    4284           73 :       print_subprocess_help = 2;
    4285           73 :       break;
    4286              : 
    4287            0 :     case OPT__target_help:
    4288            0 :       print_subprocess_help = 1;
    4289              : 
    4290              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4291            0 :       if (is_cpp_driver)
    4292            0 :         add_preprocessor_option ("--target-help", 13);
    4293            0 :       add_assembler_option ("--target-help", 13);
    4294            0 :       add_linker_option ("--target-help", 13);
    4295            0 :       break;
    4296              : 
    4297              :     case OPT__no_sysroot_suffix:
    4298              :     case OPT_pass_exit_codes:
    4299              :     case OPT_print_search_dirs:
    4300              :     case OPT_print_file_name_:
    4301              :     case OPT_print_prog_name_:
    4302              :     case OPT_print_multi_lib:
    4303              :     case OPT_print_multi_directory:
    4304              :     case OPT_print_sysroot:
    4305              :     case OPT_print_multi_os_directory:
    4306              :     case OPT_print_multiarch:
    4307              :     case OPT_print_sysroot_headers_suffix:
    4308              :     case OPT_time:
    4309              :     case OPT_wrapper:
    4310              :       /* These options set the variables specified in common.opt
    4311              :          automatically, and do not need to be saved for spec
    4312              :          processing.  */
    4313              :       do_save = false;
    4314              :       break;
    4315              : 
    4316          392 :     case OPT_print_libgcc_file_name:
    4317          392 :       print_file_name = "libgcc.a";
    4318          392 :       do_save = false;
    4319          392 :       break;
    4320              : 
    4321            0 :     case OPT_fuse_ld_bfd:
    4322            0 :        use_ld = ".bfd";
    4323            0 :        break;
    4324              : 
    4325            0 :     case OPT_fuse_ld_gold:
    4326            0 :        use_ld = ".gold";
    4327            0 :        break;
    4328              : 
    4329            0 :     case OPT_fuse_ld_mold:
    4330            0 :        use_ld = ".mold";
    4331            0 :        break;
    4332              : 
    4333            0 :     case OPT_fuse_ld_wild:
    4334            0 :        use_ld = ".wild";
    4335            0 :        break;
    4336              : 
    4337            0 :     case OPT_fcompare_debug_second:
    4338            0 :       compare_debug_second = 1;
    4339            0 :       break;
    4340              : 
    4341          613 :     case OPT_fcompare_debug:
    4342          613 :       switch (value)
    4343              :         {
    4344            0 :         case 0:
    4345            0 :           compare_debug_replacement_opt = "-fcompare-debug=";
    4346            0 :           arg = "";
    4347            0 :           goto compare_debug_with_arg;
    4348              : 
    4349          613 :         case 1:
    4350          613 :           compare_debug_replacement_opt = "-fcompare-debug=-gtoggle";
    4351          613 :           arg = "-gtoggle";
    4352          613 :           goto compare_debug_with_arg;
    4353              : 
    4354            0 :         default:
    4355            0 :           gcc_unreachable ();
    4356              :         }
    4357            6 :       break;
    4358              : 
    4359            6 :     case OPT_fcompare_debug_:
    4360            6 :       compare_debug_replacement_opt = decoded->canonical_option[0];
    4361          619 :     compare_debug_with_arg:
    4362          619 :       gcc_assert (decoded->canonical_option_num_elements == 1);
    4363          619 :       gcc_assert (arg != NULL);
    4364          619 :       if (*arg)
    4365          619 :         compare_debug = 1;
    4366              :       else
    4367            0 :         compare_debug = -1;
    4368          619 :       if (compare_debug < 0)
    4369            0 :         compare_debug_opt = NULL;
    4370              :       else
    4371          619 :         compare_debug_opt = arg;
    4372          619 :       save_switch (compare_debug_replacement_opt, 0, NULL, validated, true);
    4373          619 :       set_source_date_epoch_envvar ();
    4374          619 :       return true;
    4375              : 
    4376       266015 :     case OPT_fdiagnostics_color_:
    4377       266015 :       diagnostic_color_init (dc, value);
    4378       266015 :       break;
    4379              : 
    4380       261689 :     case OPT_fdiagnostics_urls_:
    4381       261689 :       diagnostic_urls_init (dc, value);
    4382       261689 :       break;
    4383              : 
    4384            0 :     case OPT_fdiagnostics_show_highlight_colors:
    4385            0 :       dc->set_show_highlight_colors (value);
    4386            0 :       break;
    4387              : 
    4388            0 :     case OPT_fdiagnostics_format_:
    4389            0 :         {
    4390            0 :           const char *basename = get_diagnostic_file_output_basename (*opts);
    4391            0 :           gcc_assert (dc);
    4392            0 :           diagnostics::output_format_init (*dc,
    4393              :                                            opts->x_main_input_filename, basename,
    4394              :                                            (enum diagnostics_output_format)value,
    4395            0 :                                            opts->x_flag_diagnostics_json_formatting);
    4396            0 :           break;
    4397              :         }
    4398              : 
    4399            0 :     case OPT_fdiagnostics_add_output_:
    4400            0 :       handle_OPT_fdiagnostics_add_output_ (*opts, *dc, arg, loc);
    4401            0 :       break;
    4402              : 
    4403            0 :     case OPT_fdiagnostics_set_output_:
    4404            0 :       handle_OPT_fdiagnostics_set_output_ (*opts, *dc, arg, loc);
    4405            0 :       break;
    4406              : 
    4407       290459 :     case OPT_fdiagnostics_text_art_charset_:
    4408       290459 :       dc->set_text_art_charset ((enum diagnostic_text_art_charset)value);
    4409       290459 :       break;
    4410              : 
    4411              :     case OPT_Wa_:
    4412              :       {
    4413              :         int prev, j;
    4414              :         /* Pass the rest of this option to the assembler.  */
    4415              : 
    4416              :         /* Split the argument at commas.  */
    4417              :         prev = 0;
    4418          634 :         for (j = 0; arg[j]; j++)
    4419          586 :           if (arg[j] == ',')
    4420              :             {
    4421            0 :               add_assembler_option (arg + prev, j - prev);
    4422            0 :               prev = j + 1;
    4423              :             }
    4424              : 
    4425              :         /* Record the part after the last comma.  */
    4426           48 :         add_assembler_option (arg + prev, j - prev);
    4427              :       }
    4428           48 :       do_save = false;
    4429           48 :       break;
    4430              : 
    4431              :     case OPT_Wp_:
    4432              :       {
    4433              :         int prev, j;
    4434              :         /* Pass the rest of this option to the preprocessor.  */
    4435              : 
    4436              :         /* Split the argument at commas.  */
    4437              :         prev = 0;
    4438            0 :         for (j = 0; arg[j]; j++)
    4439            0 :           if (arg[j] == ',')
    4440              :             {
    4441            0 :               add_preprocessor_option (arg + prev, j - prev);
    4442            0 :               prev = j + 1;
    4443              :             }
    4444              : 
    4445              :         /* Record the part after the last comma.  */
    4446            0 :         add_preprocessor_option (arg + prev, j - prev);
    4447              :       }
    4448            0 :       do_save = false;
    4449            0 :       break;
    4450              : 
    4451              :     case OPT_Wl_:
    4452              :       {
    4453              :         int prev, j;
    4454              :         /* Split the argument at commas.  */
    4455              :         prev = 0;
    4456       124688 :         for (j = 0; arg[j]; j++)
    4457       117232 :           if (arg[j] == ',')
    4458              :             {
    4459           54 :               add_infile (save_string (arg + prev, j - prev), "*");
    4460           54 :               prev = j + 1;
    4461              :             }
    4462              :         /* Record the part after the last comma.  */
    4463         7456 :         add_infile (arg + prev, "*");
    4464         7456 :         if (strcmp (arg, "-z,lazy") == 0 || strcmp (arg, "-z,norelro") == 0)
    4465           12 :           avoid_linker_hardening_p = true;
    4466              :       }
    4467              :       do_save = false;
    4468              :       break;
    4469              : 
    4470           12 :     case OPT_z:
    4471           12 :       if (strcmp (arg, "lazy") == 0 || strcmp (arg, "norelro") == 0)
    4472           12 :         avoid_linker_hardening_p = true;
    4473              :       break;
    4474              : 
    4475            0 :     case OPT_Xlinker:
    4476            0 :       add_infile (arg, "*");
    4477            0 :       do_save = false;
    4478            0 :       break;
    4479              : 
    4480            0 :     case OPT_Xpreprocessor:
    4481            0 :       add_preprocessor_option (arg, strlen (arg));
    4482            0 :       do_save = false;
    4483            0 :       break;
    4484              : 
    4485           65 :     case OPT_Xassembler:
    4486           65 :       add_assembler_option (arg, strlen (arg));
    4487           65 :       do_save = false;
    4488           65 :       break;
    4489              : 
    4490       245854 :     case OPT_l:
    4491              :       /* POSIX allows separation of -l and the lib arg; canonicalize
    4492              :          by concatenating -l with its arg */
    4493       245854 :       add_infile (concat ("-l", arg, NULL), "*");
    4494              : 
    4495              :       /* Forward to offloading compilation '-l[...]' flags for standard,
    4496              :          well-known libraries.  */
    4497              :       /* Doing this processing here means that we don't get to see libraries
    4498              :          injected via specs, such as '-lquadmath' injected via
    4499              :          '[build]/[target]/libgfortran/libgfortran.spec'.  However, this issue
    4500              :          is not actually relevant for the current set of host/offloading
    4501              :          configurations.  */
    4502       245854 :       if (ENABLE_OFFLOADING)
    4503              :         forward_offload_option (opt_index, arg, validated);
    4504              : 
    4505       245854 :       do_save = false;
    4506       245854 :       break;
    4507              : 
    4508       259524 :     case OPT_L:
    4509              :       /* Similarly, canonicalize -L for linkers that may not accept
    4510              :          separate arguments.  */
    4511       259524 :       save_switch (concat ("-L", arg, NULL), 0, NULL, validated, true);
    4512       259524 :       return true;
    4513              : 
    4514            0 :     case OPT_F:
    4515              :       /* Likewise -F.  */
    4516            0 :       save_switch (concat ("-F", arg, NULL), 0, NULL, validated, true);
    4517            0 :       return true;
    4518              : 
    4519          407 :     case OPT_save_temps:
    4520          407 :       if (!save_temps_flag)
    4521          401 :         save_temps_flag = SAVE_TEMPS_DUMP;
    4522              :       validated = true;
    4523              :       break;
    4524              : 
    4525           58 :     case OPT_save_temps_:
    4526           58 :       if (strcmp (arg, "cwd") == 0)
    4527           29 :         save_temps_flag = SAVE_TEMPS_CWD;
    4528           29 :       else if (strcmp (arg, "obj") == 0
    4529            0 :                || strcmp (arg, "object") == 0)
    4530           29 :         save_temps_flag = SAVE_TEMPS_OBJ;
    4531              :       else
    4532            0 :         fatal_error (input_location, "%qs is an unknown %<-save-temps%> option",
    4533            0 :                      decoded->orig_option_with_args_text);
    4534           58 :       save_temps_overrides_dumpdir = true;
    4535           58 :       break;
    4536              : 
    4537        20556 :     case OPT_dumpdir:
    4538        20556 :       free (dumpdir);
    4539        20556 :       dumpdir = xstrdup (arg);
    4540        20556 :       save_temps_overrides_dumpdir = false;
    4541        20556 :       break;
    4542              : 
    4543        21992 :     case OPT_dumpbase:
    4544        21992 :       free (dumpbase);
    4545        21992 :       dumpbase = xstrdup (arg);
    4546        21992 :       break;
    4547              : 
    4548          252 :     case OPT_dumpbase_ext:
    4549          252 :       free (dumpbase_ext);
    4550          252 :       dumpbase_ext = xstrdup (arg);
    4551          252 :       break;
    4552              : 
    4553              :     case OPT_no_canonical_prefixes:
    4554              :       /* Already handled as a special case, so ignored here.  */
    4555              :       do_save = false;
    4556              :       break;
    4557              : 
    4558              :     case OPT_pipe:
    4559              :       validated = true;
    4560              :       /* These options set the variables specified in common.opt
    4561              :          automatically, but do need to be saved for spec
    4562              :          processing.  */
    4563              :       break;
    4564              : 
    4565            3 :     case OPT_specs_:
    4566            3 :       {
    4567            3 :         struct user_specs *user = XNEW (struct user_specs);
    4568              : 
    4569            3 :         user->next = (struct user_specs *) 0;
    4570            3 :         user->filename = arg;
    4571            3 :         if (user_specs_tail)
    4572            0 :           user_specs_tail->next = user;
    4573              :         else
    4574            3 :           user_specs_head = user;
    4575            3 :         user_specs_tail = user;
    4576              :       }
    4577            3 :       validated = true;
    4578            3 :       break;
    4579              : 
    4580            0 :     case OPT__sysroot_:
    4581            0 :       target_system_root = arg;
    4582            0 :       target_system_root_changed = 1;
    4583              :       /* Saving this option is useful to let self-specs decide to
    4584              :          provide a default one.  */
    4585            0 :       do_save = true;
    4586            0 :       validated = true;
    4587            0 :       break;
    4588              : 
    4589            0 :     case OPT_time_:
    4590            0 :       if (report_times_to_file)
    4591            0 :         fclose (report_times_to_file);
    4592            0 :       report_times_to_file = fopen (arg, "a");
    4593            0 :       do_save = false;
    4594            0 :       break;
    4595              : 
    4596         8111 :     case OPT_truncate:
    4597         8111 :       totruncate_file = arg;
    4598         8111 :       do_save = false;
    4599         8111 :       break;
    4600              : 
    4601          642 :     case OPT____:
    4602              :       /* "-###"
    4603              :          This is similar to -v except that there is no execution
    4604              :          of the commands and the echoed arguments are quoted.  It
    4605              :          is intended for use in shell scripts to capture the
    4606              :          driver-generated command line.  */
    4607          642 :       verbose_only_flag++;
    4608          642 :       verbose_flag = 1;
    4609          642 :       do_save = false;
    4610          642 :       break;
    4611              : 
    4612       484199 :     case OPT_B:
    4613       484199 :       {
    4614       484199 :         size_t len = strlen (arg);
    4615              : 
    4616              :         /* Catch the case where the user has forgotten to append a
    4617              :            directory separator to the path.  Note, they may be using
    4618              :            -B to add an executable name prefix, eg "i386-elf-", in
    4619              :            order to distinguish between multiple installations of
    4620              :            GCC in the same directory.  Hence we must check to see
    4621              :            if appending a directory separator actually makes a
    4622              :            valid directory name.  */
    4623       484199 :         if (!IS_DIR_SEPARATOR (arg[len - 1])
    4624       484199 :             && is_directory (arg))
    4625              :           {
    4626        94162 :             char *tmp = XNEWVEC (char, len + 2);
    4627        94162 :             strcpy (tmp, arg);
    4628        94162 :             tmp[len] = DIR_SEPARATOR;
    4629        94162 :             tmp[++len] = 0;
    4630        94162 :             arg = tmp;
    4631              :           }
    4632              : 
    4633       484199 :         add_prefix (&exec_prefixes, arg, NULL,
    4634              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4635       484199 :         add_prefix (&startfile_prefixes, arg, NULL,
    4636              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4637       484199 :         add_prefix (&include_prefixes, arg, NULL,
    4638              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4639              :       }
    4640       484199 :       validated = true;
    4641       484199 :       break;
    4642              : 
    4643         2474 :     case OPT_E:
    4644         2474 :       have_E = true;
    4645         2474 :       break;
    4646              : 
    4647        48739 :     case OPT_x:
    4648        48739 :       spec_lang = arg;
    4649        48739 :       if (!strcmp (spec_lang, "none"))
    4650              :         /* Suppress the warning if -xnone comes after the last input
    4651              :            file, because alternate command interfaces like g++ might
    4652              :            find it useful to place -xnone after each input file.  */
    4653        13347 :         spec_lang = 0;
    4654              :       else
    4655        35392 :         last_language_n_infiles = n_infiles;
    4656              :       do_save = false;
    4657              :       break;
    4658              : 
    4659       270001 :     case OPT_o:
    4660       270001 :       have_o = 1;
    4661              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
    4662              :       arg = convert_filename (arg, ! have_c, 0);
    4663              : #endif
    4664       270001 :       output_file = arg;
    4665              :       /* On some systems, ld cannot handle "-o" without a space.  So
    4666              :          split the option from its argument.  */
    4667       270001 :       save_switch ("-o", 1, &arg, validated, true);
    4668       270001 :       return true;
    4669              : 
    4670         2158 :     case OPT_pie:
    4671              : #ifdef ENABLE_DEFAULT_PIE
    4672              :       /* -pie is turned on by default.  */
    4673              :       validated = true;
    4674              : #endif
    4675              :       /* FALLTHROUGH */
    4676         2158 :     case OPT_r:
    4677         2158 :     case OPT_shared:
    4678         2158 :     case OPT_no_pie:
    4679         2158 :       avoid_linker_hardening_p = true;
    4680         2158 :       break;
    4681              : 
    4682           99 :     case OPT_static:
    4683           99 :       static_p = true;
    4684           99 :       break;
    4685              : 
    4686              :     case OPT_static_libgcc:
    4687              :     case OPT_shared_libgcc:
    4688              :     case OPT_static_libgfortran:
    4689              :     case OPT_static_libquadmath:
    4690              :     case OPT_static_libphobos:
    4691              :     case OPT_static_libga68:
    4692              :     case OPT_static_libgm2:
    4693              :     case OPT_static_libstdc__:
    4694              :       /* These are always valid; gcc.cc itself understands the first two
    4695              :          gfortranspec.cc understands -static-libgfortran,
    4696              :          libgfortran.spec handles -static-libquadmath,
    4697              :          a68spec.cc understands -static-libga68,
    4698              :          d-spec.cc understands -static-libphobos,
    4699              :          gm2spec.cc understands -static-libgm2,
    4700              :          and g++spec.cc understands -static-libstdc++.  */
    4701              :       validated = true;
    4702              :       break;
    4703              : 
    4704           78 :     case OPT_fwpa:
    4705           78 :       flag_wpa = "";
    4706           78 :       break;
    4707              : 
    4708           27 :     case OPT_foffload_options_:
    4709           27 :       check_foffload_target_names (arg);
    4710           27 :       break;
    4711              : 
    4712         2838 :     case OPT_foffload_:
    4713         2838 :       handle_foffload_option (arg);
    4714         2838 :       if (arg[0] == '-' || NULL != strchr (arg, '='))
    4715          839 :         save_switch (concat ("-foffload-options=", arg, NULL),
    4716              :                      0, NULL, validated, true);
    4717              :       do_save = false;
    4718              :       break;
    4719              : 
    4720            0 :     case OPT_gcodeview:
    4721            0 :       add_infile ("--pdb=", "*");
    4722            0 :       break;
    4723              : 
    4724              :     default:
    4725              :       /* Various driver options need no special processing at this
    4726              :          point, having been handled in a prescan above or being
    4727              :          handled by specs.  */
    4728              :       break;
    4729              :     }
    4730              : 
    4731      1605343 :   if (do_save)
    4732      1823512 :     save_switch (decoded->canonical_option[0],
    4733      1823512 :                  decoded->canonical_option_num_elements - 1,
    4734              :                  &decoded->canonical_option[1], validated, true);
    4735              :   return true;
    4736              : }
    4737              : 
    4738              : /* Return true if F2 is F1 followed by a single suffix, i.e., by a
    4739              :    period and additional characters other than a period.  */
    4740              : 
    4741              : static inline bool
    4742        83828 : adds_single_suffix_p (const char *f2, const char *f1)
    4743              : {
    4744        83828 :   size_t len = strlen (f1);
    4745              : 
    4746        83828 :   return (strncmp (f1, f2, len) == 0
    4747        76277 :           && f2[len] == '.'
    4748       159634 :           && strchr (f2 + len + 1, '.') == NULL);
    4749              : }
    4750              : 
    4751              : /* Put the driver's standard set of option handlers in *HANDLERS.  */
    4752              : 
    4753              : static void
    4754       851983 : set_option_handlers (struct cl_option_handlers *handlers)
    4755              : {
    4756       851983 :   handlers->unknown_option_callback = driver_unknown_option_callback;
    4757       851983 :   handlers->wrong_lang_callback = driver_wrong_lang_callback;
    4758       851983 :   handlers->num_handlers = 3;
    4759       851983 :   handlers->handlers[0].handler = driver_handle_option;
    4760       851983 :   handlers->handlers[0].mask = CL_DRIVER;
    4761       851983 :   handlers->handlers[1].handler = common_handle_option;
    4762       851983 :   handlers->handlers[1].mask = CL_COMMON;
    4763       851983 :   handlers->handlers[2].handler = target_handle_option;
    4764       851983 :   handlers->handlers[2].mask = CL_TARGET;
    4765            0 : }
    4766              : 
    4767              : 
    4768              : /* Return the index into infiles for the single non-library
    4769              :    non-lto-wpa input file, -1 if there isn't any, or -2 if there is
    4770              :    more than one.  */
    4771              : static inline int
    4772       146551 : single_input_file_index ()
    4773              : {
    4774       146551 :   int ret = -1;
    4775              : 
    4776       476318 :   for (int i = 0; i < n_infiles; i++)
    4777              :     {
    4778       341921 :       if (infiles[i].language
    4779       237453 :           && (infiles[i].language[0] == '*'
    4780        45628 :               || (flag_wpa
    4781        17096 :                   && strcmp (infiles[i].language, "lto") == 0)))
    4782       208921 :         continue;
    4783              : 
    4784       133000 :       if (ret != -1)
    4785              :         return -2;
    4786              : 
    4787              :       ret = i;
    4788              :     }
    4789              : 
    4790              :   return ret;
    4791              : }
    4792              : 
    4793              : /* Create the vector `switches' and its contents.
    4794              :    Store its length in `n_switches'.  */
    4795              : 
    4796              : static void
    4797       293985 : process_command (unsigned int decoded_options_count,
    4798              :                  struct cl_decoded_option *decoded_options)
    4799              : {
    4800       293985 :   const char *temp;
    4801       293985 :   char *temp1;
    4802       293985 :   char *tooldir_prefix, *tooldir_prefix2;
    4803       293985 :   char *(*get_relative_prefix) (const char *, const char *,
    4804              :                                 const char *) = NULL;
    4805       293985 :   struct cl_option_handlers handlers;
    4806       293985 :   unsigned int j;
    4807              : 
    4808       293985 :   gcc_exec_prefix = env.get ("GCC_EXEC_PREFIX");
    4809              : 
    4810       293985 :   n_switches = 0;
    4811       293985 :   n_infiles = 0;
    4812       293985 :   added_libraries = 0;
    4813              : 
    4814              :   /* Figure compiler version from version string.  */
    4815              : 
    4816       293985 :   compiler_version = temp1 = xstrdup (version_string);
    4817              : 
    4818      2057895 :   for (; *temp1; ++temp1)
    4819              :     {
    4820      2057895 :       if (*temp1 == ' ')
    4821              :         {
    4822       293985 :           *temp1 = '\0';
    4823       293985 :           break;
    4824              :         }
    4825              :     }
    4826              : 
    4827              :   /* Handle any -no-canonical-prefixes flag early, to assign the function
    4828              :      that builds relative prefixes.  This function creates default search
    4829              :      paths that are needed later in normal option handling.  */
    4830              : 
    4831      6663662 :   for (j = 1; j < decoded_options_count; j++)
    4832              :     {
    4833      6369677 :       if (decoded_options[j].opt_index == OPT_no_canonical_prefixes)
    4834              :         {
    4835              :           get_relative_prefix = make_relative_prefix_ignore_links;
    4836              :           break;
    4837              :         }
    4838              :     }
    4839       293985 :   if (! get_relative_prefix)
    4840       293985 :     get_relative_prefix = make_relative_prefix;
    4841              : 
    4842              :   /* Set up the default search paths.  If there is no GCC_EXEC_PREFIX,
    4843              :      see if we can create it from the pathname specified in
    4844              :      decoded_options[0].arg.  */
    4845              : 
    4846       293985 :   gcc_libexec_prefix = standard_libexec_prefix;
    4847              : #ifndef VMS
    4848              :   /* FIXME: make_relative_prefix doesn't yet work for VMS.  */
    4849       293985 :   if (!gcc_exec_prefix)
    4850              :     {
    4851        29275 :       gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg,
    4852              :                                              standard_bindir_prefix,
    4853              :                                              standard_exec_prefix);
    4854        29275 :       gcc_libexec_prefix = get_relative_prefix (decoded_options[0].arg,
    4855              :                                              standard_bindir_prefix,
    4856              :                                              standard_libexec_prefix);
    4857        29275 :       if (gcc_exec_prefix)
    4858        29275 :         xputenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
    4859              :     }
    4860              :   else
    4861              :     {
    4862              :       /* make_relative_prefix requires a program name, but
    4863              :          GCC_EXEC_PREFIX is typically a directory name with a trailing
    4864              :          / (which is ignored by make_relative_prefix), so append a
    4865              :          program name.  */
    4866       264710 :       char *tmp_prefix = concat (gcc_exec_prefix, "gcc", NULL);
    4867       264710 :       gcc_libexec_prefix = get_relative_prefix (tmp_prefix,
    4868              :                                                 standard_exec_prefix,
    4869              :                                                 standard_libexec_prefix);
    4870              : 
    4871              :       /* The path is unrelocated, so fallback to the original setting.  */
    4872       264710 :       if (!gcc_libexec_prefix)
    4873       264365 :         gcc_libexec_prefix = standard_libexec_prefix;
    4874              : 
    4875       264710 :       free (tmp_prefix);
    4876              :     }
    4877              : #else
    4878              : #endif
    4879              :   /* From this point onward, gcc_exec_prefix is non-null if the toolchain
    4880              :      is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX
    4881              :      or an automatically created GCC_EXEC_PREFIX from
    4882              :      decoded_options[0].arg.  */
    4883              : 
    4884              :   /* Do language-specific adjustment/addition of flags.  */
    4885       293985 :   lang_specific_driver (&decoded_options, &decoded_options_count,
    4886              :                         &added_libraries);
    4887              : 
    4888       293981 :   if (gcc_exec_prefix)
    4889              :     {
    4890       293981 :       int len = strlen (gcc_exec_prefix);
    4891              : 
    4892       293981 :       if (len > (int) sizeof ("/lib/gcc/") - 1
    4893       293981 :           && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
    4894              :         {
    4895       293981 :           temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
    4896       293981 :           if (IS_DIR_SEPARATOR (*temp)
    4897       293981 :               && filename_ncmp (temp + 1, "lib", 3) == 0
    4898       293981 :               && IS_DIR_SEPARATOR (temp[4])
    4899       587962 :               && filename_ncmp (temp + 5, "gcc", 3) == 0)
    4900       293981 :             len -= sizeof ("/lib/gcc/") - 1;
    4901              :         }
    4902              : 
    4903       293981 :       set_std_prefix (gcc_exec_prefix, len);
    4904       293981 :       add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
    4905              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4906       293981 :       add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
    4907              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4908              :     }
    4909              : 
    4910              :   /* COMPILER_PATH and LIBRARY_PATH have values
    4911              :      that are lists of directory names with colons.  */
    4912              : 
    4913       293981 :   temp = env.get ("COMPILER_PATH");
    4914       293981 :   if (temp)
    4915              :     {
    4916        20392 :       const char *startp, *endp;
    4917        20392 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4918              : 
    4919        20392 :       startp = endp = temp;
    4920      1865546 :       while (1)
    4921              :         {
    4922      1865546 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4923              :             {
    4924        33136 :               strncpy (nstore, startp, endp - startp);
    4925        33136 :               if (endp == startp)
    4926            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4927        33136 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4928              :                 {
    4929            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4930            0 :                   nstore[endp - startp + 1] = 0;
    4931              :                 }
    4932              :               else
    4933        33136 :                 nstore[endp - startp] = 0;
    4934        33136 :               add_prefix (&exec_prefixes, nstore, 0,
    4935              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4936        33136 :               add_prefix (&include_prefixes, nstore, 0,
    4937              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4938        33136 :               if (*endp == 0)
    4939              :                 break;
    4940        12744 :               endp = startp = endp + 1;
    4941              :             }
    4942              :           else
    4943      1832410 :             endp++;
    4944              :         }
    4945              :     }
    4946              : 
    4947       293981 :   temp = env.get (LIBRARY_PATH_ENV);
    4948       293981 :   if (temp && *cross_compile == '0')
    4949              :     {
    4950        21745 :       const char *startp, *endp;
    4951        21745 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4952              : 
    4953        21745 :       startp = endp = temp;
    4954      3765972 :       while (1)
    4955              :         {
    4956      3765972 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4957              :             {
    4958       156151 :               strncpy (nstore, startp, endp - startp);
    4959       156151 :               if (endp == startp)
    4960            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4961       156151 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4962              :                 {
    4963         1353 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4964         1353 :                   nstore[endp - startp + 1] = 0;
    4965              :                 }
    4966              :               else
    4967       154798 :                 nstore[endp - startp] = 0;
    4968       156151 :               add_prefix (&startfile_prefixes, nstore, NULL,
    4969              :                           PREFIX_PRIORITY_LAST, 0, 1);
    4970       156151 :               if (*endp == 0)
    4971              :                 break;
    4972       134406 :               endp = startp = endp + 1;
    4973              :             }
    4974              :           else
    4975      3609821 :             endp++;
    4976              :         }
    4977              :     }
    4978              : 
    4979              :   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
    4980       293981 :   temp = env.get ("LPATH");
    4981       293981 :   if (temp && *cross_compile == '0')
    4982              :     {
    4983            0 :       const char *startp, *endp;
    4984            0 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4985              : 
    4986            0 :       startp = endp = temp;
    4987            0 :       while (1)
    4988              :         {
    4989            0 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4990              :             {
    4991            0 :               strncpy (nstore, startp, endp - startp);
    4992            0 :               if (endp == startp)
    4993            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4994            0 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4995              :                 {
    4996            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4997            0 :                   nstore[endp - startp + 1] = 0;
    4998              :                 }
    4999              :               else
    5000            0 :                 nstore[endp - startp] = 0;
    5001            0 :               add_prefix (&startfile_prefixes, nstore, NULL,
    5002              :                           PREFIX_PRIORITY_LAST, 0, 1);
    5003            0 :               if (*endp == 0)
    5004              :                 break;
    5005            0 :               endp = startp = endp + 1;
    5006              :             }
    5007              :           else
    5008            0 :             endp++;
    5009              :         }
    5010              :     }
    5011              : 
    5012              :   /* Process the options and store input files and switches in their
    5013              :      vectors.  */
    5014              : 
    5015       293981 :   last_language_n_infiles = -1;
    5016              : 
    5017       293981 :   set_option_handlers (&handlers);
    5018              : 
    5019      5739191 :   for (j = 1; j < decoded_options_count; j++)
    5020              :     {
    5021      5631591 :       switch (decoded_options[j].opt_index)
    5022              :         {
    5023       186381 :         case OPT_S:
    5024       186381 :         case OPT_c:
    5025       186381 :         case OPT_E:
    5026       186381 :           have_c = 1;
    5027       186381 :           break;
    5028              :         }
    5029      5631591 :       if (have_c)
    5030              :         break;
    5031              :     }
    5032              : 
    5033      7022962 :   for (j = 1; j < decoded_options_count; j++)
    5034              :     {
    5035      6729262 :       if (decoded_options[j].opt_index == OPT_SPECIAL_input_file)
    5036              :         {
    5037       318288 :           const char *arg = decoded_options[j].arg;
    5038              : 
    5039              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    5040              :           arg = convert_filename (arg, 0, access (arg, F_OK));
    5041              : #endif
    5042       318288 :           add_infile (arg, spec_lang,
    5043       318288 :                       decoded_options[j].mask == CL_DRIVER);
    5044              : 
    5045       318288 :           continue;
    5046       318288 :         }
    5047              : 
    5048      6410974 :       read_cmdline_option (&global_options, &global_options_set,
    5049              :                            decoded_options + j, UNKNOWN_LOCATION,
    5050              :                            CL_DRIVER, &handlers, global_dc);
    5051              :     }
    5052              : 
    5053              :   /* If the user didn't specify any, default to all configured offload
    5054              :      targets.  */
    5055       293700 :   if (ENABLE_OFFLOADING && offload_targets == NULL)
    5056              :     {
    5057              :       handle_foffload_option (OFFLOAD_TARGETS);
    5058              : #if OFFLOAD_DEFAULTED
    5059              :       offload_targets_default = true;
    5060              : #endif
    5061              :     }
    5062              : 
    5063              :   /* TODO: check if -static -pie works and maybe use it.  */
    5064       293700 :   if (flag_hardened)
    5065              :     {
    5066           91 :       if (!avoid_linker_hardening_p && !static_p)
    5067              :         {
    5068              : #if defined HAVE_LD_PIE && defined LD_PIE_SPEC
    5069           67 :           save_switch (LD_PIE_SPEC, 0, NULL, /*validated=*/true, /*known=*/false);
    5070              : #endif
    5071              :           /* These are passed straight down to collect2 so we have to break
    5072              :              it up like this.  */
    5073           67 :           if (HAVE_LD_NOW_SUPPORT)
    5074              :             {
    5075           67 :               add_infile ("-z", "*");
    5076           67 :               add_infile ("now", "*");
    5077              :             }
    5078           67 :           if (HAVE_LD_RELRO_SUPPORT)
    5079              :             {
    5080           67 :               add_infile ("-z", "*");
    5081           67 :               add_infile ("relro", "*");
    5082              :             }
    5083              :         }
    5084              :       /* We can't use OPT_Whardened yet.  Sigh.  */
    5085              :       else
    5086           24 :         warning_at (UNKNOWN_LOCATION, 0,
    5087              :                     "linker hardening options not enabled by %<-fhardened%> "
    5088              :                     "because other link options were specified on the command "
    5089              :                     "line");
    5090              :     }
    5091              : 
    5092              :   /* Handle -gtoggle as it would later in toplev.cc:process_options to
    5093              :      make the debug-level-gt spec function work as expected.  */
    5094       293700 :   if (flag_gtoggle)
    5095              :     {
    5096            4 :       if (debug_info_level == DINFO_LEVEL_NONE)
    5097            0 :         debug_info_level = DINFO_LEVEL_NORMAL;
    5098              :       else
    5099            4 :         debug_info_level = DINFO_LEVEL_NONE;
    5100              :     }
    5101              : 
    5102       293700 :   if (output_file
    5103       270000 :       && strcmp (output_file, "-") != 0
    5104       269837 :       && strcmp (output_file, HOST_BIT_BUCKET) != 0)
    5105              :     {
    5106              :       int i;
    5107       800803 :       for (i = 0; i < n_infiles; i++)
    5108       257635 :         if ((!infiles[i].language || infiles[i].language[0] != '*')
    5109       559356 :             && canonical_filename_eq (infiles[i].name, output_file))
    5110            1 :           fatal_error (input_location,
    5111              :                        "input file %qs is the same as output file",
    5112              :                        output_file);
    5113              :     }
    5114              : 
    5115       293699 :   if (output_file != NULL && output_file[0] == '\0')
    5116            0 :     fatal_error (input_location, "output filename may not be empty");
    5117              : 
    5118              :   /* -dumpdir and -save-temps=* both specify the location of aux/dump
    5119              :      outputs; the one that appears last prevails.  When compiling
    5120              :      multiple sources, an explicit dumpbase (minus -ext) may be
    5121              :      combined with an explicit or implicit dumpdir, whereas when
    5122              :      linking, a specified or implied link output name (minus
    5123              :      extension) may be combined with a prevailing -save-temps=* or an
    5124              :      otherwise implied dumpdir, but not override a prevailing
    5125              :      -dumpdir.  Primary outputs (e.g., linker output when linking
    5126              :      without -o, or .i, .s or .o outputs when processing multiple
    5127              :      inputs with -E, -S or -c, respectively) are NOT affected by these
    5128              :      -save-temps=/-dump* options, always landing in the current
    5129              :      directory and with the same basename as the input when an output
    5130              :      name is not given, but when they're intermediate outputs, they
    5131              :      are named like other aux outputs, so the options affect their
    5132              :      location and name.
    5133              : 
    5134              :      Here are some examples.  There are several more in the
    5135              :      documentation of -o and -dump*, and some quite exhaustive tests
    5136              :      in gcc.misc-tests/outputs.exp.
    5137              : 
    5138              :      When compiling any number of sources, no -dump* nor
    5139              :      -save-temps=*, all outputs in cwd without prefix:
    5140              : 
    5141              :      # gcc -c b.c -gsplit-dwarf
    5142              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5143              : 
    5144              :      # gcc -c b.c d.c -gsplit-dwarf
    5145              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5146              :      && cc1 [-dumpdir ./] -dumpbase d.c -dumpbase-ext .c # d.o d.dwo
    5147              : 
    5148              :      When compiling and linking, no -dump* nor -save-temps=*, .o
    5149              :      outputs are temporary, aux outputs land in the dir of the output,
    5150              :      prefixed with the basename of the linker output:
    5151              : 
    5152              :      # gcc b.c d.c -o ab -gsplit-dwarf
    5153              :      -> cc1 -dumpdir ab- -dumpbase b.c -dumpbase-ext .c # ab-b.dwo
    5154              :      && cc1 -dumpdir ab- -dumpbase d.c -dumpbase-ext .c # ab-d.dwo
    5155              :      && link ... -o ab
    5156              : 
    5157              :      # gcc b.c d.c [-o a.out] -gsplit-dwarf
    5158              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.dwo
    5159              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.dwo
    5160              :      && link ... [-o a.out]
    5161              : 
    5162              :      When compiling and linking, a prevailing -dumpdir fully overrides
    5163              :      the prefix of aux outputs given by the output name:
    5164              : 
    5165              :      # gcc -dumpdir f b.c d.c -gsplit-dwarf [-o [dir/]whatever]
    5166              :      -> cc1 -dumpdir f -dumpbase b.c -dumpbase-ext .c # fb.dwo
    5167              :      && cc1 -dumpdir f -dumpbase d.c -dumpbase-ext .c # fd.dwo
    5168              :      && link ... [-o whatever]
    5169              : 
    5170              :      When compiling multiple inputs, an explicit -dumpbase is combined
    5171              :      with -dumpdir, affecting aux outputs, but not the .o outputs:
    5172              : 
    5173              :      # gcc -dumpdir f -dumpbase g- b.c d.c -gsplit-dwarf -c
    5174              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # b.o fg-b.dwo
    5175              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # d.o fg-d.dwo
    5176              : 
    5177              :      When compiling and linking with -save-temps, the .o outputs that
    5178              :      would have been temporary become aux outputs, so they get
    5179              :      affected by -dump* flags:
    5180              : 
    5181              :      # gcc -dumpdir f -dumpbase g- -save-temps b.c d.c
    5182              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # fg-b.o
    5183              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # fg-d.o
    5184              :      && link
    5185              : 
    5186              :      If -save-temps=* prevails over -dumpdir, however, the explicit
    5187              :      -dumpdir is discarded, as if it wasn't there.  The basename of
    5188              :      the implicit linker output, a.out or a.exe, becomes a- as the aux
    5189              :      output prefix for all compilations:
    5190              : 
    5191              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c
    5192              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.o
    5193              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.o
    5194              :      && link
    5195              : 
    5196              :      A single -dumpbase, applying to multiple inputs, overrides the
    5197              :      linker output name, implied or explicit, as the aux output prefix:
    5198              : 
    5199              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c
    5200              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5201              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5202              :      && link
    5203              : 
    5204              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c -o dir/h.out
    5205              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5206              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5207              :      && link -o dir/h.out
    5208              : 
    5209              :      Now, if the linker output is NOT overridden as a prefix, but
    5210              :      -save-temps=* overrides implicit or explicit -dumpdir, the
    5211              :      effective dump dir combines the dir selected by the -save-temps=*
    5212              :      option with the basename of the specified or implied link output:
    5213              : 
    5214              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c -o dir/h.out
    5215              :      -> cc1 -dumpdir h- -dumpbase b.c -dumpbase-ext .c # h-b.o
    5216              :      && cc1 -dumpdir h- -dumpbase d.c -dumpbase-ext .c # h-d.o
    5217              :      && link -o dir/h.out
    5218              : 
    5219              :      # gcc [-dumpdir f] -save-temps=obj b.c d.c -o dir/h.out
    5220              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5221              :      && cc1 -dumpdir dir/h- -dumpbase d.c -dumpbase-ext .c # dir/h-d.o
    5222              :      && link -o dir/h.out
    5223              : 
    5224              :      But then again, a single -dumpbase applying to multiple inputs
    5225              :      gets used instead of the linker output basename in the combined
    5226              :      dumpdir:
    5227              : 
    5228              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=obj b.c d.c -o dir/h.out
    5229              :      -> cc1 -dumpdir dir/g- -dumpbase b.c -dumpbase-ext .c # dir/g-b.o
    5230              :      && cc1 -dumpdir dir/g- -dumpbase d.c -dumpbase-ext .c # dir/g-d.o
    5231              :      && link -o dir/h.out
    5232              : 
    5233              :      With a single input being compiled, the output basename does NOT
    5234              :      affect the dumpdir prefix.
    5235              : 
    5236              :      # gcc -save-temps=obj b.c -gsplit-dwarf -c -o dir/b.o
    5237              :      -> cc1 -dumpdir dir/ -dumpbase b.c -dumpbase-ext .c # dir/b.o dir/b.dwo
    5238              : 
    5239              :      but when compiling and linking even a single file, it does:
    5240              : 
    5241              :      # gcc -save-temps=obj b.c -o dir/h.out
    5242              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5243              : 
    5244              :      unless an explicit -dumpdir prevails:
    5245              : 
    5246              :      # gcc -save-temps[=obj] -dumpdir g- b.c -o dir/h.out
    5247              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5248              : 
    5249              :   */
    5250              : 
    5251       293699 :   bool explicit_dumpdir = dumpdir;
    5252              : 
    5253       293647 :   if ((!save_temps_overrides_dumpdir && explicit_dumpdir)
    5254       566798 :       || (output_file && not_actual_file_p (output_file)))
    5255              :     {
    5256              :       /* Do nothing.  */
    5257              :     }
    5258              : 
    5259              :   /* If -save-temps=obj and -o name, create the prefix to use for %b.
    5260              :      Otherwise just make -save-temps=obj the same as -save-temps=cwd.  */
    5261       271647 :   else if (save_temps_flag != SAVE_TEMPS_CWD && output_file != NULL)
    5262              :     {
    5263       255532 :       free (dumpdir);
    5264       255532 :       dumpdir = NULL;
    5265       255532 :       temp = lbasename (output_file);
    5266       255532 :       if (temp != output_file)
    5267       103649 :         dumpdir = xstrndup (output_file,
    5268       103649 :                             strlen (output_file) - strlen (temp));
    5269              :     }
    5270        16115 :   else if (dumpdir)
    5271              :     {
    5272            5 :       free (dumpdir);
    5273            5 :       dumpdir = NULL;
    5274              :     }
    5275              : 
    5276       293699 :   if (save_temps_flag)
    5277          459 :     save_temps_flag = SAVE_TEMPS_DUMP;
    5278              : 
    5279              :   /* If there is any pathname component in an explicit -dumpbase, it
    5280              :      overrides dumpdir entirely, so discard it right away.  Although
    5281              :      the presence of an explicit -dumpdir matters for the driver, it
    5282              :      shouldn't matter for other processes, that get all that's needed
    5283              :      from the -dumpdir and -dumpbase always passed to them.  */
    5284       293699 :   if (dumpdir && dumpbase && lbasename (dumpbase) != dumpbase)
    5285              :     {
    5286        20461 :       free (dumpdir);
    5287        20461 :       dumpdir = NULL;
    5288              :     }
    5289              : 
    5290              :   /* Check that dumpbase_ext matches the end of dumpbase, drop it
    5291              :      otherwise.  */
    5292       293699 :   if (dumpbase_ext && dumpbase && *dumpbase)
    5293              :     {
    5294           20 :       int lendb = strlen (dumpbase);
    5295           20 :       int lendbx = strlen (dumpbase_ext);
    5296              : 
    5297              :       /* -dumpbase-ext must be a suffix proper; discard it if it
    5298              :           matches all of -dumpbase, as that would make for an empty
    5299              :           basename.  */
    5300           20 :       if (lendbx >= lendb
    5301           19 :           || strcmp (dumpbase + lendb - lendbx, dumpbase_ext) != 0)
    5302              :         {
    5303            1 :           free (dumpbase_ext);
    5304            1 :           dumpbase_ext = NULL;
    5305              :         }
    5306              :     }
    5307              : 
    5308              :   /* -dumpbase with multiple sources goes into dumpdir.  With a single
    5309              :      source, it does only if linking and if dumpdir was not explicitly
    5310              :      specified.  */
    5311        21992 :   if (dumpbase && *dumpbase
    5312       314238 :       && (single_input_file_index () == -2
    5313        20255 :           || (!have_c && !explicit_dumpdir)))
    5314              :     {
    5315          296 :       char *prefix;
    5316              : 
    5317          296 :       if (dumpbase_ext)
    5318              :         /* We checked that they match above.  */
    5319            6 :         dumpbase[strlen (dumpbase) - strlen (dumpbase_ext)] = '\0';
    5320              : 
    5321          296 :       if (dumpdir)
    5322           13 :         prefix = concat (dumpdir, dumpbase, "-", NULL);
    5323              :       else
    5324          283 :         prefix = concat (dumpbase, "-", NULL);
    5325              : 
    5326          296 :       free (dumpdir);
    5327          296 :       free (dumpbase);
    5328          296 :       free (dumpbase_ext);
    5329          296 :       dumpbase = dumpbase_ext = NULL;
    5330          296 :       dumpdir = prefix;
    5331          296 :       dumpdir_trailing_dash_added = true;
    5332              :     }
    5333              : 
    5334              :   /* If dumpbase was not brought into dumpdir but we're linking, bring
    5335              :      output_file into dumpdir unless dumpdir was explicitly specified.
    5336              :      The test for !explicit_dumpdir is further below, because we want
    5337              :      to use the obase computation for a ghost outbase, passed to
    5338              :      GCC_COLLECT_OPTIONS.  */
    5339       293403 :   else if (!have_c && (!explicit_dumpdir || (dumpbase && !*dumpbase)))
    5340              :     {
    5341              :       /* If we get here, we know dumpbase was not specified, or it was
    5342              :          specified as an empty string.  If it was anything else, it
    5343              :          would have combined with dumpdir above, because the condition
    5344              :          for dumpbase to be used when present is broader than the
    5345              :          condition that gets us here.  */
    5346       107217 :       gcc_assert (!dumpbase || !*dumpbase);
    5347              : 
    5348       107217 :       const char *obase;
    5349       107217 :       char *tofree = NULL;
    5350       107217 :       if (!output_file || not_actual_file_p (output_file))
    5351              :         obase = "a";
    5352              :       else
    5353              :         {
    5354        94507 :           obase = lbasename (output_file);
    5355        94507 :           size_t blen = strlen (obase), xlen;
    5356              :           /* Drop the suffix if it's dumpbase_ext, if given,
    5357              :              otherwise .exe or the target executable suffix, or if the
    5358              :              output was explicitly named a.out, but not otherwise.  */
    5359        94507 :           if (dumpbase_ext
    5360        94507 :               ? (blen > (xlen = strlen (dumpbase_ext))
    5361          223 :                  && strcmp ((temp = (obase + blen - xlen)),
    5362              :                             dumpbase_ext) == 0)
    5363        94284 :               : ((temp = strrchr (obase + 1, '.'))
    5364        92419 :                  && (xlen = strlen (temp))
    5365       186703 :                  && (strcmp (temp, ".exe") == 0
    5366              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    5367              :                      || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
    5368              : #endif
    5369         9050 :                      || strcmp (obase, "a.out") == 0)))
    5370              :             {
    5371        83618 :               tofree = xstrndup (obase, blen - xlen);
    5372        83618 :               obase = tofree;
    5373              :             }
    5374              :         }
    5375              : 
    5376              :       /* We wish to save this basename to the -dumpdir passed through
    5377              :          GCC_COLLECT_OPTIONS within maybe_run_linker, for e.g. LTO,
    5378              :          but we do NOT wish to add it to e.g. %b, so we keep
    5379              :          outbase_length as zero.  */
    5380       107217 :       gcc_assert (!outbase);
    5381       107217 :       outbase_length = 0;
    5382              : 
    5383              :       /* If we're building [dir1/]foo[.exe] out of a single input
    5384              :          [dir2/]foo.c that shares the same basename, dump to
    5385              :          [dir2/]foo.c.* rather than duplicating the basename into
    5386              :          [dir2/]foo-foo.c.*.  */
    5387       107217 :       int idxin;
    5388       107217 :       if (dumpbase
    5389       107217 :           || ((idxin = single_input_file_index ()) >= 0
    5390        83828 :               && adds_single_suffix_p (lbasename (infiles[idxin].name),
    5391              :                                        obase)))
    5392              :         {
    5393        77254 :           if (obase == tofree)
    5394        75482 :             outbase = tofree;
    5395              :           else
    5396              :             {
    5397         1772 :               outbase = xstrdup (obase);
    5398         1772 :               free (tofree);
    5399              :             }
    5400       107217 :           obase = tofree = NULL;
    5401              :         }
    5402              :       else
    5403              :         {
    5404        29963 :           if (dumpdir)
    5405              :             {
    5406        14830 :               char *p = concat (dumpdir, obase, "-", NULL);
    5407        14830 :               free (dumpdir);
    5408        14830 :               dumpdir = p;
    5409              :             }
    5410              :           else
    5411        15133 :             dumpdir = concat (obase, "-", NULL);
    5412              : 
    5413        29963 :           dumpdir_trailing_dash_added = true;
    5414              : 
    5415        29963 :           free (tofree);
    5416        29963 :           obase = tofree = NULL;
    5417              :         }
    5418              : 
    5419       107217 :       if (!explicit_dumpdir || dumpbase)
    5420              :         {
    5421              :           /* Absent -dumpbase and present -dumpbase-ext have been applied
    5422              :              to the linker output name, so compute fresh defaults for each
    5423              :              compilation.  */
    5424       107217 :           free (dumpbase_ext);
    5425       107217 :           dumpbase_ext = NULL;
    5426              :         }
    5427              :     }
    5428              : 
    5429              :   /* Now, if we're compiling, or if we haven't used the dumpbase
    5430              :      above, then outbase (%B) is derived from dumpbase, if given, or
    5431              :      from the output name, given or implied.  We can't precompute
    5432              :      implied output names, but that's ok, since they're derived from
    5433              :      input names.  Just make sure we skip this if dumpbase is the
    5434              :      empty string: we want to use input names then, so don't set
    5435              :      outbase.  */
    5436       293699 :   if ((dumpbase || have_c)
    5437       187851 :       && !(dumpbase && !*dumpbase))
    5438              :     {
    5439       186398 :       gcc_assert (!outbase);
    5440              : 
    5441       186398 :       if (dumpbase)
    5442              :         {
    5443        20243 :           gcc_assert (single_input_file_index () != -2);
    5444              :           /* We do not want lbasename here; dumpbase with dirnames
    5445              :              overrides dumpdir entirely, even if dumpdir is
    5446              :              specified.  */
    5447        20243 :           if (dumpbase_ext)
    5448              :             /* We've already checked above that the suffix matches.  */
    5449           13 :             outbase = xstrndup (dumpbase,
    5450           13 :                                 strlen (dumpbase) - strlen (dumpbase_ext));
    5451              :           else
    5452        20230 :             outbase = xstrdup (dumpbase);
    5453              :         }
    5454       166155 :       else if (output_file && !not_actual_file_p (output_file))
    5455              :         {
    5456       161262 :           outbase = xstrdup (lbasename (output_file));
    5457       161262 :           char *p = strrchr (outbase + 1, '.');
    5458       161262 :           if (p)
    5459       161262 :             *p = '\0';
    5460              :         }
    5461              : 
    5462       186398 :       if (outbase)
    5463       181505 :         outbase_length = strlen (outbase);
    5464              :     }
    5465              : 
    5466              :   /* If there is any pathname component in an explicit -dumpbase, do
    5467              :      not use dumpdir, but retain it to pass it on to the compiler.  */
    5468       293699 :   if (dumpdir)
    5469       119152 :     dumpdir_length = strlen (dumpdir);
    5470              :   else
    5471       174547 :     dumpdir_length = 0;
    5472              : 
    5473              :   /* Check that dumpbase_ext, if still present, still matches the end
    5474              :      of dumpbase, if present, and drop it otherwise.  We only retained
    5475              :      it above when dumpbase was absent to maybe use it to drop the
    5476              :      extension from output_name before combining it with dumpdir.  We
    5477              :      won't deal with -dumpbase-ext when -dumpbase is not explicitly
    5478              :      given, even if just to activate backward-compatible dumpbase:
    5479              :      dropping it on the floor is correct, expected and documented
    5480              :      behavior.  Attempting to deal with a -dumpbase-ext that might
    5481              :      match the end of some input filename, or of the combination of
    5482              :      the output basename with the suffix of the input filename,
    5483              :      possible with an intermediate .gk extension for -fcompare-debug,
    5484              :      is just calling for trouble.  */
    5485       293699 :   if (dumpbase_ext)
    5486              :     {
    5487           22 :       if (!dumpbase || !*dumpbase)
    5488              :         {
    5489            9 :           free (dumpbase_ext);
    5490            9 :           dumpbase_ext = NULL;
    5491              :         }
    5492              :       else
    5493           13 :         gcc_assert (strcmp (dumpbase + strlen (dumpbase)
    5494              :                             - strlen (dumpbase_ext), dumpbase_ext) == 0);
    5495              :     }
    5496              : 
    5497       293699 :   if (save_temps_flag && use_pipes)
    5498              :     {
    5499              :       /* -save-temps overrides -pipe, so that temp files are produced */
    5500            0 :       if (save_temps_flag)
    5501            0 :         warning (0, "%<-pipe%> ignored because %<-save-temps%> specified");
    5502            0 :       use_pipes = 0;
    5503              :     }
    5504              : 
    5505       293699 :   if (!compare_debug)
    5506              :     {
    5507       293080 :       const char *gcd = env.get ("GCC_COMPARE_DEBUG");
    5508              : 
    5509       293080 :       if (gcd && gcd[0] == '-')
    5510              :         {
    5511            0 :           compare_debug = 2;
    5512            0 :           compare_debug_opt = gcd;
    5513              :         }
    5514            0 :       else if (gcd && *gcd && strcmp (gcd, "0"))
    5515              :         {
    5516            0 :           compare_debug = 3;
    5517            0 :           compare_debug_opt = "-gtoggle";
    5518              :         }
    5519              :     }
    5520          619 :   else if (compare_debug < 0)
    5521              :     {
    5522            0 :       compare_debug = 0;
    5523            0 :       gcc_assert (!compare_debug_opt);
    5524              :     }
    5525              : 
    5526              :   /* Set up the search paths.  We add directories that we expect to
    5527              :      contain GNU Toolchain components before directories specified by
    5528              :      the machine description so that we will find GNU components (like
    5529              :      the GNU assembler) before those of the host system.  */
    5530              : 
    5531              :   /* If we don't know where the toolchain has been installed, use the
    5532              :      configured-in locations.  */
    5533       293699 :   if (!gcc_exec_prefix)
    5534              :     {
    5535              : #ifndef OS2
    5536            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
    5537              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5538            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
    5539              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5540            0 :       add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
    5541              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5542              : #endif
    5543            0 :       add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
    5544              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5545              :     }
    5546              : 
    5547       293699 :   gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
    5548       293699 :   tooldir_prefix2 = concat (tooldir_base_prefix, spec_machine,
    5549              :                             dir_separator_str, NULL);
    5550              : 
    5551              :   /* Look for tools relative to the location from which the driver is
    5552              :      running, or, if that is not available, the configured prefix.  */
    5553       293699 :   tooldir_prefix
    5554       587398 :     = concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    5555              :               spec_host_machine, dir_separator_str, spec_version,
    5556              :               accel_dir_suffix, dir_separator_str, tooldir_prefix2, NULL);
    5557       293699 :   free (tooldir_prefix2);
    5558              : 
    5559       293699 :   add_prefix (&exec_prefixes,
    5560       293699 :               concat (tooldir_prefix, "bin", dir_separator_str, NULL),
    5561              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 0);
    5562       293699 :   add_prefix (&startfile_prefixes,
    5563       293699 :               concat (tooldir_prefix, "lib", dir_separator_str, NULL),
    5564              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
    5565       293699 :   free (tooldir_prefix);
    5566              : 
    5567              : #if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
    5568              :   /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
    5569              :      then consider it to relocate with the rest of the GCC installation
    5570              :      if GCC_EXEC_PREFIX is set.
    5571              :      ``make_relative_prefix'' is not compiled for VMS, so don't call it.  */
    5572              :   if (target_system_root && !target_system_root_changed && gcc_exec_prefix)
    5573              :     {
    5574              :       char *tmp_prefix = get_relative_prefix (decoded_options[0].arg,
    5575              :                                               standard_bindir_prefix,
    5576              :                                               target_system_root);
    5577              :       if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
    5578              :         {
    5579              :           target_system_root = tmp_prefix;
    5580              :           target_system_root_changed = 1;
    5581              :         }
    5582              :     }
    5583              : #endif
    5584              : 
    5585              :   /* More prefixes are enabled in main, after we read the specs file
    5586              :      and determine whether this is cross-compilation or not.  */
    5587              : 
    5588       293699 :   if (n_infiles != 0 && n_infiles == last_language_n_infiles && spec_lang != 0)
    5589            0 :     warning (0, "%<-x %s%> after last input file has no effect", spec_lang);
    5590              : 
    5591              :   /* Synthesize -fcompare-debug flag from the GCC_COMPARE_DEBUG
    5592              :      environment variable.  */
    5593       293699 :   if (compare_debug == 2 || compare_debug == 3)
    5594              :     {
    5595            0 :       const char *opt = concat ("-fcompare-debug=", compare_debug_opt, NULL);
    5596            0 :       save_switch (opt, 0, NULL, false, true);
    5597            0 :       compare_debug = 1;
    5598              :     }
    5599              : 
    5600              :   /* Ensure we only invoke each subprocess once.  */
    5601       293699 :   if (n_infiles == 0
    5602         7963 :       && (print_subprocess_help || print_help_list || print_version))
    5603              :     {
    5604              :       /* Create a dummy input file, so that we can pass
    5605              :          the help option on to the various sub-processes.  */
    5606           78 :       add_infile ("help-dummy", "c");
    5607              :     }
    5608              : 
    5609              :   /* Decide if undefined variable references are allowed in specs.  */
    5610              : 
    5611              :   /* -v alone is safe. --version and --help alone or together are safe.  Note
    5612              :      that -v would make them unsafe, as they'd then be run for subprocesses as
    5613              :      well, the location of which might depend on variables possibly coming
    5614              :      from self-specs.  Note also that the command name is counted in
    5615              :      decoded_options_count.  */
    5616              : 
    5617       293699 :   unsigned help_version_count = 0;
    5618              : 
    5619       293699 :   if (print_version)
    5620           78 :     help_version_count++;
    5621              : 
    5622       293699 :   if (print_help_list)
    5623            4 :     help_version_count++;
    5624              : 
    5625       587398 :   spec_undefvar_allowed =
    5626         1547 :     ((verbose_flag && decoded_options_count == 2)
    5627       295207 :      || help_version_count == decoded_options_count - 1);
    5628              : 
    5629       293699 :   alloc_switch ();
    5630       293699 :   switches[n_switches].part1 = 0;
    5631       293699 :   alloc_infile ();
    5632       293699 :   infiles[n_infiles].name = 0;
    5633       293699 : }
    5634              : 
    5635              : /* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
    5636              :    and place that in the environment.  */
    5637              : 
    5638              : static void
    5639       814715 : set_collect_gcc_options (void)
    5640              : {
    5641       814715 :   int i;
    5642       814715 :   int first_time;
    5643              : 
    5644              :   /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
    5645              :      the compiler.  */
    5646       814715 :   obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
    5647              :                 sizeof ("COLLECT_GCC_OPTIONS=") - 1);
    5648              : 
    5649       814715 :   first_time = true;
    5650     19705342 :   for (i = 0; (int) i < n_switches; i++)
    5651              :     {
    5652     18890627 :       const char *const *args;
    5653     18890627 :       const char *p, *q;
    5654     18890627 :       if (!first_time)
    5655     18075912 :         obstack_grow (&collect_obstack, " ", 1);
    5656              : 
    5657     18890627 :       first_time = false;
    5658              : 
    5659              :       /* Ignore elided switches.  */
    5660     19011084 :       if ((switches[i].live_cond
    5661     18890627 :            & (SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC))
    5662              :           == SWITCH_IGNORE)
    5663       120457 :         continue;
    5664              : 
    5665     18770170 :       obstack_grow (&collect_obstack, "'-", 2);
    5666     18770170 :       q = switches[i].part1;
    5667     18770170 :       while ((p = strchr (q, '\'')))
    5668              :         {
    5669            0 :           obstack_grow (&collect_obstack, q, p - q);
    5670            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5671            0 :           q = ++p;
    5672              :         }
    5673     18770170 :       obstack_grow (&collect_obstack, q, strlen (q));
    5674     18770170 :       obstack_grow (&collect_obstack, "'", 1);
    5675              : 
    5676     22910548 :       for (args = switches[i].args; args && *args; args++)
    5677              :         {
    5678      4140378 :           obstack_grow (&collect_obstack, " '", 2);
    5679      4140378 :           q = *args;
    5680      4140378 :           while ((p = strchr (q, '\'')))
    5681              :             {
    5682            0 :               obstack_grow (&collect_obstack, q, p - q);
    5683            0 :               obstack_grow (&collect_obstack, "'\\''", 4);
    5684            0 :               q = ++p;
    5685              :             }
    5686      4140378 :           obstack_grow (&collect_obstack, q, strlen (q));
    5687      4140378 :           obstack_grow (&collect_obstack, "'", 1);
    5688              :         }
    5689              :     }
    5690              : 
    5691       814715 :   if (dumpdir)
    5692              :     {
    5693       580302 :       if (!first_time)
    5694       580302 :         obstack_grow (&collect_obstack, " ", 1);
    5695       580302 :       first_time = false;
    5696              : 
    5697       580302 :       obstack_grow (&collect_obstack, "'-dumpdir' '", 12);
    5698       580302 :       const char *p, *q;
    5699              : 
    5700       580302 :       q = dumpdir;
    5701       580302 :       while ((p = strchr (q, '\'')))
    5702              :         {
    5703            0 :           obstack_grow (&collect_obstack, q, p - q);
    5704            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5705            0 :           q = ++p;
    5706              :         }
    5707       580302 :       obstack_grow (&collect_obstack, q, strlen (q));
    5708              : 
    5709       580302 :       obstack_grow (&collect_obstack, "'", 1);
    5710              :     }
    5711              : 
    5712       814715 :   obstack_grow (&collect_obstack, "\0", 1);
    5713       814715 :   xputenv (XOBFINISH (&collect_obstack, char *));
    5714       814715 : }
    5715              : 
    5716              : /* Process a spec string, accumulating and running commands.  */
    5717              : 
    5718              : /* These variables describe the input file name.
    5719              :    input_file_number is the index on outfiles of this file,
    5720              :    so that the output file name can be stored for later use by %o.
    5721              :    input_basename is the start of the part of the input file
    5722              :    sans all directory names, and basename_length is the number
    5723              :    of characters starting there excluding the suffix .c or whatever.  */
    5724              : 
    5725              : static const char *gcc_input_filename;
    5726              : static int input_file_number;
    5727              : size_t input_filename_length;
    5728              : static int basename_length;
    5729              : static int suffixed_basename_length;
    5730              : static const char *input_basename;
    5731              : static const char *input_suffix;
    5732              : #ifndef HOST_LACKS_INODE_NUMBERS
    5733              : static struct stat input_stat;
    5734              : #endif
    5735              : static int input_stat_set;
    5736              : 
    5737              : /* The compiler used to process the current input file.  */
    5738              : static struct compiler *input_file_compiler;
    5739              : 
    5740              : /* These are variables used within do_spec and do_spec_1.  */
    5741              : 
    5742              : /* Nonzero if an arg has been started and not yet terminated
    5743              :    (with space, tab or newline).  */
    5744              : static int arg_going;
    5745              : 
    5746              : /* Nonzero means %d or %g has been seen; the next arg to be terminated
    5747              :    is a temporary file name.  */
    5748              : static int delete_this_arg;
    5749              : 
    5750              : /* Nonzero means %w has been seen; the next arg to be terminated
    5751              :    is the output file name of this compilation.  */
    5752              : static int this_is_output_file;
    5753              : 
    5754              : /* Nonzero means %s has been seen; the next arg to be terminated
    5755              :    is the name of a library file and we should try the standard
    5756              :    search dirs for it.  */
    5757              : static int this_is_library_file;
    5758              : 
    5759              : /* Nonzero means %T has been seen; the next arg to be terminated
    5760              :    is the name of a linker script and we should try all of the
    5761              :    standard search dirs for it.  If it is found insert a --script
    5762              :    command line switch and then substitute the full path in place,
    5763              :    otherwise generate an error message.  */
    5764              : static int this_is_linker_script;
    5765              : 
    5766              : /* Nonzero means that the input of this command is coming from a pipe.  */
    5767              : static int input_from_pipe;
    5768              : 
    5769              : /* Nonnull means substitute this for any suffix when outputting a switches
    5770              :    arguments.  */
    5771              : static const char *suffix_subst;
    5772              : 
    5773              : /* If there is an argument being accumulated, terminate it and store it.  */
    5774              : 
    5775              : static void
    5776     79742038 : end_going_arg (void)
    5777              : {
    5778     79742038 :   if (arg_going)
    5779              :     {
    5780     18793549 :       const char *string;
    5781              : 
    5782     18793549 :       obstack_1grow (&obstack, 0);
    5783     18793549 :       string = XOBFINISH (&obstack, const char *);
    5784     18793549 :       if (this_is_library_file)
    5785       536908 :         string = find_file (string);
    5786     18793549 :       if (this_is_linker_script)
    5787              :         {
    5788            0 :           char * full_script_path = find_a_file (&startfile_prefixes, string, R_OK, true);
    5789              : 
    5790            0 :           if (full_script_path == NULL)
    5791              :             {
    5792            0 :               error ("unable to locate default linker script %qs in the library search paths", string);
    5793              :               /* Script was not found on search path.  */
    5794            0 :               return;
    5795              :             }
    5796            0 :           store_arg ("--script", false, false);
    5797            0 :           string = full_script_path;
    5798              :         }
    5799     18793549 :       store_arg (string, delete_this_arg, this_is_output_file);
    5800     18793549 :       if (this_is_output_file)
    5801        99388 :         outfiles[input_file_number] = string;
    5802     18793549 :       arg_going = 0;
    5803              :     }
    5804              : }
    5805              : 
    5806              : 
    5807              : /* Parse the WRAPPER string which is a comma separated list of the command line
    5808              :    and insert them into the beginning of argbuf.  */
    5809              : 
    5810              : static void
    5811            0 : insert_wrapper (const char *wrapper)
    5812              : {
    5813            0 :   int n = 0;
    5814            0 :   int i;
    5815            0 :   char *buf = xstrdup (wrapper);
    5816            0 :   char *p = buf;
    5817            0 :   unsigned int old_length = argbuf.length ();
    5818              : 
    5819            0 :   do
    5820              :     {
    5821            0 :       n++;
    5822            0 :       while (*p == ',')
    5823            0 :         p++;
    5824              :     }
    5825            0 :   while ((p = strchr (p, ',')) != NULL);
    5826              : 
    5827            0 :   argbuf.safe_grow (old_length + n, true);
    5828            0 :   memmove (argbuf.address () + n,
    5829            0 :            argbuf.address (),
    5830            0 :            old_length * sizeof (const_char_p));
    5831              : 
    5832            0 :   i = 0;
    5833            0 :   p = buf;
    5834              :   do
    5835              :     {
    5836            0 :       while (*p == ',')
    5837              :         {
    5838            0 :           *p = 0;
    5839            0 :           p++;
    5840              :         }
    5841            0 :       argbuf[i] = p;
    5842            0 :       i++;
    5843              :     }
    5844            0 :   while ((p = strchr (p, ',')) != NULL);
    5845            0 :   gcc_assert (i == n);
    5846            0 : }
    5847              : 
    5848              : /* Process the spec SPEC and run the commands specified therein.
    5849              :    Returns 0 if the spec is successfully processed; -1 if failed.  */
    5850              : 
    5851              : int
    5852       559799 : do_spec (const char *spec)
    5853              : {
    5854       559799 :   int value;
    5855              : 
    5856       559799 :   value = do_spec_2 (spec, NULL);
    5857              : 
    5858              :   /* Force out any unfinished command.
    5859              :      If -pipe, this forces out the last command if it ended in `|'.  */
    5860       559799 :   if (value == 0)
    5861              :     {
    5862       554319 :       if (argbuf.length () > 0
    5863       832510 :           && !strcmp (argbuf.last (), "|"))
    5864            0 :         argbuf.pop ();
    5865              : 
    5866       554319 :       set_collect_gcc_options ();
    5867              : 
    5868       554319 :       if (argbuf.length () > 0)
    5869       278191 :         value = execute ();
    5870              :     }
    5871              : 
    5872       559799 :   return value;
    5873              : }
    5874              : 
    5875              : /* Process the spec SPEC, with SOFT_MATCHED_PART designating the current value
    5876              :    of a matched * pattern which may be re-injected by way of %*.  */
    5877              : 
    5878              : static int
    5879      5262908 : do_spec_2 (const char *spec, const char *soft_matched_part)
    5880              : {
    5881      5262908 :   int result;
    5882              : 
    5883      5262908 :   clear_args ();
    5884      5262908 :   arg_going = 0;
    5885      5262908 :   delete_this_arg = 0;
    5886      5262908 :   this_is_output_file = 0;
    5887      5262908 :   this_is_library_file = 0;
    5888      5262908 :   this_is_linker_script = 0;
    5889      5262908 :   input_from_pipe = 0;
    5890      5262908 :   suffix_subst = NULL;
    5891              : 
    5892      5262908 :   result = do_spec_1 (spec, 0, soft_matched_part);
    5893              : 
    5894      5262908 :   end_going_arg ();
    5895              : 
    5896      5262908 :   return result;
    5897              : }
    5898              : 
    5899              : /* Process the given spec string and add any new options to the end
    5900              :    of the switches/n_switches array.  */
    5901              : 
    5902              : static void
    5903      2938300 : do_option_spec (const char *name, const char *spec)
    5904              : {
    5905      2938300 :   unsigned int i, value_count, value_len;
    5906      2938300 :   const char *p, *q, *value;
    5907      2938300 :   char *tmp_spec, *tmp_spec_p;
    5908              : 
    5909      2938300 :   if (configure_default_options[0].name == NULL)
    5910              :     return;
    5911              : 
    5912      7933410 :   for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
    5913      5582770 :     if (strcmp (configure_default_options[i].name, name) == 0)
    5914              :       break;
    5915      2938300 :   if (i == ARRAY_SIZE (configure_default_options))
    5916              :     return;
    5917              : 
    5918       587660 :   value = configure_default_options[i].value;
    5919       587660 :   value_len = strlen (value);
    5920              : 
    5921              :   /* Compute the size of the final spec.  */
    5922       587660 :   value_count = 0;
    5923       587660 :   p = spec;
    5924      1175320 :   while ((p = strstr (p, "%(VALUE)")) != NULL)
    5925              :     {
    5926       587660 :       p ++;
    5927       587660 :       value_count ++;
    5928              :     }
    5929              : 
    5930              :   /* Replace each %(VALUE) by the specified value.  */
    5931       587660 :   tmp_spec = (char *) alloca (strlen (spec) + 1
    5932              :                      + value_count * (value_len - strlen ("%(VALUE)")));
    5933       587660 :   tmp_spec_p = tmp_spec;
    5934       587660 :   q = spec;
    5935      1175320 :   while ((p = strstr (q, "%(VALUE)")) != NULL)
    5936              :     {
    5937       587660 :       memcpy (tmp_spec_p, q, p - q);
    5938       587660 :       tmp_spec_p = tmp_spec_p + (p - q);
    5939       587660 :       memcpy (tmp_spec_p, value, value_len);
    5940       587660 :       tmp_spec_p += value_len;
    5941       587660 :       q = p + strlen ("%(VALUE)");
    5942              :     }
    5943       587660 :   strcpy (tmp_spec_p, q);
    5944              : 
    5945       587660 :   do_self_spec (tmp_spec);
    5946              : }
    5947              : 
    5948              : /* Process the given spec string and add any new options to the end
    5949              :    of the switches/n_switches array.  */
    5950              : 
    5951              : static void
    5952      2644790 : do_self_spec (const char *spec)
    5953              : {
    5954      2644790 :   int i;
    5955              : 
    5956      2644790 :   do_spec_2 (spec, NULL);
    5957      2644790 :   do_spec_1 (" ", 0, NULL);
    5958              : 
    5959              :   /* Mark %<S switches processed by do_self_spec to be ignored permanently.
    5960              :      do_self_specs adds the replacements to switches array, so it shouldn't
    5961              :      be processed afterwards.  */
    5962     64193301 :   for (i = 0; i < n_switches; i++)
    5963     58903721 :     if ((switches[i].live_cond & SWITCH_IGNORE))
    5964          667 :       switches[i].live_cond |= SWITCH_IGNORE_PERMANENTLY;
    5965              : 
    5966      2644790 :   if (argbuf.length () > 0)
    5967              :     {
    5968       558002 :       const char **argbuf_copy;
    5969       558002 :       struct cl_decoded_option *decoded_options;
    5970       558002 :       struct cl_option_handlers handlers;
    5971       558002 :       unsigned int decoded_options_count;
    5972       558002 :       unsigned int j;
    5973              : 
    5974              :       /* Create a copy of argbuf with a dummy argv[0] entry for
    5975              :          decode_cmdline_options_to_array.  */
    5976       558002 :       argbuf_copy = XNEWVEC (const char *,
    5977              :                              argbuf.length () + 1);
    5978       558002 :       argbuf_copy[0] = "";
    5979       558002 :       memcpy (argbuf_copy + 1, argbuf.address (),
    5980       558002 :               argbuf.length () * sizeof (const char *));
    5981              : 
    5982      1116004 :       decode_cmdline_options_to_array (argbuf.length () + 1,
    5983              :                                        argbuf_copy,
    5984              :                                        CL_DRIVER, &decoded_options,
    5985              :                                        &decoded_options_count);
    5986       558002 :       free (argbuf_copy);
    5987              : 
    5988       558002 :       set_option_handlers (&handlers);
    5989              : 
    5990      1118480 :       for (j = 1; j < decoded_options_count; j++)
    5991              :         {
    5992       560478 :           switch (decoded_options[j].opt_index)
    5993              :             {
    5994            0 :             case OPT_SPECIAL_input_file:
    5995              :               /* Specs should only generate options, not input
    5996              :                  files.  */
    5997            0 :               if (strcmp (decoded_options[j].arg, "-") != 0)
    5998            0 :                 fatal_error (input_location,
    5999              :                              "switch %qs does not start with %<-%>",
    6000              :                              decoded_options[j].arg);
    6001              :               else
    6002            0 :                 fatal_error (input_location,
    6003              :                              "spec-generated switch is just %<-%>");
    6004         1238 :               break;
    6005              : 
    6006         1238 :             case OPT_fcompare_debug_second:
    6007         1238 :             case OPT_fcompare_debug:
    6008         1238 :             case OPT_fcompare_debug_:
    6009         1238 :             case OPT_o:
    6010              :               /* Avoid duplicate processing of some options from
    6011              :                  compare-debug specs; just save them here.  */
    6012         1238 :               save_switch (decoded_options[j].canonical_option[0],
    6013         1238 :                            (decoded_options[j].canonical_option_num_elements
    6014              :                             - 1),
    6015         1238 :                            &decoded_options[j].canonical_option[1], false, true);
    6016         1238 :               break;
    6017              : 
    6018       559240 :             default:
    6019       559240 :               read_cmdline_option (&global_options, &global_options_set,
    6020              :                                    decoded_options + j, UNKNOWN_LOCATION,
    6021              :                                    CL_DRIVER, &handlers, global_dc);
    6022       559240 :               break;
    6023              :             }
    6024              :         }
    6025              : 
    6026       558002 :       free (decoded_options);
    6027              : 
    6028       558002 :       alloc_switch ();
    6029       558002 :       switches[n_switches].part1 = 0;
    6030              :     }
    6031      2644790 : }
    6032              : 
    6033              : /* Callback for processing %D and %I specs.  */
    6034              : 
    6035              : struct spec_path {
    6036              :   const char *option;
    6037              :   const char *append;
    6038              :   size_t append_len;
    6039              :   bool omit_relative;
    6040              :   bool separate_options;
    6041              :   bool realpaths;
    6042              : 
    6043              :   void *operator() (char *path);
    6044              : };
    6045              : 
    6046              : void *
    6047      3320152 : spec_path::operator() (char *path)
    6048              : {
    6049      3320152 :   size_t len = 0;
    6050      3320152 :   char save = 0;
    6051              : 
    6052              :   /* The path must exist; we want to resolve it to the realpath so that this
    6053              :      can be embedded as a runpath.  */
    6054      3320152 :   if (realpaths)
    6055            0 :      path = lrealpath (path);
    6056              : 
    6057              :   /* However, if we failed to resolve it - perhaps because there was a bogus
    6058              :      -B option on the command line, then punt on this entry.  */
    6059      3320152 :   if (!path)
    6060              :     return NULL;
    6061              : 
    6062      3320152 :   if (omit_relative && !IS_ABSOLUTE_PATH (path))
    6063              :     return NULL;
    6064              : 
    6065      3320152 :   if (append_len != 0)
    6066              :     {
    6067      1379016 :       len = strlen (path);
    6068      1379016 :       memcpy (path + len, append, append_len + 1);
    6069              :     }
    6070              : 
    6071      3320152 :   if (!is_directory (path))
    6072              :     return NULL;
    6073              : 
    6074      1246201 :   do_spec_1 (option, 1, NULL);
    6075      1246201 :   if (separate_options)
    6076       444752 :     do_spec_1 (" ", 0, NULL);
    6077              : 
    6078      1246201 :   if (append_len == 0)
    6079              :     {
    6080       801449 :       len = strlen (path);
    6081       801449 :       save = path[len - 1];
    6082       801449 :       if (IS_DIR_SEPARATOR (path[len - 1]))
    6083       801449 :         path[len - 1] = '\0';
    6084              :     }
    6085              : 
    6086      1246201 :   do_spec_1 (path, 1, NULL);
    6087      1246201 :   do_spec_1 (" ", 0, NULL);
    6088              : 
    6089              :   /* Must not damage the original path.  */
    6090      1246201 :   if (append_len == 0)
    6091       801449 :     path[len - 1] = save;
    6092              : 
    6093              :   return NULL;
    6094              : }
    6095              : 
    6096              : /* True if we should compile INFILE. */
    6097              : 
    6098              : static bool
    6099        43453 : compile_input_file_p (struct infile *infile)
    6100              : {
    6101        26051 :   if ((!infile->language) || (infile->language[0] != '*'))
    6102        38850 :     if (infile->incompiler == input_file_compiler)
    6103            0 :       return true;
    6104              :   return false;
    6105              : }
    6106              : 
    6107              : /* Process each member of VEC as a spec.  */
    6108              : 
    6109              : static void
    6110       462895 : do_specs_vec (vec<char_p> vec)
    6111              : {
    6112       463013 :   for (char *opt : vec)
    6113              :     {
    6114           70 :       do_spec_1 (opt, 1, NULL);
    6115              :       /* Make each accumulated option a separate argument.  */
    6116           70 :       do_spec_1 (" ", 0, NULL);
    6117              :     }
    6118       462895 : }
    6119              : 
    6120              : /* Add options passed via -Xassembler or -Wa to COLLECT_AS_OPTIONS.  */
    6121              : 
    6122              : static void
    6123       293698 : putenv_COLLECT_AS_OPTIONS (vec<char_p> vec)
    6124              : {
    6125       293698 :   if (vec.is_empty ())
    6126       293698 :      return;
    6127              : 
    6128          103 :   obstack_init (&collect_obstack);
    6129          103 :   obstack_grow (&collect_obstack, "COLLECT_AS_OPTIONS=",
    6130              :                 strlen ("COLLECT_AS_OPTIONS="));
    6131              : 
    6132          103 :   char *opt;
    6133          103 :   unsigned ix;
    6134              : 
    6135          298 :   FOR_EACH_VEC_ELT (vec, ix, opt)
    6136              :     {
    6137          195 :       obstack_1grow (&collect_obstack, '\'');
    6138          195 :       obstack_grow (&collect_obstack, opt, strlen (opt));
    6139          195 :       obstack_1grow (&collect_obstack, '\'');
    6140          195 :       if (ix < vec.length () - 1)
    6141           92 :         obstack_1grow(&collect_obstack, ' ');
    6142              :     }
    6143              : 
    6144          103 :   obstack_1grow (&collect_obstack, '\0');
    6145          103 :   xputenv (XOBFINISH (&collect_obstack, char *));
    6146              : }
    6147              : 
    6148              : /* Process the sub-spec SPEC as a portion of a larger spec.
    6149              :    This is like processing a whole spec except that we do
    6150              :    not initialize at the beginning and we do not supply a
    6151              :    newline by default at the end.
    6152              :    INSWITCH nonzero means don't process %-sequences in SPEC;
    6153              :    in this case, % is treated as an ordinary character.
    6154              :    This is used while substituting switches.
    6155              :    INSWITCH nonzero also causes SPC not to terminate an argument.
    6156              : 
    6157              :    Value is zero unless a line was finished
    6158              :    and the command on that line reported an error.  */
    6159              : 
    6160              : static int
    6161     52195106 : do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
    6162              : {
    6163     52195106 :   const char *p = spec;
    6164     52195106 :   int c;
    6165     52195106 :   int i;
    6166     52195106 :   int value;
    6167              : 
    6168              :   /* If it's an empty string argument to a switch, keep it as is.  */
    6169     52195106 :   if (inswitch && !*p)
    6170            1 :     arg_going = 1;
    6171              : 
    6172    527768588 :   while ((c = *p++))
    6173              :     /* If substituting a switch, treat all chars like letters.
    6174              :        Otherwise, NL, SPC, TAB and % are special.  */
    6175    475619723 :     switch (inswitch ? 'a' : c)
    6176              :       {
    6177       260396 :       case '\n':
    6178       260396 :         end_going_arg ();
    6179              : 
    6180       260396 :         if (argbuf.length () > 0
    6181       520792 :             && !strcmp (argbuf.last (), "|"))
    6182              :           {
    6183              :             /* A `|' before the newline means use a pipe here,
    6184              :                but only if -pipe was specified.
    6185              :                Otherwise, execute now and don't pass the `|' as an arg.  */
    6186       164617 :             if (use_pipes)
    6187              :               {
    6188            0 :                 input_from_pipe = 1;
    6189            0 :                 break;
    6190              :               }
    6191              :             else
    6192       164617 :               argbuf.pop ();
    6193              :           }
    6194              : 
    6195       260396 :         set_collect_gcc_options ();
    6196              : 
    6197       260396 :         if (argbuf.length () > 0)
    6198              :           {
    6199       260396 :             value = execute ();
    6200       260396 :             if (value)
    6201              :               return value;
    6202              :           }
    6203              :         /* Reinitialize for a new command, and for a new argument.  */
    6204       254916 :         clear_args ();
    6205       254916 :         arg_going = 0;
    6206       254916 :         delete_this_arg = 0;
    6207       254916 :         this_is_output_file = 0;
    6208       254916 :         this_is_library_file = 0;
    6209       254916 :         this_is_linker_script = 0;
    6210       254916 :         input_from_pipe = 0;
    6211       254916 :         break;
    6212              : 
    6213       164617 :       case '|':
    6214       164617 :         end_going_arg ();
    6215              : 
    6216              :         /* Use pipe */
    6217       164617 :         obstack_1grow (&obstack, c);
    6218       164617 :         arg_going = 1;
    6219       164617 :         break;
    6220              : 
    6221     69409874 :       case '\t':
    6222     69409874 :       case ' ':
    6223     69409874 :         end_going_arg ();
    6224              : 
    6225              :         /* Reinitialize for a new argument.  */
    6226     69409874 :         delete_this_arg = 0;
    6227     69409874 :         this_is_output_file = 0;
    6228     69409874 :         this_is_library_file = 0;
    6229     69409874 :         this_is_linker_script = 0;
    6230     69409874 :         break;
    6231              : 
    6232     48864632 :       case '%':
    6233     48864632 :         switch (c = *p++)
    6234              :           {
    6235            0 :           case 0:
    6236            0 :             fatal_error (input_location, "spec %qs invalid", spec);
    6237              : 
    6238         3606 :           case 'b':
    6239              :             /* Don't use %b in the linker command.  */
    6240         3606 :             gcc_assert (suffixed_basename_length);
    6241         3606 :             if (!this_is_output_file && dumpdir_length)
    6242          689 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6243         3606 :             if (this_is_output_file || !outbase_length)
    6244         3264 :               obstack_grow (&obstack, input_basename, basename_length);
    6245              :             else
    6246          342 :               obstack_grow (&obstack, outbase, outbase_length);
    6247         3606 :             if (compare_debug < 0)
    6248            6 :               obstack_grow (&obstack, ".gk", 3);
    6249         3606 :             arg_going = 1;
    6250         3606 :             break;
    6251              : 
    6252           10 :           case 'B':
    6253              :             /* Don't use %B in the linker command.  */
    6254           10 :             gcc_assert (suffixed_basename_length);
    6255           10 :             if (!this_is_output_file && dumpdir_length)
    6256            0 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6257           10 :             if (this_is_output_file || !outbase_length)
    6258            5 :               obstack_grow (&obstack, input_basename, basename_length);
    6259              :             else
    6260            5 :               obstack_grow (&obstack, outbase, outbase_length);
    6261           10 :             if (compare_debug < 0)
    6262            3 :               obstack_grow (&obstack, ".gk", 3);
    6263           10 :             obstack_grow (&obstack, input_basename + basename_length,
    6264              :                           suffixed_basename_length - basename_length);
    6265              : 
    6266           10 :             arg_going = 1;
    6267           10 :             break;
    6268              : 
    6269        96867 :           case 'd':
    6270        96867 :             delete_this_arg = 2;
    6271        96867 :             break;
    6272              : 
    6273              :           /* Dump out the directories specified with LIBRARY_PATH,
    6274              :              followed by the absolute directories
    6275              :              that we search for startfiles.  */
    6276       104821 :           case 'D':
    6277       104821 :             {
    6278       104821 :               struct spec_path info;
    6279              : 
    6280       104821 :               info.option = "-L";
    6281       104821 :               info.append_len = 0;
    6282              : #ifdef RELATIVE_PREFIX_NOT_LINKDIR
    6283              :               /* Used on systems which record the specified -L dirs
    6284              :                  and use them to search for dynamic linking.
    6285              :                  Relative directories always come from -B,
    6286              :                  and it is better not to use them for searching
    6287              :                  at run time.  In particular, stage1 loses.  */
    6288              :               info.omit_relative = true;
    6289              : #else
    6290       104821 :               info.omit_relative = false;
    6291              : #endif
    6292       104821 :               info.separate_options = false;
    6293       104821 :               info.realpaths = false;
    6294              : 
    6295       104821 :               for_each_path (&startfile_prefixes, true, 0, info);
    6296              :             }
    6297       104821 :             break;
    6298              : 
    6299            0 :           case 'P':
    6300            0 :             {
    6301            0 :               struct spec_path info;
    6302              : 
    6303            0 :               info.option = RUNPATH_OPTION;
    6304            0 :               info.append_len = 0;
    6305            0 :               info.omit_relative = false;
    6306            0 :               info.separate_options = true;
    6307              :               /* We want to embed the actual paths that have the libraries.  */
    6308            0 :               info.realpaths = true;
    6309              : 
    6310            0 :               for_each_path (&startfile_prefixes, true, 0, info);
    6311              :             }
    6312            0 :             break;
    6313              : 
    6314              :           case 'e':
    6315              :             /* %efoo means report an error with `foo' as error message
    6316              :                and don't execute any more commands for this file.  */
    6317              :             {
    6318              :               const char *q = p;
    6319              :               char *buf;
    6320            0 :               while (*p != 0 && *p != '\n')
    6321            0 :                 p++;
    6322            0 :               buf = (char *) alloca (p - q + 1);
    6323            0 :               strncpy (buf, q, p - q);
    6324            0 :               buf[p - q] = 0;
    6325            0 :               error ("%s", _(buf));
    6326            0 :               return -1;
    6327              :             }
    6328              :             break;
    6329              :           case 'n':
    6330              :             /* %nfoo means report a notice with `foo' on stderr.  */
    6331              :             {
    6332              :               const char *q = p;
    6333              :               char *buf;
    6334            0 :               while (*p != 0 && *p != '\n')
    6335            0 :                 p++;
    6336            0 :               buf = (char *) alloca (p - q + 1);
    6337            0 :               strncpy (buf, q, p - q);
    6338            0 :               buf[p - q] = 0;
    6339            0 :               inform (UNKNOWN_LOCATION, "%s", _(buf));
    6340            0 :               if (*p)
    6341            0 :                 p++;
    6342              :             }
    6343              :             break;
    6344              : 
    6345          882 :           case 'j':
    6346          882 :             {
    6347          882 :               struct stat st;
    6348              : 
    6349              :               /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
    6350              :                  defined, and it is not a directory, and it is
    6351              :                  writable, use it.  Otherwise, treat this like any
    6352              :                  other temporary file.  */
    6353              : 
    6354          882 :               if ((!save_temps_flag)
    6355          882 :                   && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
    6356         1764 :                   && (access (HOST_BIT_BUCKET, W_OK) == 0))
    6357              :                 {
    6358          882 :                   obstack_grow (&obstack, HOST_BIT_BUCKET,
    6359              :                                 strlen (HOST_BIT_BUCKET));
    6360          882 :                   delete_this_arg = 0;
    6361          882 :                   arg_going = 1;
    6362          882 :                   break;
    6363              :                 }
    6364              :             }
    6365            0 :             goto create_temp_file;
    6366       164617 :           case '|':
    6367       164617 :             if (use_pipes)
    6368              :               {
    6369            0 :                 obstack_1grow (&obstack, '-');
    6370            0 :                 delete_this_arg = 0;
    6371            0 :                 arg_going = 1;
    6372              : 
    6373              :                 /* consume suffix */
    6374            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6375            0 :                   p++;
    6376            0 :                 if (p[0] == '%' && p[1] == 'O')
    6377            0 :                   p += 2;
    6378              : 
    6379              :                 break;
    6380              :               }
    6381       164617 :             goto create_temp_file;
    6382       159276 :           case 'm':
    6383       159276 :             if (use_pipes)
    6384              :               {
    6385              :                 /* consume suffix */
    6386            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6387            0 :                   p++;
    6388            0 :                 if (p[0] == '%' && p[1] == 'O')
    6389            0 :                   p += 2;
    6390              : 
    6391              :                 break;
    6392              :               }
    6393       159276 :             goto create_temp_file;
    6394       513232 :           case 'g':
    6395       513232 :           case 'u':
    6396       513232 :           case 'U':
    6397       513232 :           create_temp_file:
    6398       513232 :               {
    6399       513232 :                 struct temp_name *t;
    6400       513232 :                 int suffix_length;
    6401       513232 :                 const char *suffix = p;
    6402       513232 :                 char *saved_suffix = NULL;
    6403              : 
    6404      1529040 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6405      1015808 :                   p++;
    6406       513232 :                 suffix_length = p - suffix;
    6407       513232 :                 if (p[0] == '%' && p[1] == 'O')
    6408              :                   {
    6409        97089 :                     p += 2;
    6410              :                     /* We don't support extra suffix characters after %O.  */
    6411        97089 :                     if (*p == '.' || ISALNUM ((unsigned char) *p))
    6412            0 :                       fatal_error (input_location,
    6413              :                                    "spec %qs has invalid %<%%0%c%>", spec, *p);
    6414        97089 :                     if (suffix_length == 0)
    6415              :                       suffix = TARGET_OBJECT_SUFFIX;
    6416              :                     else
    6417              :                       {
    6418            0 :                         saved_suffix
    6419            0 :                           = XNEWVEC (char, suffix_length
    6420              :                                      + strlen (TARGET_OBJECT_SUFFIX) + 1);
    6421            0 :                         strncpy (saved_suffix, suffix, suffix_length);
    6422            0 :                         strcpy (saved_suffix + suffix_length,
    6423              :                                 TARGET_OBJECT_SUFFIX);
    6424              :                       }
    6425        97089 :                     suffix_length += strlen (TARGET_OBJECT_SUFFIX);
    6426              :                   }
    6427              : 
    6428       513232 :                 if (compare_debug < 0)
    6429              :                   {
    6430          610 :                     suffix = concat (".gk", suffix, NULL);
    6431          610 :                     suffix_length += 3;
    6432              :                   }
    6433              : 
    6434              :                 /* If -save-temps was specified, use that for the
    6435              :                    temp file.  */
    6436       513232 :                 if (save_temps_flag)
    6437              :                   {
    6438         1194 :                     char *tmp;
    6439         1194 :                     bool adjusted_suffix = false;
    6440         1194 :                     if (suffix_length
    6441         1194 :                         && !outbase_length && !basename_length
    6442          224 :                         && !dumpdir_trailing_dash_added)
    6443              :                       {
    6444           20 :                         adjusted_suffix = true;
    6445           20 :                         suffix++;
    6446           20 :                         suffix_length--;
    6447              :                       }
    6448         1194 :                     temp_filename_length
    6449         1194 :                       = dumpdir_length + suffix_length + 1;
    6450         1194 :                     if (outbase_length)
    6451           72 :                       temp_filename_length += outbase_length;
    6452              :                     else
    6453         1122 :                       temp_filename_length += basename_length;
    6454         1194 :                     tmp = (char *) alloca (temp_filename_length);
    6455         1194 :                     if (dumpdir_length)
    6456         1036 :                       memcpy (tmp, dumpdir, dumpdir_length);
    6457         1194 :                     if (outbase_length)
    6458           72 :                       memcpy (tmp + dumpdir_length, outbase,
    6459              :                               outbase_length);
    6460         1122 :                     else if (basename_length)
    6461          898 :                       memcpy (tmp + dumpdir_length, input_basename,
    6462              :                               basename_length);
    6463         1194 :                     memcpy (tmp + temp_filename_length - suffix_length - 1,
    6464              :                             suffix, suffix_length);
    6465         1194 :                     if (adjusted_suffix)
    6466              :                       {
    6467           20 :                         adjusted_suffix = false;
    6468           20 :                         suffix--;
    6469           20 :                         suffix_length++;
    6470              :                       }
    6471         1194 :                     tmp[temp_filename_length - 1] = '\0';
    6472         1194 :                     temp_filename = tmp;
    6473              : 
    6474         1194 :                     if (filename_cmp (temp_filename, gcc_input_filename) != 0)
    6475              :                       {
    6476              : #ifndef HOST_LACKS_INODE_NUMBERS
    6477         1194 :                         struct stat st_temp;
    6478              : 
    6479              :                         /* Note, set_input() resets input_stat_set to 0.  */
    6480         1194 :                         if (input_stat_set == 0)
    6481              :                           {
    6482          557 :                             input_stat_set = stat (gcc_input_filename,
    6483              :                                                    &input_stat);
    6484          557 :                             if (input_stat_set >= 0)
    6485          557 :                               input_stat_set = 1;
    6486              :                           }
    6487              : 
    6488              :                         /* If we have the stat for the gcc_input_filename
    6489              :                            and we can do the stat for the temp_filename
    6490              :                            then the they could still refer to the same
    6491              :                            file if st_dev/st_ino's are the same.  */
    6492         1194 :                         if (input_stat_set != 1
    6493         1194 :                             || stat (temp_filename, &st_temp) < 0
    6494          365 :                             || input_stat.st_dev != st_temp.st_dev
    6495         1208 :                             || input_stat.st_ino != st_temp.st_ino)
    6496              : #else
    6497              :                         /* Just compare canonical pathnames.  */
    6498              :                         char* input_realname = lrealpath (gcc_input_filename);
    6499              :                         char* temp_realname = lrealpath (temp_filename);
    6500              :                         bool files_differ = filename_cmp (input_realname, temp_realname);
    6501              :                         free (input_realname);
    6502              :                         free (temp_realname);
    6503              :                         if (files_differ)
    6504              : #endif
    6505              :                           {
    6506         1194 :                             temp_filename
    6507         1194 :                               = save_string (temp_filename,
    6508              :                                              temp_filename_length - 1);
    6509         1194 :                             obstack_grow (&obstack, temp_filename,
    6510              :                                                     temp_filename_length);
    6511         1194 :                             arg_going = 1;
    6512         1194 :                             delete_this_arg = 0;
    6513         1194 :                             break;
    6514              :                           }
    6515              :                       }
    6516              :                   }
    6517              : 
    6518              :                 /* See if we already have an association of %g/%u/%U and
    6519              :                    suffix.  */
    6520       878930 :                 for (t = temp_names; t; t = t->next)
    6521       533176 :                   if (t->length == suffix_length
    6522       356194 :                       && strncmp (t->suffix, suffix, suffix_length) == 0
    6523       170225 :                       && t->unique == (c == 'u' || c == 'U' || c == 'j'))
    6524              :                     break;
    6525              : 
    6526              :                 /* Make a new association if needed.  %u and %j
    6527              :                    require one.  */
    6528       512038 :                 if (t == 0 || c == 'u' || c == 'j')
    6529              :                   {
    6530       349495 :                     if (t == 0)
    6531              :                       {
    6532       345754 :                         t = XNEW (struct temp_name);
    6533       345754 :                         t->next = temp_names;
    6534       345754 :                         temp_names = t;
    6535              :                       }
    6536       349495 :                     t->length = suffix_length;
    6537       349495 :                     if (saved_suffix)
    6538              :                       {
    6539            0 :                         t->suffix = saved_suffix;
    6540            0 :                         saved_suffix = NULL;
    6541              :                       }
    6542              :                     else
    6543       349495 :                       t->suffix = save_string (suffix, suffix_length);
    6544       349495 :                     t->unique = (c == 'u' || c == 'U' || c == 'j');
    6545       349495 :                     temp_filename = make_temp_file (t->suffix);
    6546       349495 :                     temp_filename_length = strlen (temp_filename);
    6547       349495 :                     t->filename = temp_filename;
    6548       349495 :                     t->filename_length = temp_filename_length;
    6549              :                   }
    6550              : 
    6551       512038 :                 free (saved_suffix);
    6552              : 
    6553       512038 :                 obstack_grow (&obstack, t->filename, t->filename_length);
    6554       512038 :                 delete_this_arg = 1;
    6555              :               }
    6556       512038 :             arg_going = 1;
    6557       512038 :             break;
    6558              : 
    6559       285223 :           case 'i':
    6560       285223 :             if (combine_inputs)
    6561              :               {
    6562              :                 /* We are going to expand `%i' into `@FILE', where FILE
    6563              :                    is a newly-created temporary filename.  The filenames
    6564              :                    that would usually be expanded in place of %o will be
    6565              :                    written to the temporary file.  */
    6566        29672 :                 if (at_file_supplied)
    6567        12280 :                   open_at_file ();
    6568              : 
    6569        73125 :                 for (i = 0; (int) i < n_infiles; i++)
    6570        86906 :                   if (compile_input_file_p (&infiles[i]))
    6571              :                     {
    6572        38788 :                       store_arg (infiles[i].name, 0, 0);
    6573        38788 :                       infiles[i].compiled = true;
    6574              :                     }
    6575              : 
    6576        29672 :                 if (at_file_supplied)
    6577        12280 :                   close_at_file ();
    6578              :               }
    6579              :             else
    6580              :               {
    6581       255551 :                 obstack_grow (&obstack, gcc_input_filename,
    6582              :                               input_filename_length);
    6583       255551 :                 arg_going = 1;
    6584              :               }
    6585              :             break;
    6586              : 
    6587       221267 :           case 'I':
    6588       221267 :             {
    6589       221267 :               struct spec_path info;
    6590              : 
    6591       221267 :               if (multilib_dir)
    6592              :                 {
    6593         6029 :                   do_spec_1 ("-imultilib", 1, NULL);
    6594              :                   /* Make this a separate argument.  */
    6595         6029 :                   do_spec_1 (" ", 0, NULL);
    6596         6029 :                   do_spec_1 (multilib_dir, 1, NULL);
    6597         6029 :                   do_spec_1 (" ", 0, NULL);
    6598              :                 }
    6599              : 
    6600       221267 :               if (multiarch_dir)
    6601              :                 {
    6602            0 :                   do_spec_1 ("-imultiarch", 1, NULL);
    6603              :                   /* Make this a separate argument.  */
    6604            0 :                   do_spec_1 (" ", 0, NULL);
    6605            0 :                   do_spec_1 (multiarch_dir, 1, NULL);
    6606            0 :                   do_spec_1 (" ", 0, NULL);
    6607              :                 }
    6608              : 
    6609       221267 :               if (gcc_exec_prefix)
    6610              :                 {
    6611       221267 :                   do_spec_1 ("-iprefix", 1, NULL);
    6612              :                   /* Make this a separate argument.  */
    6613       221267 :                   do_spec_1 (" ", 0, NULL);
    6614       221267 :                   do_spec_1 (gcc_exec_prefix, 1, NULL);
    6615       221267 :                   do_spec_1 (" ", 0, NULL);
    6616              :                 }
    6617              : 
    6618       221267 :               if (target_system_root_changed ||
    6619       221267 :                   (target_system_root && target_sysroot_hdrs_suffix))
    6620              :                 {
    6621            0 :                   do_spec_1 ("-isysroot", 1, NULL);
    6622              :                   /* Make this a separate argument.  */
    6623            0 :                   do_spec_1 (" ", 0, NULL);
    6624            0 :                   do_spec_1 (target_system_root, 1, NULL);
    6625            0 :                   if (target_sysroot_hdrs_suffix)
    6626            0 :                     do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
    6627            0 :                   do_spec_1 (" ", 0, NULL);
    6628              :                 }
    6629              : 
    6630       221267 :               info.option = "-isystem";
    6631       221267 :               info.append = "include";
    6632       221267 :               info.append_len = strlen (info.append);
    6633       221267 :               info.omit_relative = false;
    6634       221267 :               info.separate_options = true;
    6635       221267 :               info.realpaths = false;
    6636              : 
    6637       221267 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6638              : 
    6639       221267 :               info.append = "include-fixed";
    6640       221267 :               if (*sysroot_hdrs_suffix_spec)
    6641            0 :                 info.append = concat (info.append, dir_separator_str,
    6642              :                                       multilib_dir, NULL);
    6643       221267 :               else if (multiarch_dir)
    6644              :                 {
    6645              :                   /* For multiarch, search include-fixed/<multiarch-dir>
    6646              :                      before include-fixed.  */
    6647            0 :                   info.append = concat (info.append, dir_separator_str,
    6648              :                                         multiarch_dir, NULL);
    6649            0 :                   info.append_len = strlen (info.append);
    6650            0 :                   for_each_path (&include_prefixes, false,
    6651              :                                  info.append_len, info);
    6652              : 
    6653            0 :                   info.append = "include-fixed";
    6654              :                 }
    6655       221267 :               info.append_len = strlen (info.append);
    6656       221267 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6657              :             }
    6658       221267 :             break;
    6659              : 
    6660        94936 :           case 'o':
    6661              :             /* We are going to expand `%o' into `@FILE', where FILE
    6662              :                is a newly-created temporary filename.  The filenames
    6663              :                that would usually be expanded in place of %o will be
    6664              :                written to the temporary file.  */
    6665        94936 :             if (at_file_supplied)
    6666            6 :               open_at_file ();
    6667              : 
    6668       422336 :             for (i = 0; i < n_infiles + lang_specific_extra_outfiles; i++)
    6669       327400 :               if (outfiles[i])
    6670       327360 :                 store_arg (outfiles[i], 0, 0);
    6671              : 
    6672        94936 :             if (at_file_supplied)
    6673            6 :               close_at_file ();
    6674              :             break;
    6675              : 
    6676         3746 :           case 'O':
    6677         3746 :             obstack_grow (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    6678         3746 :             arg_going = 1;
    6679         3746 :             break;
    6680              : 
    6681       536912 :           case 's':
    6682       536912 :             this_is_library_file = 1;
    6683       536912 :             break;
    6684              : 
    6685            0 :           case 'T':
    6686            0 :             this_is_linker_script = 1;
    6687            0 :             break;
    6688              : 
    6689          421 :           case 'V':
    6690          421 :             outfiles[input_file_number] = NULL;
    6691          421 :             break;
    6692              : 
    6693        99816 :           case 'w':
    6694        99816 :             this_is_output_file = 1;
    6695        99816 :             break;
    6696              : 
    6697       173251 :           case 'W':
    6698       173251 :             {
    6699       173251 :               unsigned int cur_index = argbuf.length ();
    6700              :               /* Handle the {...} following the %W.  */
    6701       173251 :               if (*p != '{')
    6702            0 :                 fatal_error (input_location,
    6703              :                              "spec %qs has invalid %<%%W%c%>", spec, *p);
    6704       173251 :               p = handle_braces (p + 1);
    6705       173251 :               if (p == 0)
    6706              :                 return -1;
    6707       173251 :               end_going_arg ();
    6708              :               /* If any args were output, mark the last one for deletion
    6709              :                  on failure.  */
    6710       346502 :               if (argbuf.length () != cur_index)
    6711       170067 :                 record_temp_file (argbuf.last (), 0, 1);
    6712              :               break;
    6713              :             }
    6714              : 
    6715       301779 :           case '@':
    6716              :             /* Handle the {...} following the %@.  */
    6717       301779 :             if (*p != '{')
    6718            0 :               fatal_error (input_location,
    6719              :                            "spec %qs has invalid %<%%@%c%>", spec, *p);
    6720       301779 :             if (at_file_supplied)
    6721           15 :               open_at_file ();
    6722       301779 :             p = handle_braces (p + 1);
    6723       301779 :             if (at_file_supplied)
    6724           15 :               close_at_file ();
    6725       301779 :             if (p == 0)
    6726              :               return -1;
    6727              :             break;
    6728              : 
    6729              :           /* %x{OPTION} records OPTION for %X to output.  */
    6730            0 :           case 'x':
    6731            0 :             {
    6732            0 :               const char *p1 = p;
    6733            0 :               char *string;
    6734              : 
    6735              :               /* Skip past the option value and make a copy.  */
    6736            0 :               if (*p != '{')
    6737            0 :                 fatal_error (input_location,
    6738              :                              "spec %qs has invalid %<%%x%c%>", spec, *p);
    6739            0 :               while (*p++ != '}')
    6740              :                 ;
    6741            0 :               string = save_string (p1 + 1, p - p1 - 2);
    6742              : 
    6743              :               /* See if we already recorded this option.  */
    6744            0 :               for (const char *opt : linker_options)
    6745            0 :                 if (! strcmp (string, opt))
    6746              :                   {
    6747            0 :                     free (string);
    6748            0 :                     return 0;
    6749              :                   }
    6750              : 
    6751              :               /* This option is new; add it.  */
    6752            0 :               add_linker_option (string, strlen (string));
    6753            0 :               free (string);
    6754              :             }
    6755            0 :             break;
    6756              : 
    6757              :           /* Dump out the options accumulated previously using %x.  */
    6758        94936 :           case 'X':
    6759        94936 :             do_specs_vec (linker_options);
    6760        94936 :             break;
    6761              : 
    6762              :           /* Dump out the options accumulated previously using -Wa,.  */
    6763       161116 :           case 'Y':
    6764       161116 :             do_specs_vec (assembler_options);
    6765       161116 :             break;
    6766              : 
    6767              :           /* Dump out the options accumulated previously using -Wp,.  */
    6768       206843 :           case 'Z':
    6769       206843 :             do_specs_vec (preprocessor_options);
    6770       206843 :             break;
    6771              : 
    6772              :             /* Here are digits and numbers that just process
    6773              :                a certain constant string as a spec.  */
    6774              : 
    6775       282163 :           case '1':
    6776       282163 :             value = do_spec_1 (cc1_spec, 0, NULL);
    6777       282163 :             if (value != 0)
    6778              :               return value;
    6779              :             break;
    6780              : 
    6781        97489 :           case '2':
    6782        97489 :             value = do_spec_1 (cc1plus_spec, 0, NULL);
    6783        97489 :             if (value != 0)
    6784              :               return value;
    6785              :             break;
    6786              : 
    6787       161116 :           case 'a':
    6788       161116 :             value = do_spec_1 (asm_spec, 0, NULL);
    6789       161116 :             if (value != 0)
    6790              :               return value;
    6791              :             break;
    6792              : 
    6793       161116 :           case 'A':
    6794       161116 :             value = do_spec_1 (asm_final_spec, 0, NULL);
    6795       161116 :             if (value != 0)
    6796              :               return value;
    6797              :             break;
    6798              : 
    6799       206843 :           case 'C':
    6800       206843 :             {
    6801       109480 :               const char *const spec
    6802       206843 :                 = (input_file_compiler->cpp_spec
    6803       206843 :                    ? input_file_compiler->cpp_spec
    6804              :                    : cpp_spec);
    6805       206843 :               value = do_spec_1 (spec, 0, NULL);
    6806       206843 :               if (value != 0)
    6807              :                 return value;
    6808              :             }
    6809              :             break;
    6810              : 
    6811        94730 :           case 'E':
    6812        94730 :             value = do_spec_1 (endfile_spec, 0, NULL);
    6813        94730 :             if (value != 0)
    6814              :               return value;
    6815              :             break;
    6816              : 
    6817        94936 :           case 'l':
    6818        94936 :             value = do_spec_1 (link_spec, 0, NULL);
    6819        94936 :             if (value != 0)
    6820              :               return value;
    6821              :             break;
    6822              : 
    6823       183975 :           case 'L':
    6824       183975 :             value = do_spec_1 (lib_spec, 0, NULL);
    6825       183975 :             if (value != 0)
    6826              :               return value;
    6827              :             break;
    6828              : 
    6829            0 :           case 'M':
    6830            0 :             if (multilib_os_dir == NULL)
    6831            0 :               obstack_1grow (&obstack, '.');
    6832              :             else
    6833            0 :               obstack_grow (&obstack, multilib_os_dir,
    6834              :                             strlen (multilib_os_dir));
    6835              :             break;
    6836              : 
    6837       367760 :           case 'G':
    6838       367760 :             value = do_spec_1 (libgcc_spec, 0, NULL);
    6839       367760 :             if (value != 0)
    6840              :               return value;
    6841              :             break;
    6842              : 
    6843            0 :           case 'R':
    6844              :             /* We assume there is a directory
    6845              :                separator at the end of this string.  */
    6846            0 :             if (target_system_root)
    6847              :               {
    6848            0 :                 obstack_grow (&obstack, target_system_root,
    6849              :                               strlen (target_system_root));
    6850            0 :                 if (target_sysroot_suffix)
    6851            0 :                   obstack_grow (&obstack, target_sysroot_suffix,
    6852              :                                 strlen (target_sysroot_suffix));
    6853              :               }
    6854              :             break;
    6855              : 
    6856        94730 :           case 'S':
    6857        94730 :             value = do_spec_1 (startfile_spec, 0, NULL);
    6858        94730 :             if (value != 0)
    6859              :               return value;
    6860              :             break;
    6861              : 
    6862              :             /* Here we define characters other than letters and digits.  */
    6863              : 
    6864     39780492 :           case '{':
    6865     39780492 :             p = handle_braces (p);
    6866     39780492 :             if (p == 0)
    6867              :               return -1;
    6868              :             break;
    6869              : 
    6870       435231 :           case ':':
    6871       435231 :             p = handle_spec_function (p, NULL, soft_matched_part);
    6872       435231 :             if (p == 0)
    6873              :               return -1;
    6874              :             break;
    6875              : 
    6876            0 :           case '%':
    6877            0 :             obstack_1grow (&obstack, '%');
    6878            0 :             break;
    6879              : 
    6880              :           case '.':
    6881              :             {
    6882              :               unsigned len = 0;
    6883              : 
    6884        11898 :               while (p[len] && p[len] != ' ' && p[len] != '%')
    6885         5967 :                 len++;
    6886         5931 :               suffix_subst = save_string (p - 1, len + 1);
    6887         5931 :               p += len;
    6888              :             }
    6889         5931 :            break;
    6890              : 
    6891              :            /* Henceforth ignore the option(s) matching the pattern
    6892              :               after the %<.  */
    6893      1447327 :           case '<':
    6894      1447327 :           case '>':
    6895      1447327 :             {
    6896      1447327 :               unsigned len = 0;
    6897      1447327 :               int have_wildcard = 0;
    6898      1447327 :               int i;
    6899      1447327 :               int switch_option;
    6900              : 
    6901      1447327 :               if (c == '>')
    6902      1447327 :                 switch_option = SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC;
    6903              :               else
    6904      1447305 :                 switch_option = SWITCH_IGNORE;
    6905              : 
    6906     17456873 :               while (p[len] && p[len] != ' ' && p[len] != '\t')
    6907     16009546 :                 len++;
    6908              : 
    6909      1447327 :               if (p[len-1] == '*')
    6910        14670 :                 have_wildcard = 1;
    6911              : 
    6912     34635450 :               for (i = 0; i < n_switches; i++)
    6913     33188123 :                 if (!strncmp (switches[i].part1, p, len - have_wildcard)
    6914        45644 :                     && (have_wildcard || switches[i].part1[len] == '\0'))
    6915              :                   {
    6916        45375 :                     switches[i].live_cond |= switch_option;
    6917              :                     /* User switch be validated from validate_all_switches.
    6918              :                        when the definition is seen from the spec file.
    6919              :                        If not defined anywhere, will be rejected.  */
    6920        45375 :                     if (switches[i].known)
    6921        45375 :                       switches[i].validated = true;
    6922              :                   }
    6923              : 
    6924              :               p += len;
    6925              :             }
    6926              :             break;
    6927              : 
    6928         6798 :           case '*':
    6929         6798 :             if (soft_matched_part)
    6930              :               {
    6931         6798 :                 if (soft_matched_part[0])
    6932          333 :                   do_spec_1 (soft_matched_part, 1, NULL);
    6933              :                 /* Only insert a space after the substitution if it is at the
    6934              :                    end of the current sequence.  So if:
    6935              : 
    6936              :                      "%{foo=*:bar%*}%{foo=*:one%*two}"
    6937              : 
    6938              :                    matches -foo=hello then it will produce:
    6939              : 
    6940              :                      barhello onehellotwo
    6941              :                 */
    6942         6798 :                 if (*p == 0 || *p == '}')
    6943         6798 :                   do_spec_1 (" ", 0, NULL);
    6944              :               }
    6945              :             else
    6946              :               /* Catch the case where a spec string contains something like
    6947              :                  '%{foo:%*}'.  i.e. there is no * in the pattern on the left
    6948              :                  hand side of the :.  */
    6949            0 :               error ("spec failure: %<%%*%> has not been initialized by pattern match");
    6950              :             break;
    6951              : 
    6952              :             /* Process a string found as the value of a spec given by name.
    6953              :                This feature allows individual machine descriptions
    6954              :                to add and use their own specs.  */
    6955              :           case '(':
    6956              :             {
    6957     32982648 :               const char *name = p;
    6958              :               struct spec_list *sl;
    6959              :               int len;
    6960              : 
    6961              :               /* The string after the S/P is the name of a spec that is to be
    6962              :                  processed.  */
    6963     32982648 :               while (*p && *p != ')')
    6964     30438326 :                 p++;
    6965              : 
    6966              :               /* See if it's in the list.  */
    6967     34972361 :               for (len = p - name, sl = specs; sl; sl = sl->next)
    6968     34972361 :                 if (sl->name_len == len && !strncmp (sl->name, name, len))
    6969              :                   {
    6970      2544322 :                     name = *(sl->ptr_spec);
    6971              : #ifdef DEBUG_SPECS
    6972              :                     fnotice (stderr, "Processing spec (%s), which is '%s'\n",
    6973              :                              sl->name, name);
    6974              : #endif
    6975      2544322 :                     break;
    6976              :                   }
    6977              : 
    6978      2544322 :               if (sl)
    6979              :                 {
    6980      2544322 :                   value = do_spec_1 (name, 0, NULL);
    6981      2544322 :                   if (value != 0)
    6982              :                     return value;
    6983              :                 }
    6984              : 
    6985              :               /* Discard the closing paren.  */
    6986      2538981 :               if (*p)
    6987      2538981 :                 p++;
    6988              :             }
    6989              :             break;
    6990              : 
    6991            9 :           case '"':
    6992              :             /* End a previous argument, if there is one, then issue an
    6993              :                empty argument.  */
    6994            9 :             end_going_arg ();
    6995            9 :             arg_going = 1;
    6996            9 :             end_going_arg ();
    6997            9 :             break;
    6998              : 
    6999            0 :           default:
    7000            0 :             error ("spec failure: unrecognized spec option %qc", c);
    7001            0 :             break;
    7002              :           }
    7003              :         break;
    7004              : 
    7005            0 :       case '\\':
    7006              :         /* Backslash: treat next character as ordinary.  */
    7007            0 :         c = *p++;
    7008              : 
    7009              :         /* When adding more cases that previously matched default, make
    7010              :            sure to adjust quote_spec_char_p as well.  */
    7011              : 
    7012              :         /* Fall through.  */
    7013    356920204 :       default:
    7014              :         /* Ordinary character: put it into the current argument.  */
    7015    356920204 :         obstack_1grow (&obstack, c);
    7016    356920204 :         arg_going = 1;
    7017              :       }
    7018              : 
    7019              :   /* End of string.  If we are processing a spec function, we need to
    7020              :      end any pending argument.  */
    7021     52148865 :   if (processing_spec_function)
    7022      4470974 :     end_going_arg ();
    7023              : 
    7024              :   return 0;
    7025              : }
    7026              : 
    7027              : /* Look up a spec function.  */
    7028              : 
    7029              : static const struct spec_function *
    7030      2055853 : lookup_spec_function (const char *name)
    7031              : {
    7032      2055853 :   const struct spec_function *sf;
    7033              : 
    7034     24601662 :   for (sf = static_spec_functions; sf->name != NULL; sf++)
    7035     24601662 :     if (strcmp (sf->name, name) == 0)
    7036              :       return sf;
    7037              : 
    7038              :   return NULL;
    7039              : }
    7040              : 
    7041              : /* Evaluate a spec function.  */
    7042              : 
    7043              : static const char *
    7044      2055853 : eval_spec_function (const char *func, const char *args,
    7045              :                     const char *soft_matched_part)
    7046              : {
    7047      2055853 :   const struct spec_function *sf;
    7048      2055853 :   const char *funcval;
    7049              : 
    7050              :   /* Saved spec processing context.  */
    7051      2055853 :   vec<const_char_p> save_argbuf;
    7052              : 
    7053      2055853 :   int save_arg_going;
    7054      2055853 :   int save_delete_this_arg;
    7055      2055853 :   int save_this_is_output_file;
    7056      2055853 :   int save_this_is_library_file;
    7057      2055853 :   int save_input_from_pipe;
    7058      2055853 :   int save_this_is_linker_script;
    7059      2055853 :   const char *save_suffix_subst;
    7060              : 
    7061      2055853 :   int save_growing_size;
    7062      2055853 :   void *save_growing_value = NULL;
    7063              : 
    7064      2055853 :   sf = lookup_spec_function (func);
    7065      2055853 :   if (sf == NULL)
    7066            0 :     fatal_error (input_location, "unknown spec function %qs", func);
    7067              : 
    7068              :   /* Push the spec processing context.  */
    7069      2055853 :   save_argbuf = argbuf;
    7070              : 
    7071      2055853 :   save_arg_going = arg_going;
    7072      2055853 :   save_delete_this_arg = delete_this_arg;
    7073      2055853 :   save_this_is_output_file = this_is_output_file;
    7074      2055853 :   save_this_is_library_file = this_is_library_file;
    7075      2055853 :   save_this_is_linker_script = this_is_linker_script;
    7076      2055853 :   save_input_from_pipe = input_from_pipe;
    7077      2055853 :   save_suffix_subst = suffix_subst;
    7078              : 
    7079              :   /* If we have some object growing now, finalize it so the args and function
    7080              :      eval proceed from a cleared context.  This is needed to prevent the first
    7081              :      constructed arg from mistakenly including the growing value.  We'll push
    7082              :      this value back on the obstack once the function evaluation is done, to
    7083              :      restore a consistent processing context for our caller.  This is fine as
    7084              :      the address of growing objects isn't guaranteed to remain stable until
    7085              :      they are finalized, and we expect this situation to be rare enough for
    7086              :      the extra copy not to be an issue.  */
    7087      2055853 :   save_growing_size = obstack_object_size (&obstack);
    7088      2055853 :   if (save_growing_size > 0)
    7089        42377 :     save_growing_value = obstack_finish (&obstack);
    7090              : 
    7091              :   /* Create a new spec processing context, and build the function
    7092              :      arguments.  */
    7093              : 
    7094      2055853 :   alloc_args ();
    7095      2055853 :   if (do_spec_2 (args, soft_matched_part) < 0)
    7096            0 :     fatal_error (input_location, "error in arguments to spec function %qs",
    7097              :                  func);
    7098              : 
    7099              :   /* argbuf_index is an index for the next argument to be inserted, and
    7100              :      so contains the count of the args already inserted.  */
    7101              : 
    7102      6167559 :   funcval = (*sf->func) (argbuf.length (),
    7103              :                          argbuf.address ());
    7104              : 
    7105              :   /* Pop the spec processing context.  */
    7106      2055853 :   argbuf.release ();
    7107      2055853 :   argbuf = save_argbuf;
    7108              : 
    7109      2055853 :   arg_going = save_arg_going;
    7110      2055853 :   delete_this_arg = save_delete_this_arg;
    7111      2055853 :   this_is_output_file = save_this_is_output_file;
    7112      2055853 :   this_is_library_file = save_this_is_library_file;
    7113      2055853 :   this_is_linker_script = save_this_is_linker_script;
    7114      2055853 :   input_from_pipe = save_input_from_pipe;
    7115      2055853 :   suffix_subst = save_suffix_subst;
    7116              : 
    7117      2055853 :   if (save_growing_size > 0)
    7118        42377 :     obstack_grow (&obstack, save_growing_value, save_growing_size);
    7119              : 
    7120      2055853 :   return funcval;
    7121              : }
    7122              : 
    7123              : /* Handle a spec function call of the form:
    7124              : 
    7125              :    %:function(args)
    7126              : 
    7127              :    ARGS is processed as a spec in a separate context and split into an
    7128              :    argument vector in the normal fashion.  The function returns a string
    7129              :    containing a spec which we then process in the caller's context, or
    7130              :    NULL if no processing is required.
    7131              : 
    7132              :    If RETVAL_NONNULL is not NULL, then store a bool whether function
    7133              :    returned non-NULL.
    7134              : 
    7135              :    SOFT_MATCHED_PART holds the current value of a matched * pattern, which
    7136              :    may be re-expanded with a %* as part of the function arguments.  */
    7137              : 
    7138              : static const char *
    7139      2055853 : handle_spec_function (const char *p, bool *retval_nonnull,
    7140              :                       const char *soft_matched_part)
    7141              : {
    7142      2055853 :   char *func, *args;
    7143      2055853 :   const char *endp, *funcval;
    7144      2055853 :   int count;
    7145              : 
    7146      2055853 :   processing_spec_function++;
    7147              : 
    7148              :   /* Get the function name.  */
    7149     19139602 :   for (endp = p; *endp != '\0'; endp++)
    7150              :     {
    7151     19139602 :       if (*endp == '(')         /* ) */
    7152              :         break;
    7153              :       /* Only allow [A-Za-z0-9], -, and _ in function names.  */
    7154     17083749 :       if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
    7155            0 :         fatal_error (input_location, "malformed spec function name");
    7156              :     }
    7157      2055853 :   if (*endp != '(')             /* ) */
    7158            0 :     fatal_error (input_location, "no arguments for spec function");
    7159      2055853 :   func = save_string (p, endp - p);
    7160      2055853 :   p = ++endp;
    7161              : 
    7162              :   /* Get the arguments.  */
    7163     24977749 :   for (count = 0; *endp != '\0'; endp++)
    7164              :     {
    7165              :       /* ( */
    7166     24977749 :       if (*endp == ')')
    7167              :         {
    7168      2145100 :           if (count == 0)
    7169              :             break;
    7170        89247 :           count--;
    7171              :         }
    7172     22832649 :       else if (*endp == '(')    /* ) */
    7173        89247 :         count++;
    7174              :     }
    7175              :   /* ( */
    7176      2055853 :   if (*endp != ')')
    7177            0 :     fatal_error (input_location, "malformed spec function arguments");
    7178      2055853 :   args = save_string (p, endp - p);
    7179      2055853 :   p = ++endp;
    7180              : 
    7181              :   /* p now points to just past the end of the spec function expression.  */
    7182              : 
    7183      2055853 :   funcval = eval_spec_function (func, args, soft_matched_part);
    7184      2055853 :   if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
    7185              :     p = NULL;
    7186      2055853 :   if (retval_nonnull)
    7187      1620622 :     *retval_nonnull = funcval != NULL;
    7188              : 
    7189      2055853 :   free (func);
    7190      2055853 :   free (args);
    7191              : 
    7192      2055853 :   processing_spec_function--;
    7193              : 
    7194      2055853 :   return p;
    7195              : }
    7196              : 
    7197              : /* Inline subroutine of handle_braces.  Returns true if the current
    7198              :    input suffix matches the atom bracketed by ATOM and END_ATOM.  */
    7199              : static inline bool
    7200            0 : input_suffix_matches (const char *atom, const char *end_atom)
    7201              : {
    7202            0 :   return (input_suffix
    7203            0 :           && !strncmp (input_suffix, atom, end_atom - atom)
    7204            0 :           && input_suffix[end_atom - atom] == '\0');
    7205              : }
    7206              : 
    7207              : /* Subroutine of handle_braces.  Returns true if the current
    7208              :    input file's spec name matches the atom bracketed by ATOM and END_ATOM.  */
    7209              : static bool
    7210            0 : input_spec_matches (const char *atom, const char *end_atom)
    7211              : {
    7212            0 :   return (input_file_compiler
    7213            0 :           && input_file_compiler->suffix
    7214            0 :           && input_file_compiler->suffix[0] != '\0'
    7215            0 :           && !strncmp (input_file_compiler->suffix + 1, atom,
    7216            0 :                        end_atom - atom)
    7217            0 :           && input_file_compiler->suffix[end_atom - atom + 1] == '\0');
    7218              : }
    7219              : 
    7220              : /* Subroutine of handle_braces.  Returns true if a switch
    7221              :    matching the atom bracketed by ATOM and END_ATOM appeared on the
    7222              :    command line.  */
    7223              : static bool
    7224     38220487 : switch_matches (const char *atom, const char *end_atom, int starred)
    7225              : {
    7226     38220487 :   int i;
    7227     38220487 :   int len = end_atom - atom;
    7228     38220487 :   int plen = starred ? len : -1;
    7229              : 
    7230    898965680 :   for (i = 0; i < n_switches; i++)
    7231    862107947 :     if (!strncmp (switches[i].part1, atom, len)
    7232      2304791 :         && (starred || switches[i].part1[len] == '\0')
    7233    863471318 :         && check_live_switch (i, plen))
    7234              :       return true;
    7235              : 
    7236              :     /* Check if a switch with separated form matching the atom.
    7237              :        We check -D and -U switches. */
    7238    860745194 :     else if (switches[i].args != 0)
    7239              :       {
    7240    199261047 :         if ((*switches[i].part1 == 'D' || *switches[i].part1 == 'U')
    7241      8328727 :             && *switches[i].part1 == atom[0])
    7242              :           {
    7243            1 :             if (!strncmp (switches[i].args[0], &atom[1], len - 1)
    7244            1 :                 && (starred || (switches[i].part1[1] == '\0'
    7245            1 :                                 && switches[i].args[0][len - 1] == '\0'))
    7246            2 :                 && check_live_switch (i, (starred ? 1 : -1)))
    7247              :               return true;
    7248              :           }
    7249              :       }
    7250              : 
    7251              :   return false;
    7252              : }
    7253              : 
    7254              : /* Inline subroutine of handle_braces.  Mark all of the switches which
    7255              :    match ATOM (extends to END_ATOM; STARRED indicates whether there
    7256              :    was a star after the atom) for later processing.  */
    7257              : static inline void
    7258     11111035 : mark_matching_switches (const char *atom, const char *end_atom, int starred)
    7259              : {
    7260     11111035 :   int i;
    7261     11111035 :   int len = end_atom - atom;
    7262     11111035 :   int plen = starred ? len : -1;
    7263              : 
    7264    265037578 :   for (i = 0; i < n_switches; i++)
    7265    253926543 :     if (!strncmp (switches[i].part1, atom, len)
    7266      6287494 :         && (starred || switches[i].part1[len] == '\0')
    7267    259995904 :         && check_live_switch (i, plen))
    7268      6023996 :       switches[i].ordering = 1;
    7269     11111035 : }
    7270              : 
    7271              : /* Inline subroutine of handle_braces.  Process all the currently
    7272              :    marked switches through give_switch, and clear the marks.  */
    7273              : static inline void
    7274      9644017 : process_marked_switches (void)
    7275              : {
    7276      9644017 :   int i;
    7277              : 
    7278    229991224 :   for (i = 0; i < n_switches; i++)
    7279    220347207 :     if (switches[i].ordering == 1)
    7280              :       {
    7281      6023996 :         switches[i].ordering = 0;
    7282      6023996 :         give_switch (i, 0);
    7283              :       }
    7284      9644017 : }
    7285              : 
    7286              : /* Handle a %{ ... } construct.  P points just inside the leading {.
    7287              :    Returns a pointer one past the end of the brace block, or 0
    7288              :    if we call do_spec_1 and that returns -1.  */
    7289              : 
    7290              : static const char *
    7291     40255522 : handle_braces (const char *p)
    7292              : {
    7293     40255522 :   const char *atom, *end_atom;
    7294     40255522 :   const char *d_atom = NULL, *d_end_atom = NULL;
    7295     40255522 :   char *esc_buf = NULL, *d_esc_buf = NULL;
    7296     40255522 :   int esc;
    7297     40255522 :   const char *orig = p;
    7298              : 
    7299     40255522 :   bool a_is_suffix;
    7300     40255522 :   bool a_is_spectype;
    7301     40255522 :   bool a_is_starred;
    7302     40255522 :   bool a_is_negated;
    7303     40255522 :   bool a_matched;
    7304              : 
    7305     40255522 :   bool a_must_be_last = false;
    7306     40255522 :   bool ordered_set    = false;
    7307     40255522 :   bool disjunct_set   = false;
    7308     40255522 :   bool disj_matched   = false;
    7309     40255522 :   bool disj_starred   = true;
    7310     40255522 :   bool n_way_choice   = false;
    7311     40255522 :   bool n_way_matched  = false;
    7312              : 
    7313              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    7314              : 
    7315     53516727 :   do
    7316              :     {
    7317     53516727 :       if (a_must_be_last)
    7318            0 :         goto invalid;
    7319              : 
    7320              :       /* Scan one "atom" (S in the description above of %{}, possibly
    7321              :          with '!', '.', '@', ',', or '*' modifiers).  */
    7322     53516727 :       a_matched = false;
    7323     53516727 :       a_is_suffix = false;
    7324     53516727 :       a_is_starred = false;
    7325     53516727 :       a_is_negated = false;
    7326     53516727 :       a_is_spectype = false;
    7327              : 
    7328     60994239 :       SKIP_WHITE ();
    7329     53516727 :       if (*p == '!')
    7330     12943859 :         p++, a_is_negated = true;
    7331              : 
    7332     53516727 :       SKIP_WHITE ();
    7333     53516727 :       if (*p == '%' && p[1] == ':')
    7334              :         {
    7335      1620622 :           atom = NULL;
    7336      1620622 :           end_atom = NULL;
    7337      1620622 :           p = handle_spec_function (p + 2, &a_matched, NULL);
    7338              :         }
    7339              :       else
    7340              :         {
    7341     51896105 :           if (*p == '.')
    7342            0 :             p++, a_is_suffix = true;
    7343     51896105 :           else if (*p == ',')
    7344            0 :             p++, a_is_spectype = true;
    7345              : 
    7346     51896105 :           atom = p;
    7347     51896105 :           esc = 0;
    7348     51896105 :           while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    7349    391193322 :                  || *p == ',' || *p == '.' || *p == '@' || *p == '\\')
    7350              :             {
    7351    339297217 :               if (*p == '\\')
    7352              :                 {
    7353            0 :                   p++;
    7354            0 :                   if (!*p)
    7355            0 :                     fatal_error (input_location,
    7356              :                                  "braced spec %qs ends in escape", orig);
    7357            0 :                   esc++;
    7358              :                 }
    7359    339297217 :               p++;
    7360              :             }
    7361     51896105 :           end_atom = p;
    7362              : 
    7363     51896105 :           if (esc)
    7364              :             {
    7365            0 :               const char *ap;
    7366            0 :               char *ep;
    7367              : 
    7368            0 :               if (esc_buf && esc_buf != d_esc_buf)
    7369            0 :                 free (esc_buf);
    7370            0 :               esc_buf = NULL;
    7371            0 :               ep = esc_buf = (char *) xmalloc (end_atom - atom - esc + 1);
    7372            0 :               for (ap = atom; ap != end_atom; ap++, ep++)
    7373              :                 {
    7374            0 :                   if (*ap == '\\')
    7375            0 :                     ap++;
    7376            0 :                   *ep = *ap;
    7377              :                 }
    7378            0 :               *ep = '\0';
    7379            0 :               atom = esc_buf;
    7380            0 :               end_atom = ep;
    7381              :             }
    7382              : 
    7383     51896105 :           if (*p == '*')
    7384     11689382 :             p++, a_is_starred = 1;
    7385              :         }
    7386              : 
    7387     53516727 :       SKIP_WHITE ();
    7388     53516727 :       switch (*p)
    7389              :         {
    7390     11111035 :         case '&': case '}':
    7391              :           /* Substitute the switch(es) indicated by the current atom.  */
    7392     11111035 :           ordered_set = true;
    7393     11111035 :           if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
    7394     11111035 :               || a_is_spectype || atom == end_atom)
    7395            0 :             goto invalid;
    7396              : 
    7397     11111035 :           mark_matching_switches (atom, end_atom, a_is_starred);
    7398              : 
    7399     11111035 :           if (*p == '}')
    7400      9644017 :             process_marked_switches ();
    7401              :           break;
    7402              : 
    7403     42405692 :         case '|': case ':':
    7404              :           /* Substitute some text if the current atom appears as a switch
    7405              :              or suffix.  */
    7406     42405692 :           disjunct_set = true;
    7407     42405692 :           if (ordered_set)
    7408            0 :             goto invalid;
    7409              : 
    7410     42405692 :           if (atom && atom == end_atom)
    7411              :             {
    7412      1754046 :               if (!n_way_choice || disj_matched || *p == '|'
    7413      1754046 :                   || a_is_negated || a_is_suffix || a_is_spectype
    7414      1754046 :                   || a_is_starred)
    7415            0 :                 goto invalid;
    7416              : 
    7417              :               /* An empty term may appear as the last choice of an
    7418              :                  N-way choice set; it means "otherwise".  */
    7419      1754046 :               a_must_be_last = true;
    7420      1754046 :               disj_matched = !n_way_matched;
    7421      1754046 :               disj_starred = false;
    7422              :             }
    7423              :           else
    7424              :             {
    7425     40651646 :               if ((a_is_suffix || a_is_spectype) && a_is_starred)
    7426            0 :                 goto invalid;
    7427              : 
    7428     40651646 :               if (!a_is_starred)
    7429     35137168 :                 disj_starred = false;
    7430              : 
    7431              :               /* Don't bother testing this atom if we already have a
    7432              :                  match.  */
    7433     40651646 :               if (!disj_matched && !n_way_matched)
    7434              :                 {
    7435     39642544 :                   if (atom == NULL)
    7436              :                     /* a_matched is already set by handle_spec_function.  */;
    7437     38125547 :                   else if (a_is_suffix)
    7438            0 :                     a_matched = input_suffix_matches (atom, end_atom);
    7439     38125547 :                   else if (a_is_spectype)
    7440            0 :                     a_matched = input_spec_matches (atom, end_atom);
    7441              :                   else
    7442     38125547 :                     a_matched = switch_matches (atom, end_atom, a_is_starred);
    7443              : 
    7444     39642544 :                   if (a_matched != a_is_negated)
    7445              :                     {
    7446     12822687 :                       disj_matched = true;
    7447     12822687 :                       d_atom = atom;
    7448     12822687 :                       d_end_atom = end_atom;
    7449     12822687 :                       d_esc_buf = esc_buf;
    7450              :                     }
    7451              :                 }
    7452              :             }
    7453              : 
    7454     42405692 :           if (*p == ':')
    7455              :             {
    7456              :               /* Found the body, that is, the text to substitute if the
    7457              :                  current disjunction matches.  */
    7458     67175182 :               p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
    7459     33587591 :                                       disj_matched && !n_way_matched);
    7460     33587591 :               if (p == 0)
    7461        35420 :                 goto done;
    7462              : 
    7463              :               /* If we have an N-way choice, reset state for the next
    7464              :                  disjunction.  */
    7465     33552171 :               if (*p == ';')
    7466              :                 {
    7467      2976086 :                   n_way_choice = true;
    7468      2976086 :                   n_way_matched |= disj_matched;
    7469      2976086 :                   disj_matched = false;
    7470      2976086 :                   disj_starred = true;
    7471      2976086 :                   d_atom = d_end_atom = NULL;
    7472              :                 }
    7473              :             }
    7474              :           break;
    7475              : 
    7476            0 :         default:
    7477            0 :           goto invalid;
    7478              :         }
    7479              :     }
    7480     53481307 :   while (*p++ != '}');
    7481              : 
    7482     40220102 :  done:
    7483     40255522 :   if (d_esc_buf && d_esc_buf != esc_buf)
    7484            0 :     free (d_esc_buf);
    7485     40255522 :   if (esc_buf)
    7486            0 :     free (esc_buf);
    7487              : 
    7488     40255522 :   return p;
    7489              : 
    7490            0 :  invalid:
    7491            0 :   fatal_error (input_location, "braced spec %qs is invalid at %qc", orig, *p);
    7492              : 
    7493              : #undef SKIP_WHITE
    7494              : }
    7495              : 
    7496              : /* Subroutine of handle_braces.  Scan and process a brace substitution body
    7497              :    (X in the description of %{} syntax).  P points one past the colon;
    7498              :    ATOM and END_ATOM bracket the first atom which was found to be true
    7499              :    (present) in the current disjunction; STARRED indicates whether all
    7500              :    the atoms in the current disjunction were starred (for syntax validation);
    7501              :    MATCHED indicates whether the disjunction matched or not, and therefore
    7502              :    whether or not the body is to be processed through do_spec_1 or just
    7503              :    skipped.  Returns a pointer to the closing } or ;, or 0 if do_spec_1
    7504              :    returns -1.  */
    7505              : 
    7506              : static const char *
    7507     33587591 : process_brace_body (const char *p, const char *atom, const char *end_atom,
    7508              :                     int starred, int matched)
    7509              : {
    7510     33587591 :   const char *body, *end_body;
    7511     33587591 :   unsigned int nesting_level;
    7512     33587591 :   bool have_subst     = false;
    7513              : 
    7514              :   /* Locate the closing } or ;, honoring nested braces.
    7515              :      Trim trailing whitespace.  */
    7516     33587591 :   body = p;
    7517     33587591 :   nesting_level = 1;
    7518  11366578155 :   for (;;)
    7519              :     {
    7520   5700082873 :       if (*p == '{')
    7521    169833641 :         nesting_level++;
    7522   5530249232 :       else if (*p == '}')
    7523              :         {
    7524    200445146 :           if (!--nesting_level)
    7525              :             break;
    7526              :         }
    7527   5329804086 :       else if (*p == ';' && nesting_level == 1)
    7528              :         break;
    7529   5326828000 :       else if (*p == '%' && p[1] == '*' && nesting_level == 1)
    7530              :         have_subst = true;
    7531   5326052777 :       else if (*p == '\0')
    7532            0 :         goto invalid;
    7533   5666495282 :       p++;
    7534              :     }
    7535              : 
    7536              :   end_body = p;
    7537     36322110 :   while (end_body[-1] == ' ' || end_body[-1] == '\t')
    7538      2734519 :     end_body--;
    7539              : 
    7540     33587591 :   if (have_subst && !starred)
    7541            0 :     goto invalid;
    7542              : 
    7543     33587591 :   if (matched)
    7544              :     {
    7545              :       /* Copy the substitution body to permanent storage and execute it.
    7546              :          If have_subst is false, this is a simple matter of running the
    7547              :          body through do_spec_1...  */
    7548     13768258 :       char *string = save_string (body, end_body - body);
    7549     13768258 :       if (!have_subst)
    7550              :         {
    7551     13761464 :           if (do_spec_1 (string, 0, NULL) < 0)
    7552              :             {
    7553        35420 :               free (string);
    7554        35420 :               return 0;
    7555              :             }
    7556              :         }
    7557              :       else
    7558              :         {
    7559              :           /* ... but if have_subst is true, we have to process the
    7560              :              body once for each matching switch, with %* set to the
    7561              :              variant part of the switch.  */
    7562         6794 :           unsigned int hard_match_len = end_atom - atom;
    7563         6794 :           int i;
    7564              : 
    7565       273898 :           for (i = 0; i < n_switches; i++)
    7566       267104 :             if (!strncmp (switches[i].part1, atom, hard_match_len)
    7567       267104 :                 && check_live_switch (i, hard_match_len))
    7568              :               {
    7569         6798 :                 if (do_spec_1 (string, 0,
    7570              :                                &switches[i].part1[hard_match_len]) < 0)
    7571              :                   {
    7572            0 :                     free (string);
    7573            0 :                     return 0;
    7574              :                   }
    7575              :                 /* Pass any arguments this switch has.  */
    7576         6798 :                 give_switch (i, 1);
    7577         6798 :                 suffix_subst = NULL;
    7578              :               }
    7579              :         }
    7580     13732838 :       free (string);
    7581              :     }
    7582              : 
    7583              :   return p;
    7584              : 
    7585            0 :  invalid:
    7586            0 :   fatal_error (input_location, "braced spec body %qs is invalid", body);
    7587              : }
    7588              : 
    7589              : /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
    7590              :    on the command line.  PREFIX_LENGTH is the length of XXX in an {XXX*}
    7591              :    spec, or -1 if either exact match or %* is used.
    7592              : 
    7593              :    A -O switch is obsoleted by a later -O switch.  A -f, -g, -m, or -W switch
    7594              :    whose value does not begin with "no-" is obsoleted by the same value
    7595              :    with the "no-", similarly for a switch with the "no-" prefix.  */
    7596              : 
    7597              : static int
    7598      7439531 : check_live_switch (int switchnum, int prefix_length)
    7599              : {
    7600      7439531 :   const char *name = switches[switchnum].part1;
    7601      7439531 :   int i;
    7602              : 
    7603              :   /* If we already processed this switch and determined if it was
    7604              :      live or not, return our past determination.  */
    7605      7439531 :   if (switches[switchnum].live_cond != 0)
    7606       939325 :     return ((switches[switchnum].live_cond & SWITCH_LIVE) != 0
    7607       893360 :             && (switches[switchnum].live_cond & SWITCH_FALSE) == 0
    7608      1832685 :             && (switches[switchnum].live_cond & SWITCH_IGNORE_PERMANENTLY)
    7609       939325 :                == 0);
    7610              : 
    7611              :   /* In the common case of {<at-most-one-letter>*}, a negating
    7612              :      switch would always match, so ignore that case.  We will just
    7613              :      send the conflicting switches to the compiler phase.  */
    7614      6500206 :   if (prefix_length >= 0 && prefix_length <= 1)
    7615              :     return 1;
    7616              : 
    7617              :   /* Now search for duplicate in a manner that depends on the name.  */
    7618       872603 :   switch (*name)
    7619              :     {
    7620           62 :     case 'O':
    7621          344 :       for (i = switchnum + 1; i < n_switches; i++)
    7622          287 :         if (switches[i].part1[0] == 'O')
    7623              :           {
    7624            5 :             switches[switchnum].validated = true;
    7625            5 :             switches[switchnum].live_cond = SWITCH_FALSE;
    7626            5 :             return 0;
    7627              :           }
    7628              :       break;
    7629              : 
    7630       274434 :     case 'W':  case 'f':  case 'm': case 'g':
    7631       274434 :       if (startswith (name + 1, "no-"))
    7632              :         {
    7633              :           /* We have Xno-YYY, search for XYYY.  */
    7634        35155 :           for (i = switchnum + 1; i < n_switches; i++)
    7635        29550 :             if (switches[i].part1[0] == name[0]
    7636         5641 :                 && ! strcmp (&switches[i].part1[1], &name[4]))
    7637              :               {
    7638              :                 /* --specs are validated with the validate_switches mechanism.  */
    7639            0 :                 if (switches[switchnum].known)
    7640            0 :                   switches[switchnum].validated = true;
    7641            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7642            0 :                 return 0;
    7643              :               }
    7644              :         }
    7645              :       else
    7646              :         {
    7647              :           /* We have XYYY, search for Xno-YYY.  */
    7648      2840277 :           for (i = switchnum + 1; i < n_switches; i++)
    7649      2571448 :             if (switches[i].part1[0] == name[0]
    7650      1560329 :                 && switches[i].part1[1] == 'n'
    7651       196427 :                 && switches[i].part1[2] == 'o'
    7652       196426 :                 && switches[i].part1[3] == '-'
    7653       196396 :                 && !strcmp (&switches[i].part1[4], &name[1]))
    7654              :               {
    7655              :                 /* --specs are validated with the validate_switches mechanism.  */
    7656            0 :                 if (switches[switchnum].known)
    7657            0 :                   switches[switchnum].validated = true;
    7658            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7659            0 :                 return 0;
    7660              :               }
    7661              :         }
    7662              :       break;
    7663              :     }
    7664              : 
    7665              :   /* Otherwise the switch is live.  */
    7666       872598 :   switches[switchnum].live_cond |= SWITCH_LIVE;
    7667       872598 :   return 1;
    7668              : }
    7669              : 
    7670              : /* Pass a switch to the current accumulating command
    7671              :    in the same form that we received it.
    7672              :    SWITCHNUM identifies the switch; it is an index into
    7673              :    the vector of switches gcc received, which is `switches'.
    7674              :    This cannot fail since it never finishes a command line.
    7675              : 
    7676              :    If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.  */
    7677              : 
    7678              : static void
    7679      6030794 : give_switch (int switchnum, int omit_first_word)
    7680              : {
    7681      6030794 :   if ((switches[switchnum].live_cond & SWITCH_IGNORE) != 0)
    7682              :     return;
    7683              : 
    7684      6030783 :   if (!omit_first_word)
    7685              :     {
    7686      6023985 :       do_spec_1 ("-", 0, NULL);
    7687      6023985 :       do_spec_1 (switches[switchnum].part1, 1, NULL);
    7688              :     }
    7689              : 
    7690      6030783 :   if (switches[switchnum].args != 0)
    7691              :     {
    7692              :       const char **p;
    7693      2461976 :       for (p = switches[switchnum].args; *p; p++)
    7694              :         {
    7695      1230988 :           const char *arg = *p;
    7696              : 
    7697      1230988 :           do_spec_1 (" ", 0, NULL);
    7698      1230988 :           if (suffix_subst)
    7699              :             {
    7700         5931 :               unsigned length = strlen (arg);
    7701         5931 :               int dot = 0;
    7702              : 
    7703        11862 :               while (length-- && !IS_DIR_SEPARATOR (arg[length]))
    7704        11862 :                 if (arg[length] == '.')
    7705              :                   {
    7706         5931 :                     (const_cast<char *> (arg))[length] = 0;
    7707         5931 :                     dot = 1;
    7708         5931 :                     break;
    7709              :                   }
    7710         5931 :               do_spec_1 (arg, 1, NULL);
    7711         5931 :               if (dot)
    7712         5931 :                 (const_cast<char *> (arg))[length] = '.';
    7713         5931 :               do_spec_1 (suffix_subst, 1, NULL);
    7714              :             }
    7715              :           else
    7716      1225057 :             do_spec_1 (arg, 1, NULL);
    7717              :         }
    7718              :     }
    7719              : 
    7720      6030783 :   do_spec_1 (" ", 0, NULL);
    7721      6030783 :   switches[switchnum].validated = true;
    7722              : }
    7723              : 
    7724              : /* Print GCC configuration (e.g. version, thread model, target,
    7725              :    configuration_arguments) to a given FILE.  */
    7726              : 
    7727              : static void
    7728         1547 : print_configuration (FILE *file)
    7729              : {
    7730         1547 :   int n;
    7731         1547 :   const char *thrmod;
    7732              : 
    7733         1547 :   fnotice (file, "Target: %s\n", spec_machine);
    7734         1547 :   fnotice (file, "Configured with: %s\n", configuration_arguments);
    7735              : 
    7736              : #ifdef THREAD_MODEL_SPEC
    7737              :   /* We could have defined THREAD_MODEL_SPEC to "%*" by default,
    7738              :   but there's no point in doing all this processing just to get
    7739              :   thread_model back.  */
    7740              :   obstack_init (&obstack);
    7741              :   do_spec_1 (THREAD_MODEL_SPEC, 0, thread_model);
    7742              :   obstack_1grow (&obstack, '\0');
    7743              :   thrmod = XOBFINISH (&obstack, const char *);
    7744              : #else
    7745         1547 :   thrmod = thread_model;
    7746              : #endif
    7747              : 
    7748         1547 :   fnotice (file, "Thread model: %s\n", thrmod);
    7749         1547 :   fnotice (file, "Supported LTO compression algorithms: zlib");
    7750              : #ifdef HAVE_ZSTD_H
    7751         1547 :   fnotice (file, " zstd");
    7752              : #endif
    7753         1547 :   fnotice (file, "\n");
    7754              : 
    7755              :   /* compiler_version is truncated at the first space when initialized
    7756              :   from version string, so truncate version_string at the first space
    7757              :   before comparing.  */
    7758        12376 :   for (n = 0; version_string[n]; n++)
    7759        10829 :     if (version_string[n] == ' ')
    7760              :       break;
    7761              : 
    7762         1547 :   if (! strncmp (version_string, compiler_version, n)
    7763         1547 :       && compiler_version[n] == 0)
    7764         1547 :     fnotice (file, "gcc version %s %s\n", version_string,
    7765              :              pkgversion_string);
    7766              :   else
    7767            0 :     fnotice (file, "gcc driver version %s %sexecuting gcc version %s\n",
    7768              :              version_string, pkgversion_string, compiler_version);
    7769              : 
    7770         1547 : }
    7771              : 
    7772              : #define RETRY_ICE_ATTEMPTS 3
    7773              : 
    7774              : /* Returns true if FILE1 and FILE2 contain equivalent data, 0 otherwise.
    7775              :    If lines start with 0x followed by 1-16 lowercase hexadecimal digits
    7776              :    followed by a space, ignore anything before that space.  These are
    7777              :    typically function addresses from libbacktrace and those can differ
    7778              :    due to ASLR.  */
    7779              : 
    7780              : static bool
    7781            0 : files_equal_p (char *file1, char *file2)
    7782              : {
    7783            0 :   FILE *f1 = fopen (file1, "rb");
    7784            0 :   FILE *f2 = fopen (file2, "rb");
    7785            0 :   char line1[256], line2[256];
    7786              : 
    7787            0 :   bool line_start = true;
    7788            0 :   while (fgets (line1, sizeof (line1), f1))
    7789              :     {
    7790            0 :       if (!fgets (line2, sizeof (line2), f2))
    7791            0 :         goto error;
    7792            0 :       char *p1 = line1, *p2 = line2;
    7793            0 :       if (line_start
    7794            0 :           && line1[0] == '0'
    7795            0 :           && line1[1] == 'x'
    7796            0 :           && line2[0] == '0'
    7797            0 :           && line2[1] == 'x')
    7798              :         {
    7799              :           int i, j;
    7800            0 :           for (i = 0; i < 16; ++i)
    7801            0 :             if (!ISXDIGIT (line1[2 + i]) || ISUPPER (line1[2 + i]))
    7802              :               break;
    7803            0 :           for (j = 0; j < 16; ++j)
    7804            0 :             if (!ISXDIGIT (line2[2 + j]) || ISUPPER (line2[2 + j]))
    7805              :               break;
    7806            0 :           if (i && line1[2 + i] == ' ' && j && line2[2 + j] == ' ')
    7807              :             {
    7808            0 :               p1 = line1 + i + 3;
    7809            0 :               p2 = line2 + j + 3;
    7810              :             }
    7811              :         }
    7812            0 :       if (strcmp (p1, p2) != 0)
    7813            0 :         goto error;
    7814            0 :       line_start = strchr (line1, '\n') != NULL;
    7815              :     }
    7816            0 :   if (fgets (line2, sizeof (line2), f2))
    7817            0 :     goto error;
    7818              : 
    7819            0 :   fclose (f1);
    7820            0 :   fclose (f2);
    7821            0 :   return 1;
    7822              : 
    7823            0 : error:
    7824            0 :   fclose (f1);
    7825            0 :   fclose (f2);
    7826            0 :   return 0;
    7827              : }
    7828              : 
    7829              : /* Check that compiler's output doesn't differ across runs.
    7830              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are arrays of files, containing
    7831              :    stdout and stderr for each compiler run.  Return true if all of
    7832              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are equivalent.  */
    7833              : 
    7834              : static bool
    7835            0 : check_repro (char **temp_stdout_files, char **temp_stderr_files)
    7836              : {
    7837            0 :   int i;
    7838            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS - 2; ++i)
    7839              :     {
    7840            0 :      if (!files_equal_p (temp_stdout_files[i], temp_stdout_files[i + 1])
    7841            0 :          || !files_equal_p (temp_stderr_files[i], temp_stderr_files[i + 1]))
    7842              :        {
    7843            0 :          fnotice (stderr, "The bug is not reproducible, so it is"
    7844              :                   " likely a hardware or OS problem.\n");
    7845            0 :          break;
    7846              :        }
    7847              :     }
    7848            0 :   return i == RETRY_ICE_ATTEMPTS - 2;
    7849              : }
    7850              : 
    7851              : enum attempt_status {
    7852              :   ATTEMPT_STATUS_FAIL_TO_RUN,
    7853              :   ATTEMPT_STATUS_SUCCESS,
    7854              :   ATTEMPT_STATUS_ICE
    7855              : };
    7856              : 
    7857              : 
    7858              : /* Run compiler with arguments NEW_ARGV to reproduce the ICE, storing stdout
    7859              :    to OUT_TEMP and stderr to ERR_TEMP.  If APPEND is TRUE, append to OUT_TEMP
    7860              :    and ERR_TEMP instead of truncating.  If EMIT_SYSTEM_INFO is TRUE, also write
    7861              :    GCC configuration into to ERR_TEMP.  Return ATTEMPT_STATUS_FAIL_TO_RUN if
    7862              :    compiler failed to run, ATTEMPT_STATUS_ICE if compiled ICE-ed and
    7863              :    ATTEMPT_STATUS_SUCCESS otherwise.  */
    7864              : 
    7865              : static enum attempt_status
    7866            0 : run_attempt (const char **new_argv, const char *out_temp,
    7867              :              const char *err_temp, int emit_system_info, int append)
    7868              : {
    7869              : 
    7870            0 :   if (emit_system_info)
    7871              :     {
    7872            0 :       FILE *file_out = fopen (err_temp, "a");
    7873            0 :       print_configuration (file_out);
    7874            0 :       fputs ("\n", file_out);
    7875            0 :       fclose (file_out);
    7876              :     }
    7877              : 
    7878            0 :   int exit_status;
    7879            0 :   const char *errmsg;
    7880            0 :   struct pex_obj *pex;
    7881            0 :   int err;
    7882            0 :   int pex_flags = PEX_USE_PIPES | PEX_LAST;
    7883            0 :   enum attempt_status status = ATTEMPT_STATUS_FAIL_TO_RUN;
    7884              : 
    7885            0 :   if (append)
    7886            0 :     pex_flags |= PEX_STDOUT_APPEND | PEX_STDERR_APPEND;
    7887              : 
    7888            0 :   pex = pex_init (PEX_USE_PIPES, new_argv[0], NULL);
    7889            0 :   if (!pex)
    7890              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    7891              : 
    7892            0 :   errmsg = pex_run (pex, pex_flags, new_argv[0],
    7893            0 :                     const_cast<char *const *> (&new_argv[1]),
    7894              :                     out_temp, err_temp, &err);
    7895            0 :   if (errmsg != NULL)
    7896              :     {
    7897            0 :       errno = err;
    7898            0 :       fatal_error (input_location,
    7899              :                    err ? G_ ("cannot execute %qs: %s: %m")
    7900              :                    : G_ ("cannot execute %qs: %s"),
    7901              :                    new_argv[0], errmsg);
    7902              :     }
    7903              : 
    7904            0 :   if (!pex_get_status (pex, 1, &exit_status))
    7905            0 :     goto out;
    7906              : 
    7907            0 :   switch (WEXITSTATUS (exit_status))
    7908              :     {
    7909              :       case ICE_EXIT_CODE:
    7910            0 :         status = ATTEMPT_STATUS_ICE;
    7911              :         break;
    7912              : 
    7913            0 :       case SUCCESS_EXIT_CODE:
    7914            0 :         status = ATTEMPT_STATUS_SUCCESS;
    7915            0 :         break;
    7916              : 
    7917            0 :       default:
    7918            0 :         ;
    7919              :     }
    7920              : 
    7921            0 : out:
    7922            0 :   pex_free (pex);
    7923            0 :   return status;
    7924              : }
    7925              : 
    7926              : /* This routine reads lines from IN file, adds C++ style comments
    7927              :    at the beginning of each line and writes result into OUT.  */
    7928              : 
    7929              : static void
    7930            0 : insert_comments (const char *file_in, const char *file_out)
    7931              : {
    7932            0 :   FILE *in = fopen (file_in, "rb");
    7933            0 :   FILE *out = fopen (file_out, "wb");
    7934            0 :   char line[256];
    7935              : 
    7936            0 :   bool add_comment = true;
    7937            0 :   while (fgets (line, sizeof (line), in))
    7938              :     {
    7939            0 :       if (add_comment)
    7940            0 :         fputs ("// ", out);
    7941            0 :       fputs (line, out);
    7942            0 :       add_comment = strchr (line, '\n') != NULL;
    7943              :     }
    7944              : 
    7945            0 :   fclose (in);
    7946            0 :   fclose (out);
    7947            0 : }
    7948              : 
    7949              : /* This routine adds preprocessed source code into the given ERR_FILE.
    7950              :    To do this, it adds "-E" to NEW_ARGV and execute RUN_ATTEMPT routine to
    7951              :    add information in report file.  RUN_ATTEMPT should return
    7952              :    ATTEMPT_STATUS_SUCCESS, in other case we cannot generate the report.  */
    7953              : 
    7954              : static void
    7955            0 : do_report_bug (const char **new_argv, const int nargs,
    7956              :                char **out_file, char **err_file)
    7957              : {
    7958            0 :   int i, status;
    7959            0 :   int fd = open (*out_file, O_RDWR | O_APPEND);
    7960            0 :   if (fd < 0)
    7961              :     return;
    7962            0 :   write (fd, "\n//", 3);
    7963            0 :   for (i = 0; i < nargs; i++)
    7964              :     {
    7965            0 :       write (fd, " ", 1);
    7966            0 :       write (fd, new_argv[i], strlen (new_argv[i]));
    7967              :     }
    7968            0 :   write (fd, "\n\n", 2);
    7969            0 :   close (fd);
    7970            0 :   new_argv[nargs] = "-E";
    7971            0 :   new_argv[nargs + 1] = NULL;
    7972              : 
    7973            0 :   status = run_attempt (new_argv, *out_file, *err_file, 0, 1);
    7974              : 
    7975            0 :   if (status == ATTEMPT_STATUS_SUCCESS)
    7976              :     {
    7977            0 :       fnotice (stderr, "Preprocessed source stored into %s file,"
    7978              :                " please attach this to your bugreport.\n", *out_file);
    7979              :       /* Make sure it is not deleted.  */
    7980            0 :       free (*out_file);
    7981            0 :       *out_file = NULL;
    7982              :     }
    7983              : }
    7984              : 
    7985              : /* Try to reproduce ICE.  If bug is reproducible, generate report .err file
    7986              :    containing GCC configuration, backtrace, compiler's command line options
    7987              :    and preprocessed source code.  */
    7988              : 
    7989              : static void
    7990            0 : try_generate_repro (const char **argv)
    7991              : {
    7992            0 :   int i, nargs, out_arg = -1, quiet = 0, attempt;
    7993            0 :   const char **new_argv;
    7994            0 :   char *temp_files[RETRY_ICE_ATTEMPTS * 2];
    7995            0 :   char **temp_stdout_files = &temp_files[0];
    7996            0 :   char **temp_stderr_files = &temp_files[RETRY_ICE_ATTEMPTS];
    7997              : 
    7998            0 :   if (gcc_input_filename == NULL || ! strcmp (gcc_input_filename, "-"))
    7999            0 :     return;
    8000              : 
    8001            0 :   for (nargs = 0; argv[nargs] != NULL; ++nargs)
    8002              :     /* Only retry compiler ICEs, not preprocessor ones.  */
    8003            0 :     if (! strcmp (argv[nargs], "-E"))
    8004              :       return;
    8005            0 :     else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o')
    8006              :       {
    8007            0 :         if (out_arg == -1)
    8008              :           out_arg = nargs;
    8009              :         else
    8010              :           return;
    8011              :       }
    8012              :     /* If the compiler is going to output any time information,
    8013              :        it might varry between invocations.  */
    8014            0 :     else if (! strcmp (argv[nargs], "-quiet"))
    8015              :       quiet = 1;
    8016            0 :     else if (! strcmp (argv[nargs], "-ftime-report"))
    8017              :       return;
    8018              : 
    8019            0 :   if (out_arg == -1 || !quiet)
    8020              :     return;
    8021              : 
    8022            0 :   memset (temp_files, '\0', sizeof (temp_files));
    8023            0 :   new_argv = XALLOCAVEC (const char *, nargs + 4);
    8024            0 :   memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *));
    8025            0 :   new_argv[nargs++] = "-frandom-seed=0";
    8026            0 :   new_argv[nargs++] = "-fdump-noaddr";
    8027            0 :   new_argv[nargs] = NULL;
    8028            0 :   if (new_argv[out_arg][2] == '\0')
    8029            0 :     new_argv[out_arg + 1] = "-";
    8030              :   else
    8031            0 :     new_argv[out_arg] = "-o-";
    8032              : 
    8033              : #ifdef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
    8034            0 :   personality (personality (0xffffffffU) | ADDR_NO_RANDOMIZE);
    8035              : #endif
    8036              : 
    8037            0 :   int status;
    8038            0 :   for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS; ++attempt)
    8039              :     {
    8040            0 :       int emit_system_info = 0;
    8041            0 :       int append = 0;
    8042            0 :       temp_stdout_files[attempt] = make_temp_file (".out");
    8043            0 :       temp_stderr_files[attempt] = make_temp_file (".err");
    8044              : 
    8045            0 :       if (attempt == RETRY_ICE_ATTEMPTS - 1)
    8046              :         {
    8047            0 :           append = 1;
    8048            0 :           emit_system_info = 1;
    8049              :         }
    8050              : 
    8051            0 :       status = run_attempt (new_argv, temp_stdout_files[attempt],
    8052              :                             temp_stderr_files[attempt], emit_system_info,
    8053              :                             append);
    8054              : 
    8055            0 :       if (status != ATTEMPT_STATUS_ICE)
    8056              :         {
    8057            0 :           fnotice (stderr, "The bug is not reproducible, so it is"
    8058              :                    " likely a hardware or OS problem.\n");
    8059            0 :           goto out;
    8060              :         }
    8061              :     }
    8062              : 
    8063            0 :   if (!check_repro (temp_stdout_files, temp_stderr_files))
    8064            0 :     goto out;
    8065              : 
    8066            0 :   {
    8067              :     /* Insert commented out backtrace into report file.  */
    8068            0 :     char **stderr_commented = &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1];
    8069            0 :     insert_comments (temp_stderr_files[RETRY_ICE_ATTEMPTS - 1],
    8070              :                      *stderr_commented);
    8071              : 
    8072              :     /* In final attempt we append compiler options and preprocesssed code to last
    8073              :        generated .out file with configuration and backtrace.  */
    8074            0 :     char **err = &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1];
    8075            0 :     do_report_bug (new_argv, nargs, stderr_commented, err);
    8076              :   }
    8077              : 
    8078              : out:
    8079            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS * 2; i++)
    8080            0 :     if (temp_files[i])
    8081              :       {
    8082            0 :         unlink (temp_stdout_files[i]);
    8083            0 :         free (temp_stdout_files[i]);
    8084              :       }
    8085              : }
    8086              : 
    8087              : /* Search for a file named NAME trying various prefixes including the
    8088              :    user's -B prefix and some standard ones.
    8089              :    Return the absolute file name found.  If nothing is found, return NAME.  */
    8090              : 
    8091              : static const char *
    8092       540791 : find_file (const char *name)
    8093              : {
    8094       540791 :   char *newname = find_a_file (&startfile_prefixes, name, R_OK, true);
    8095       540791 :   return newname ? newname : name;
    8096              : }
    8097              : 
    8098              : /* Determine whether a directory exists.  */
    8099              : 
    8100              : static int
    8101     10290454 : is_directory (const char *path1)
    8102              : {
    8103     10290454 :   int len1;
    8104     10290454 :   char *path;
    8105     10290454 :   char *cp;
    8106     10290454 :   struct stat st;
    8107              : 
    8108              :   /* Ensure the string ends with "/.".  The resulting path will be a
    8109              :      directory even if the given path is a symbolic link.  */
    8110     10290454 :   len1 = strlen (path1);
    8111     10290454 :   path = (char *) alloca (3 + len1);
    8112     10290454 :   memcpy (path, path1, len1);
    8113     10290454 :   cp = path + len1;
    8114     10290454 :   if (!IS_DIR_SEPARATOR (cp[-1]))
    8115      1484002 :     *cp++ = DIR_SEPARATOR;
    8116     10290454 :   *cp++ = '.';
    8117     10290454 :   *cp = '\0';
    8118              : 
    8119     10290454 :   return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
    8120              : }
    8121              : 
    8122              : /* Set up the various global variables to indicate that we're processing
    8123              :    the input file named FILENAME.  */
    8124              : 
    8125              : void
    8126       826905 : set_input (const char *filename)
    8127              : {
    8128       826905 :   const char *p;
    8129              : 
    8130       826905 :   gcc_input_filename = filename;
    8131       826905 :   input_filename_length = strlen (gcc_input_filename);
    8132       826905 :   input_basename = lbasename (gcc_input_filename);
    8133              : 
    8134              :   /* Find a suffix starting with the last period,
    8135              :      and set basename_length to exclude that suffix.  */
    8136       826905 :   basename_length = strlen (input_basename);
    8137       826905 :   suffixed_basename_length = basename_length;
    8138       826905 :   p = input_basename + basename_length;
    8139      3633400 :   while (p != input_basename && *p != '.')
    8140      2806495 :     --p;
    8141       826905 :   if (*p == '.' && p != input_basename)
    8142              :     {
    8143       592575 :       basename_length = p - input_basename;
    8144       592575 :       input_suffix = p + 1;
    8145              :     }
    8146              :   else
    8147       234330 :     input_suffix = "";
    8148              : 
    8149              :   /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then
    8150              :      we will need to do a stat on the gcc_input_filename.  The
    8151              :      INPUT_STAT_SET signals that the stat is needed.  */
    8152       826905 :   input_stat_set = 0;
    8153       826905 : }
    8154              : 
    8155              : /* On fatal signals, delete all the temporary files.  */
    8156              : 
    8157              : static void
    8158            0 : fatal_signal (int signum)
    8159              : {
    8160            0 :   signal (signum, SIG_DFL);
    8161            0 :   delete_failure_queue ();
    8162            0 :   delete_temp_files ();
    8163              :   /* Get the same signal again, this time not handled,
    8164              :      so its normal effect occurs.  */
    8165            0 :   kill (getpid (), signum);
    8166            0 : }
    8167              : 
    8168              : /* Compare the contents of the two files named CMPFILE[0] and
    8169              :    CMPFILE[1].  Return zero if they're identical, nonzero
    8170              :    otherwise.  */
    8171              : 
    8172              : static int
    8173          613 : compare_files (char *cmpfile[])
    8174              : {
    8175          613 :   int ret = 0;
    8176          613 :   FILE *temp[2] = { NULL, NULL };
    8177          613 :   int i;
    8178              : 
    8179              : #if HAVE_MMAP_FILE
    8180          613 :   {
    8181          613 :     size_t length[2];
    8182          613 :     void *map[2] = { NULL, NULL };
    8183              : 
    8184         1839 :     for (i = 0; i < 2; i++)
    8185              :       {
    8186         1226 :         struct stat st;
    8187              : 
    8188         1226 :         if (stat (cmpfile[i], &st) < 0 || !S_ISREG (st.st_mode))
    8189              :           {
    8190            0 :             error ("%s: could not determine length of compare-debug file %s",
    8191              :                    gcc_input_filename, cmpfile[i]);
    8192            0 :             ret = 1;
    8193            0 :             break;
    8194              :           }
    8195              : 
    8196         1226 :         length[i] = st.st_size;
    8197              :       }
    8198              : 
    8199          613 :     if (!ret && length[0] != length[1])
    8200              :       {
    8201           14 :         error ("%s: %<-fcompare-debug%> failure (length)", gcc_input_filename);
    8202           14 :         ret = 1;
    8203              :       }
    8204              : 
    8205           14 :     if (!ret)
    8206         1735 :       for (i = 0; i < 2; i++)
    8207              :         {
    8208         1167 :           int fd = open (cmpfile[i], O_RDONLY);
    8209         1167 :           if (fd < 0)
    8210              :             {
    8211            0 :               error ("%s: could not open compare-debug file %s",
    8212              :                      gcc_input_filename, cmpfile[i]);
    8213            0 :               ret = 1;
    8214            0 :               break;
    8215              :             }
    8216              : 
    8217         1167 :           map[i] = mmap (NULL, length[i], PROT_READ, MAP_PRIVATE, fd, 0);
    8218         1167 :           close (fd);
    8219              : 
    8220         1167 :           if (map[i] == (void *) MAP_FAILED)
    8221              :             {
    8222              :               ret = -1;
    8223              :               break;
    8224              :             }
    8225              :         }
    8226              : 
    8227          599 :     if (!ret)
    8228              :       {
    8229          568 :         if (memcmp (map[0], map[1], length[0]) != 0)
    8230              :           {
    8231            0 :             error ("%s: %<-fcompare-debug%> failure", gcc_input_filename);
    8232            0 :             ret = 1;
    8233              :           }
    8234              :       }
    8235              : 
    8236         1839 :     for (i = 0; i < 2; i++)
    8237         1226 :       if (map[i])
    8238         1167 :         munmap ((caddr_t) map[i], length[i]);
    8239              : 
    8240          613 :     if (ret >= 0)
    8241          582 :       return ret;
    8242              : 
    8243           31 :     ret = 0;
    8244              :   }
    8245              : #endif
    8246              : 
    8247           93 :   for (i = 0; i < 2; i++)
    8248              :     {
    8249           62 :       temp[i] = fopen (cmpfile[i], "r");
    8250           62 :       if (!temp[i])
    8251              :         {
    8252            0 :           error ("%s: could not open compare-debug file %s",
    8253              :                  gcc_input_filename, cmpfile[i]);
    8254            0 :           ret = 1;
    8255            0 :           break;
    8256              :         }
    8257              :     }
    8258              : 
    8259           31 :   if (!ret && temp[0] && temp[1])
    8260           31 :     for (;;)
    8261              :       {
    8262           31 :         int c0, c1;
    8263           31 :         c0 = fgetc (temp[0]);
    8264           31 :         c1 = fgetc (temp[1]);
    8265              : 
    8266           31 :         if (c0 != c1)
    8267              :           {
    8268            0 :             error ("%s: %<-fcompare-debug%> failure",
    8269              :                    gcc_input_filename);
    8270            0 :             ret = 1;
    8271            0 :             break;
    8272              :           }
    8273              : 
    8274           31 :         if (c0 == EOF)
    8275              :           break;
    8276              :       }
    8277              : 
    8278           93 :   for (i = 1; i >= 0; i--)
    8279              :     {
    8280           62 :       if (temp[i])
    8281           62 :         fclose (temp[i]);
    8282              :     }
    8283              : 
    8284              :   return ret;
    8285              : }
    8286              : 
    8287       293985 : driver::driver (bool can_finalize, bool debug) :
    8288       293985 :   explicit_link_files (NULL),
    8289       293985 :   decoded_options (NULL)
    8290              : {
    8291       293985 :   env.init (can_finalize, debug);
    8292       293985 : }
    8293              : 
    8294       293503 : driver::~driver ()
    8295              : {
    8296       293503 :   XDELETEVEC (explicit_link_files);
    8297       293503 :   XDELETEVEC (decoded_options);
    8298       293503 : }
    8299              : 
    8300              : /* driver::main is implemented as a series of driver:: method calls.  */
    8301              : 
    8302              : int
    8303       293985 : driver::main (int argc, char **argv)
    8304              : {
    8305       293985 :   bool early_exit;
    8306              : 
    8307       293985 :   set_progname (argv[0]);
    8308       293985 :   expand_at_files (&argc, &argv);
    8309       293985 :   decode_argv (argc, const_cast <const char **> (argv));
    8310       293985 :   global_initializations ();
    8311       293985 :   build_multilib_strings ();
    8312       293985 :   set_up_specs ();
    8313       293698 :   putenv_COLLECT_AS_OPTIONS (assembler_options);
    8314       293698 :   putenv_COLLECT_GCC (argv[0]);
    8315       293698 :   maybe_putenv_COLLECT_LTO_WRAPPER ();
    8316       293698 :   maybe_putenv_OFFLOAD_TARGETS ();
    8317       293698 :   handle_unrecognized_options ();
    8318              : 
    8319       293698 :   if (completion)
    8320              :     {
    8321            5 :       m_option_proposer.suggest_completion (completion);
    8322            5 :       return 0;
    8323              :     }
    8324              : 
    8325       293693 :   if (!maybe_print_and_exit ())
    8326              :     return 0;
    8327              : 
    8328       281675 :   early_exit = prepare_infiles ();
    8329       281481 :   if (early_exit)
    8330          445 :     return get_exit_code ();
    8331              : 
    8332       281036 :   do_spec_on_infiles ();
    8333       281036 :   maybe_run_linker (argv[0]);
    8334       281036 :   final_actions ();
    8335       281036 :   return get_exit_code ();
    8336              : }
    8337              : 
    8338              : /* Locate the final component of argv[0] after any leading path, and set
    8339              :    the program name accordingly.  */
    8340              : 
    8341              : void
    8342       293985 : driver::set_progname (const char *argv0) const
    8343              : {
    8344       293985 :   const char *p = argv0 + strlen (argv0);
    8345      1630963 :   while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
    8346      1336978 :     --p;
    8347       293985 :   progname = p;
    8348              : 
    8349       293985 :   xmalloc_set_program_name (progname);
    8350       293985 : }
    8351              : 
    8352              : /* Expand any @ files within the command-line args,
    8353              :    setting at_file_supplied if any were expanded.  */
    8354              : 
    8355              : void
    8356       293985 : driver::expand_at_files (int *argc, char ***argv) const
    8357              : {
    8358       293985 :   char **old_argv = *argv;
    8359              : 
    8360       293985 :   expandargv (argc, argv);
    8361              : 
    8362              :   /* Determine if any expansions were made.  */
    8363       293985 :   if (*argv != old_argv)
    8364        12286 :     at_file_supplied = true;
    8365       293985 : }
    8366              : 
    8367              : /* Decode the command-line arguments from argc/argv into the
    8368              :    decoded_options array.  */
    8369              : 
    8370              : void
    8371       293985 : driver::decode_argv (int argc, const char **argv)
    8372              : {
    8373       293985 :   init_opts_obstack ();
    8374       293985 :   init_options_struct (&global_options, &global_options_set);
    8375              : 
    8376       293985 :   decode_cmdline_options_to_array (argc, argv,
    8377              :                                    CL_DRIVER,
    8378              :                                    &decoded_options, &decoded_options_count);
    8379       293985 : }
    8380              : 
    8381              : /* Perform various initializations and setup.  */
    8382              : 
    8383              : void
    8384       293985 : driver::global_initializations ()
    8385              : {
    8386              :   /* Unlock the stdio streams.  */
    8387       293985 :   unlock_std_streams ();
    8388              : 
    8389       293985 :   gcc_init_libintl ();
    8390              : 
    8391       293985 :   diagnostic_initialize (global_dc, 0);
    8392       293985 :   diagnostic_color_init (global_dc);
    8393       293985 :   diagnostic_urls_init (global_dc);
    8394       293985 :   global_dc->push_owned_urlifier (make_gcc_urlifier (0));
    8395              : 
    8396              : #ifdef GCC_DRIVER_HOST_INITIALIZATION
    8397              :   /* Perform host dependent initialization when needed.  */
    8398              :   GCC_DRIVER_HOST_INITIALIZATION;
    8399              : #endif
    8400              : 
    8401       293985 :   if (atexit (delete_temp_files) != 0)
    8402            0 :     fatal_error (input_location, "atexit failed");
    8403              : 
    8404       293985 :   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
    8405       293834 :     signal (SIGINT, fatal_signal);
    8406              : #ifdef SIGHUP
    8407       293985 :   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
    8408        21362 :     signal (SIGHUP, fatal_signal);
    8409              : #endif
    8410       293985 :   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
    8411       293985 :     signal (SIGTERM, fatal_signal);
    8412              : #ifdef SIGPIPE
    8413       293985 :   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
    8414       293985 :     signal (SIGPIPE, fatal_signal);
    8415              : #endif
    8416              : #ifdef SIGCHLD
    8417              :   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
    8418              :      receive the signal.  A different setting is inheritable */
    8419       293985 :   signal (SIGCHLD, SIG_DFL);
    8420              : #endif
    8421              : 
    8422              :   /* Parsing and gimplification sometimes need quite large stack.
    8423              :      Increase stack size limits if possible.  */
    8424       293985 :   stack_limit_increase (64 * 1024 * 1024);
    8425              : 
    8426              :   /* Allocate the argument vector.  */
    8427       293985 :   alloc_args ();
    8428              : 
    8429       293985 :   obstack_init (&obstack);
    8430       293985 : }
    8431              : 
    8432              : /* Build multilib_select, et. al from the separate lines that make up each
    8433              :    multilib selection.  */
    8434              : 
    8435              : void
    8436       293985 : driver::build_multilib_strings () const
    8437              : {
    8438       293985 :   {
    8439       293985 :     const char *p;
    8440       293985 :     const char *const *q = multilib_raw;
    8441       293985 :     int need_space;
    8442              : 
    8443       293985 :     obstack_init (&multilib_obstack);
    8444       293985 :     while ((p = *q++) != (char *) 0)
    8445      1175940 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8446              : 
    8447       293985 :     obstack_1grow (&multilib_obstack, 0);
    8448       293985 :     multilib_select = XOBFINISH (&multilib_obstack, const char *);
    8449              : 
    8450       293985 :     q = multilib_matches_raw;
    8451       293985 :     while ((p = *q++) != (char *) 0)
    8452       881955 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8453              : 
    8454       293985 :     obstack_1grow (&multilib_obstack, 0);
    8455       293985 :     multilib_matches = XOBFINISH (&multilib_obstack, const char *);
    8456              : 
    8457       293985 :     q = multilib_exclusions_raw;
    8458       293985 :     while ((p = *q++) != (char *) 0)
    8459       293985 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8460              : 
    8461       293985 :     obstack_1grow (&multilib_obstack, 0);
    8462       293985 :     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
    8463              : 
    8464       293985 :     q = multilib_reuse_raw;
    8465       293985 :     while ((p = *q++) != (char *) 0)
    8466       293985 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8467              : 
    8468       293985 :     obstack_1grow (&multilib_obstack, 0);
    8469       293985 :     multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
    8470              : 
    8471       293985 :     need_space = false;
    8472       587970 :     for (size_t i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
    8473              :       {
    8474       293985 :         if (need_space)
    8475            0 :           obstack_1grow (&multilib_obstack, ' ');
    8476       293985 :         obstack_grow (&multilib_obstack,
    8477              :                       multilib_defaults_raw[i],
    8478              :                       strlen (multilib_defaults_raw[i]));
    8479       293985 :         need_space = true;
    8480              :       }
    8481              : 
    8482       293985 :     obstack_1grow (&multilib_obstack, 0);
    8483       293985 :     multilib_defaults = XOBFINISH (&multilib_obstack, const char *);
    8484              :   }
    8485       293985 : }
    8486              : 
    8487              : /* Set up the spec-handling machinery.  */
    8488              : 
    8489              : void
    8490       293985 : driver::set_up_specs () const
    8491              : {
    8492       293985 :   const char *spec_machine_suffix;
    8493       293985 :   char *specs_file;
    8494       293985 :   size_t i;
    8495              : 
    8496              : #ifdef INIT_ENVIRONMENT
    8497              :   /* Set up any other necessary machine specific environment variables.  */
    8498              :   xputenv (INIT_ENVIRONMENT);
    8499              : #endif
    8500              : 
    8501              :   /* Make a table of what switches there are (switches, n_switches).
    8502              :      Make a table of specified input files (infiles, n_infiles).
    8503              :      Decode switches that are handled locally.  */
    8504              : 
    8505       293985 :   process_command (decoded_options_count, decoded_options);
    8506              : 
    8507              :   /* Initialize the vector of specs to just the default.
    8508              :      This means one element containing 0s, as a terminator.  */
    8509              : 
    8510       293699 :   compilers = XNEWVAR (struct compiler, sizeof default_compilers);
    8511       293699 :   memcpy (compilers, default_compilers, sizeof default_compilers);
    8512       293699 :   n_compilers = n_default_compilers;
    8513              : 
    8514              :   /* Read specs from a file if there is one.  */
    8515              : 
    8516       293699 :   machine_suffix = concat (spec_host_machine, dir_separator_str, spec_version,
    8517              :                            accel_dir_suffix, dir_separator_str, NULL);
    8518       293699 :   just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
    8519              : 
    8520       293699 :   specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
    8521              :   /* Read the specs file unless it is a default one.  */
    8522       293699 :   if (specs_file != 0 && strcmp (specs_file, "specs"))
    8523       292607 :     read_specs (specs_file, true, false);
    8524              :   else
    8525         1092 :     init_spec ();
    8526              : 
    8527              : #ifdef ACCEL_COMPILER
    8528              :   spec_machine_suffix = machine_suffix;
    8529              : #else
    8530       293699 :   spec_machine_suffix = just_machine_suffix;
    8531              : #endif
    8532              : 
    8533       293699 :   const char *exec_prefix
    8534       293699 :     = gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix;
    8535              :   /* We need to check standard_exec_prefix/spec_machine_suffix/specs
    8536              :      for any override of as, ld and libraries.  */
    8537       293699 :   specs_file = (char *) alloca (
    8538              :     strlen (exec_prefix) + strlen (spec_machine_suffix) + sizeof ("specs"));
    8539       293699 :   strcpy (specs_file, exec_prefix);
    8540       293699 :   strcat (specs_file, spec_machine_suffix);
    8541       293699 :   strcat (specs_file, "specs");
    8542       293699 :   if (access (specs_file, R_OK) == 0)
    8543            0 :     read_specs (specs_file, true, false);
    8544              : 
    8545              :   /* Process any configure-time defaults specified for the command line
    8546              :      options, via OPTION_DEFAULT_SPECS.  */
    8547      3230689 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
    8548      2936990 :     do_option_spec (option_default_specs[i].name,
    8549      2936990 :                     option_default_specs[i].spec);
    8550              : 
    8551              :   /* Process DRIVER_SELF_SPECS, adding any new options to the end
    8552              :      of the command line.  */
    8553              : 
    8554      2055893 :   for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
    8555      1762194 :     do_self_spec (driver_self_specs[i]);
    8556              : 
    8557              :   /* If not cross-compiling, look for executables in the standard
    8558              :      places.  */
    8559       293699 :   if (*cross_compile == '0')
    8560              :     {
    8561       293699 :       if (*md_exec_prefix)
    8562              :         {
    8563            0 :           add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
    8564              :                       PREFIX_PRIORITY_LAST, 0, 0);
    8565              :         }
    8566              :     }
    8567              : 
    8568              :   /* Process sysroot_suffix_spec.  */
    8569       293699 :   if (*sysroot_suffix_spec != 0
    8570            0 :       && !no_sysroot_suffix
    8571       293699 :       && do_spec_2 (sysroot_suffix_spec, NULL) == 0)
    8572              :     {
    8573            0 :       if (argbuf.length () > 1)
    8574            0 :         error ("spec failure: more than one argument to "
    8575              :                "%<SYSROOT_SUFFIX_SPEC%>");
    8576            0 :       else if (argbuf.length () == 1)
    8577            0 :         target_sysroot_suffix = xstrdup (argbuf.last ());
    8578              :     }
    8579              : 
    8580              : #ifdef HAVE_LD_SYSROOT
    8581              :   /* Pass the --sysroot option to the linker, if it supports that.  If
    8582              :      there is a sysroot_suffix_spec, it has already been processed by
    8583              :      this point, so target_system_root really is the system root we
    8584              :      should be using.  */
    8585       293699 :   if (target_system_root)
    8586              :     {
    8587            0 :       obstack_grow (&obstack, "%(sysroot_spec) ", strlen ("%(sysroot_spec) "));
    8588            0 :       obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    8589            0 :       set_spec ("link", XOBFINISH (&obstack, const char *), false);
    8590              :     }
    8591              : #endif
    8592              : 
    8593              :   /* Process sysroot_hdrs_suffix_spec.  */
    8594       293699 :   if (*sysroot_hdrs_suffix_spec != 0
    8595            0 :       && !no_sysroot_suffix
    8596       293699 :       && do_spec_2 (sysroot_hdrs_suffix_spec, NULL) == 0)
    8597              :     {
    8598            0 :       if (argbuf.length () > 1)
    8599            0 :         error ("spec failure: more than one argument "
    8600              :                "to %<SYSROOT_HEADERS_SUFFIX_SPEC%>");
    8601            0 :       else if (argbuf.length () == 1)
    8602            0 :         target_sysroot_hdrs_suffix = xstrdup (argbuf.last ());
    8603              :     }
    8604              : 
    8605              :   /* Look for startfiles in the standard places.  */
    8606       293699 :   if (*startfile_prefix_spec != 0
    8607            0 :       && do_spec_2 (startfile_prefix_spec, NULL) == 0
    8608       293699 :       && do_spec_1 (" ", 0, NULL) == 0)
    8609              :     {
    8610            0 :       for (const char *arg : argbuf)
    8611            0 :         add_sysrooted_prefix (&startfile_prefixes, arg, "BINUTILS",
    8612              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8613              :     }
    8614              :   /* We should eventually get rid of all these and stick to
    8615              :      startfile_prefix_spec exclusively.  */
    8616       293699 :   else if (*cross_compile == '0' || target_system_root)
    8617              :     {
    8618       293699 :       if (*md_startfile_prefix)
    8619            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
    8620              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8621              : 
    8622       293699 :       if (*md_startfile_prefix_1)
    8623            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
    8624              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8625              : 
    8626              :       /* If standard_startfile_prefix is relative, base it on
    8627              :          standard_exec_prefix.  This lets us move the installed tree
    8628              :          as a unit.  If GCC_EXEC_PREFIX is defined, base
    8629              :          standard_startfile_prefix on that as well.
    8630              : 
    8631              :          If the prefix is relative, only search it for native compilers;
    8632              :          otherwise we will search a directory containing host libraries.  */
    8633       293699 :       if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
    8634              :         add_sysrooted_prefix (&startfile_prefixes,
    8635              :                               standard_startfile_prefix, "BINUTILS",
    8636              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8637       293699 :       else if (*cross_compile == '0')
    8638              :         {
    8639       293699 :           add_prefix (&startfile_prefixes,
    8640       587398 :                       concat (gcc_exec_prefix
    8641              :                               ? gcc_exec_prefix : standard_exec_prefix,
    8642              :                               machine_suffix,
    8643              :                               standard_startfile_prefix, NULL),
    8644              :                       NULL, PREFIX_PRIORITY_LAST, 0, 1);
    8645              :         }
    8646              : 
    8647              :       /* Sysrooted prefixes are relocated because target_system_root is
    8648              :          also relocated by gcc_exec_prefix.  */
    8649       293699 :       if (*standard_startfile_prefix_1)
    8650       293699 :         add_sysrooted_prefix (&startfile_prefixes,
    8651              :                               standard_startfile_prefix_1, "BINUTILS",
    8652              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8653       293699 :       if (*standard_startfile_prefix_2)
    8654       293699 :         add_sysrooted_prefix (&startfile_prefixes,
    8655              :                               standard_startfile_prefix_2, "BINUTILS",
    8656              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8657              :     }
    8658              : 
    8659              :   /* Process any user specified specs in the order given on the command
    8660              :      line.  */
    8661       293701 :   for (struct user_specs *uptr = user_specs_head; uptr; uptr = uptr->next)
    8662              :     {
    8663            3 :       char *filename = find_a_file (&startfile_prefixes, uptr->filename,
    8664              :                                     R_OK, true);
    8665            3 :       read_specs (filename ? filename : uptr->filename, false, true);
    8666              :     }
    8667              : 
    8668              :   /* Process any user self specs.  */
    8669       293698 :   {
    8670       293698 :     struct spec_list *sl;
    8671     13803806 :     for (sl = specs; sl; sl = sl->next)
    8672     13510108 :       if (sl->name_len == sizeof "self_spec" - 1
    8673      2055886 :           && !strcmp (sl->name, "self_spec"))
    8674       293698 :         do_self_spec (*sl->ptr_spec);
    8675              :   }
    8676              : 
    8677       293698 :   if (compare_debug)
    8678              :     {
    8679          619 :       enum save_temps save;
    8680              : 
    8681          619 :       if (!compare_debug_second)
    8682              :         {
    8683          619 :           n_switches_debug_check[1] = n_switches;
    8684          619 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8685          619 :           switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
    8686              :                                              n_switches_alloc);
    8687              : 
    8688          619 :           do_self_spec ("%:compare-debug-self-opt()");
    8689          619 :           n_switches_debug_check[0] = n_switches;
    8690          619 :           n_switches_alloc_debug_check[0] = n_switches_alloc;
    8691          619 :           switches_debug_check[0] = switches;
    8692              : 
    8693          619 :           n_switches = n_switches_debug_check[1];
    8694          619 :           n_switches_alloc = n_switches_alloc_debug_check[1];
    8695          619 :           switches = switches_debug_check[1];
    8696              :         }
    8697              : 
    8698              :       /* Avoid crash when computing %j in this early.  */
    8699          619 :       save = save_temps_flag;
    8700          619 :       save_temps_flag = SAVE_TEMPS_NONE;
    8701              : 
    8702          619 :       compare_debug = -compare_debug;
    8703          619 :       do_self_spec ("%:compare-debug-self-opt()");
    8704              : 
    8705          619 :       save_temps_flag = save;
    8706              : 
    8707          619 :       if (!compare_debug_second)
    8708              :         {
    8709          619 :           n_switches_debug_check[1] = n_switches;
    8710          619 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8711          619 :           switches_debug_check[1] = switches;
    8712          619 :           compare_debug = -compare_debug;
    8713          619 :           n_switches = n_switches_debug_check[0];
    8714          619 :           n_switches_alloc = n_switches_debug_check[0];
    8715          619 :           switches = switches_debug_check[0];
    8716              :         }
    8717              :     }
    8718              : 
    8719              : 
    8720              :   /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake.  */
    8721       293698 :   if (gcc_exec_prefix)
    8722       293698 :     gcc_exec_prefix = concat (gcc_exec_prefix, spec_host_machine,
    8723              :                               dir_separator_str, spec_version,
    8724              :                               accel_dir_suffix, dir_separator_str, NULL);
    8725              : 
    8726              :   /* Now we have the specs.
    8727              :      Set the `valid' bits for switches that match anything in any spec.  */
    8728              : 
    8729       293698 :   validate_all_switches ();
    8730              : 
    8731              :   /* Now that we have the switches and the specs, set
    8732              :      the subdirectory based on the options.  */
    8733       293698 :   set_multilib_dir ();
    8734       293698 : }
    8735              : 
    8736              : /* Set up to remember the pathname of gcc and any options
    8737              :    needed for collect.  We use argv[0] instead of progname because
    8738              :    we need the complete pathname.  */
    8739              : 
    8740              : void
    8741       293698 : driver::putenv_COLLECT_GCC (const char *argv0) const
    8742              : {
    8743       293698 :   obstack_init (&collect_obstack);
    8744       293698 :   obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
    8745       293698 :   obstack_grow (&collect_obstack, argv0, strlen (argv0) + 1);
    8746       293698 :   xputenv (XOBFINISH (&collect_obstack, char *));
    8747       293698 : }
    8748              : 
    8749              : /* Set up to remember the pathname of the lto wrapper. */
    8750              : 
    8751              : void
    8752       293698 : driver::maybe_putenv_COLLECT_LTO_WRAPPER () const
    8753              : {
    8754       293698 :   char *lto_wrapper_file;
    8755              : 
    8756       293698 :   if (have_c)
    8757              :     lto_wrapper_file = NULL;
    8758              :   else
    8759       107318 :     lto_wrapper_file = find_a_program ("lto-wrapper");
    8760       107318 :   if (lto_wrapper_file)
    8761              :     {
    8762       210192 :       lto_wrapper_file = convert_white_space (lto_wrapper_file);
    8763       105096 :       set_static_spec_owned (&lto_wrapper_spec, lto_wrapper_file);
    8764       105096 :       obstack_init (&collect_obstack);
    8765       105096 :       obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
    8766              :                     sizeof ("COLLECT_LTO_WRAPPER=") - 1);
    8767       105096 :       obstack_grow (&collect_obstack, lto_wrapper_spec,
    8768              :                     strlen (lto_wrapper_spec) + 1);
    8769       105096 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8770              :     }
    8771              : 
    8772       293698 : }
    8773              : 
    8774              : /* Set up to remember the names of offload targets.  */
    8775              : 
    8776              : void
    8777       293698 : driver::maybe_putenv_OFFLOAD_TARGETS () const
    8778              : {
    8779       293698 :   if (offload_targets && offload_targets[0] != '\0')
    8780              :     {
    8781            0 :       obstack_grow (&collect_obstack, "OFFLOAD_TARGET_NAMES=",
    8782              :                     sizeof ("OFFLOAD_TARGET_NAMES=") - 1);
    8783            0 :       obstack_grow (&collect_obstack, offload_targets,
    8784              :                     strlen (offload_targets) + 1);
    8785            0 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8786              : #if OFFLOAD_DEFAULTED
    8787              :       if (offload_targets_default)
    8788              :         xputenv ("OFFLOAD_TARGET_DEFAULT=1");
    8789              : #endif
    8790              :     }
    8791              : 
    8792       293698 :   free (offload_targets);
    8793       293698 :   offload_targets = NULL;
    8794       293698 : }
    8795              : 
    8796              : /* Reject switches that no pass was interested in.  */
    8797              : 
    8798              : void
    8799       293698 : driver::handle_unrecognized_options ()
    8800              : {
    8801      6935196 :   for (size_t i = 0; (int) i < n_switches; i++)
    8802      6641498 :     if (! switches[i].validated)
    8803              :       {
    8804          592 :         const char *hint = m_option_proposer.suggest_option (switches[i].part1);
    8805          592 :         if (hint)
    8806          208 :           error ("unrecognized command-line option %<-%s%>;"
    8807              :                  " did you mean %<-%s%>?",
    8808          208 :                  switches[i].part1, hint);
    8809              :         else
    8810          384 :           error ("unrecognized command-line option %<-%s%>",
    8811          384 :                  switches[i].part1);
    8812              :       }
    8813       293698 : }
    8814              : 
    8815              : /* Handle the various -print-* options, returning 0 if the driver
    8816              :    should exit, or nonzero if the driver should continue.  */
    8817              : 
    8818              : int
    8819       293693 : driver::maybe_print_and_exit () const
    8820              : {
    8821       293693 :   if (print_search_dirs)
    8822              :     {
    8823           56 :       printf (_("install: %s%s\n"),
    8824              :               gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    8825           28 :               gcc_exec_prefix ? "" : machine_suffix);
    8826           28 :       printf (_("programs: %s\n"),
    8827              :               build_search_list (&exec_prefixes, "", false, false));
    8828           28 :       printf (_("libraries: %s\n"),
    8829              :               build_search_list (&startfile_prefixes, "", false, true));
    8830           28 :       return (0);
    8831              :     }
    8832              : 
    8833       293665 :   if (print_file_name)
    8834              :     {
    8835         3483 :       printf ("%s\n", find_file (print_file_name));
    8836         3483 :       return (0);
    8837              :     }
    8838              : 
    8839       290182 :   if (print_prog_name)
    8840              :     {
    8841          110 :       if (use_ld != NULL && ! strcmp (print_prog_name, "ld"))
    8842              :         {
    8843              :           /* Append USE_LD to the default linker.  */
    8844              : #ifdef DEFAULT_LINKER
    8845              :           char *ld;
    8846              : # ifdef HAVE_HOST_EXECUTABLE_SUFFIX
    8847              :           int len = (sizeof (DEFAULT_LINKER)
    8848              :                      - sizeof (HOST_EXECUTABLE_SUFFIX));
    8849              :           ld = NULL;
    8850              :           if (len > 0)
    8851              :             {
    8852              :               char *default_linker = xstrdup (DEFAULT_LINKER);
    8853              :               /* Strip HOST_EXECUTABLE_SUFFIX if DEFAULT_LINKER contains
    8854              :                  HOST_EXECUTABLE_SUFFIX.  */
    8855              :               if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
    8856              :                 {
    8857              :                   default_linker[len] = '\0';
    8858              :                   ld = concat (default_linker, use_ld,
    8859              :                                HOST_EXECUTABLE_SUFFIX, NULL);
    8860              :                 }
    8861              :             }
    8862              :           if (ld == NULL)
    8863              : # endif
    8864              :           ld = concat (DEFAULT_LINKER, use_ld, NULL);
    8865              :           if (access (ld, X_OK) == 0)
    8866              :             {
    8867              :               printf ("%s\n", ld);
    8868              :               return (0);
    8869              :             }
    8870              : #endif
    8871            0 :           print_prog_name = concat (print_prog_name, use_ld, NULL);
    8872              :         }
    8873          110 :       char *newname = find_a_program (print_prog_name);
    8874          110 :       printf ("%s\n", (newname ? newname : print_prog_name));
    8875          110 :       return (0);
    8876              :     }
    8877              : 
    8878       290072 :   if (print_multi_lib)
    8879              :     {
    8880         4007 :       print_multilib_info ();
    8881         4007 :       return (0);
    8882              :     }
    8883              : 
    8884       286065 :   if (print_multi_directory)
    8885              :     {
    8886         3409 :       if (multilib_dir == NULL)
    8887         3384 :         printf (".\n");
    8888              :       else
    8889           25 :         printf ("%s\n", multilib_dir);
    8890         3409 :       return (0);
    8891              :     }
    8892              : 
    8893       282656 :   if (print_multiarch)
    8894              :     {
    8895            0 :       if (multiarch_dir == NULL)
    8896            0 :         printf ("\n");
    8897              :       else
    8898            0 :         printf ("%s\n", multiarch_dir);
    8899            0 :       return (0);
    8900              :     }
    8901              : 
    8902       282656 :   if (print_sysroot)
    8903              :     {
    8904            0 :       if (target_system_root)
    8905              :         {
    8906            0 :           if (target_sysroot_suffix)
    8907            0 :             printf ("%s%s\n", target_system_root, target_sysroot_suffix);
    8908              :           else
    8909            0 :             printf ("%s\n", target_system_root);
    8910              :         }
    8911            0 :       return (0);
    8912              :     }
    8913              : 
    8914       282656 :   if (print_multi_os_directory)
    8915              :     {
    8916          149 :       if (multilib_os_dir == NULL)
    8917            0 :         printf (".\n");
    8918              :       else
    8919          149 :         printf ("%s\n", multilib_os_dir);
    8920          149 :       return (0);
    8921              :     }
    8922              : 
    8923       282507 :   if (print_sysroot_headers_suffix)
    8924              :     {
    8925            1 :       if (*sysroot_hdrs_suffix_spec)
    8926              :         {
    8927            0 :           printf("%s\n", (target_sysroot_hdrs_suffix
    8928              :                           ? target_sysroot_hdrs_suffix
    8929              :                           : ""));
    8930            0 :           return (0);
    8931              :         }
    8932              :       else
    8933              :         /* The error status indicates that only one set of fixed
    8934              :            headers should be built.  */
    8935            1 :         fatal_error (input_location,
    8936              :                      "not configured with sysroot headers suffix");
    8937              :     }
    8938              : 
    8939       282506 :   if (print_help_list)
    8940              :     {
    8941            4 :       display_help ();
    8942              : 
    8943            4 :       if (! verbose_flag)
    8944              :         {
    8945            1 :           printf (_("\nFor bug reporting instructions, please see:\n"));
    8946            1 :           printf ("%s.\n", bug_report_url);
    8947              : 
    8948            1 :           return (0);
    8949              :         }
    8950              : 
    8951              :       /* We do not exit here.  Instead we have created a fake input file
    8952              :          called 'help-dummy' which needs to be compiled, and we pass this
    8953              :          on the various sub-processes, along with the --help switch.
    8954              :          Ensure their output appears after ours.  */
    8955            3 :       fputc ('\n', stdout);
    8956            3 :       fflush (stdout);
    8957              :     }
    8958              : 
    8959       282505 :   if (print_version)
    8960              :     {
    8961           78 :       printf (_("%s %s%s\n"), progname, pkgversion_string,
    8962              :               version_string);
    8963           78 :       printf ("Copyright %s 2026 Free Software Foundation, Inc.\n",
    8964              :               _("(C)"));
    8965           78 :       fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
    8966              : warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
    8967              :              stdout);
    8968           78 :       if (! verbose_flag)
    8969              :         return 0;
    8970              : 
    8971              :       /* We do not exit here. We use the same mechanism of --help to print
    8972              :          the version of the sub-processes. */
    8973            0 :       fputc ('\n', stdout);
    8974            0 :       fflush (stdout);
    8975              :     }
    8976              : 
    8977       282427 :   if (verbose_flag)
    8978              :     {
    8979         1547 :       print_configuration (stderr);
    8980         1547 :       if (n_infiles == 0)
    8981              :         return (0);
    8982              :     }
    8983              : 
    8984              :   return 1;
    8985              : }
    8986              : 
    8987              : /* Figure out what to do with each input file.
    8988              :    Return true if we need to exit early from "main", false otherwise.  */
    8989              : 
    8990              : bool
    8991       281675 : driver::prepare_infiles ()
    8992              : {
    8993       281675 :   size_t i;
    8994       281675 :   int lang_n_infiles = 0;
    8995              : 
    8996       281675 :   if (n_infiles == added_libraries)
    8997          194 :     fatal_error (input_location, "no input files");
    8998              : 
    8999       281481 :   if (seen_error ())
    9000              :     /* Early exit needed from main.  */
    9001              :     return true;
    9002              : 
    9003              :   /* Make a place to record the compiler output file names
    9004              :      that correspond to the input files.  */
    9005              : 
    9006       281036 :   i = n_infiles;
    9007       281036 :   i += lang_specific_extra_outfiles;
    9008       281036 :   outfiles = XCNEWVEC (const char *, i);
    9009              : 
    9010              :   /* Record which files were specified explicitly as link input.  */
    9011              : 
    9012       281036 :   explicit_link_files = XCNEWVEC (char, n_infiles);
    9013              : 
    9014       281036 :   combine_inputs = have_o || flag_wpa;
    9015              : 
    9016       828817 :   for (i = 0; (int) i < n_infiles; i++)
    9017              :     {
    9018       547781 :       const char *name = infiles[i].name;
    9019       547781 :       struct compiler *compiler = lookup_compiler (name,
    9020              :                                                    strlen (name),
    9021              :                                                    infiles[i].language);
    9022              : 
    9023       547781 :       if (compiler && !(compiler->combinable))
    9024       252650 :         combine_inputs = false;
    9025              : 
    9026       547781 :       if (lang_n_infiles > 0 && compiler != input_file_compiler
    9027       244974 :           && infiles[i].language && infiles[i].language[0] != '*')
    9028           33 :         infiles[i].incompiler = compiler;
    9029       547748 :       else if (infiles[i].artificial)
    9030              :         /* Leave lang_n_infiles alone so files added by the driver don't
    9031              :            interfere with -c -o.  */
    9032            3 :         infiles[i].incompiler = compiler;
    9033       547745 :       else if (compiler)
    9034              :         {
    9035       292007 :           lang_n_infiles++;
    9036       292007 :           input_file_compiler = compiler;
    9037       292007 :           infiles[i].incompiler = compiler;
    9038              :         }
    9039              :       else
    9040              :         {
    9041              :           /* Since there is no compiler for this input file, assume it is a
    9042              :              linker file.  */
    9043       255738 :           explicit_link_files[i] = 1;
    9044       255738 :           infiles[i].incompiler = NULL;
    9045              :         }
    9046       547781 :       infiles[i].compiled = false;
    9047       547781 :       infiles[i].preprocessed = false;
    9048              :     }
    9049              : 
    9050       281036 :   if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
    9051            0 :     fatal_error (input_location,
    9052              :                  "cannot specify %<-o%> with %<-c%>, %<-S%> or %<-E%> "
    9053              :                  "with multiple files");
    9054              : 
    9055              :   /* No early exit needed from main; we can continue.  */
    9056              :   return false;
    9057              : }
    9058              : 
    9059              : /* Run the spec machinery on each input file.  */
    9060              : 
    9061              : void
    9062       281036 : driver::do_spec_on_infiles () const
    9063              : {
    9064       281036 :   size_t i;
    9065              : 
    9066       828817 :   for (i = 0; (int) i < n_infiles; i++)
    9067              :     {
    9068       547781 :       int this_file_error = 0;
    9069              : 
    9070              :       /* Tell do_spec what to substitute for %i.  */
    9071              : 
    9072       547781 :       input_file_number = i;
    9073       547781 :       set_input (infiles[i].name);
    9074              : 
    9075       547781 :       if (infiles[i].compiled)
    9076         9116 :         continue;
    9077              : 
    9078              :       /* Use the same thing in %o, unless cp->spec says otherwise.  */
    9079              : 
    9080       538665 :       outfiles[i] = gcc_input_filename;
    9081              : 
    9082              :       /* Figure out which compiler from the file's suffix.  */
    9083              : 
    9084       538665 :       input_file_compiler
    9085       538665 :         = lookup_compiler (infiles[i].name, input_filename_length,
    9086              :                            infiles[i].language);
    9087              : 
    9088       538665 :       if (input_file_compiler)
    9089              :         {
    9090              :           /* Ok, we found an applicable compiler.  Run its spec.  */
    9091              : 
    9092       282927 :           if (input_file_compiler->spec[0] == '#')
    9093              :             {
    9094            0 :               error ("%s: %s compiler not installed on this system",
    9095              :                      gcc_input_filename, &input_file_compiler->spec[1]);
    9096            0 :               this_file_error = 1;
    9097              :             }
    9098              :           else
    9099              :             {
    9100       282927 :               int value;
    9101              : 
    9102       282927 :               if (compare_debug)
    9103              :                 {
    9104          617 :                   free (debug_check_temp_file[0]);
    9105          617 :                   debug_check_temp_file[0] = NULL;
    9106              : 
    9107          617 :                   free (debug_check_temp_file[1]);
    9108          617 :                   debug_check_temp_file[1] = NULL;
    9109              :                 }
    9110              : 
    9111       282927 :               value = do_spec (input_file_compiler->spec);
    9112       282927 :               infiles[i].compiled = true;
    9113       282927 :               if (value < 0)
    9114              :                 this_file_error = 1;
    9115       253666 :               else if (compare_debug && debug_check_temp_file[0])
    9116              :                 {
    9117          613 :                   if (verbose_flag)
    9118            0 :                     inform (UNKNOWN_LOCATION,
    9119              :                             "recompiling with %<-fcompare-debug%>");
    9120              : 
    9121          613 :                   compare_debug = -compare_debug;
    9122          613 :                   n_switches = n_switches_debug_check[1];
    9123          613 :                   n_switches_alloc = n_switches_alloc_debug_check[1];
    9124          613 :                   switches = switches_debug_check[1];
    9125              : 
    9126          613 :                   value = do_spec (input_file_compiler->spec);
    9127              : 
    9128          613 :                   compare_debug = -compare_debug;
    9129          613 :                   n_switches = n_switches_debug_check[0];
    9130          613 :                   n_switches_alloc = n_switches_alloc_debug_check[0];
    9131          613 :                   switches = switches_debug_check[0];
    9132              : 
    9133          613 :                   if (value < 0)
    9134              :                     {
    9135            2 :                       error ("during %<-fcompare-debug%> recompilation");
    9136            2 :                       this_file_error = 1;
    9137              :                     }
    9138              : 
    9139          613 :                   gcc_assert (debug_check_temp_file[1]
    9140              :                               && filename_cmp (debug_check_temp_file[0],
    9141              :                                                debug_check_temp_file[1]));
    9142              : 
    9143          613 :                   if (verbose_flag)
    9144            0 :                     inform (UNKNOWN_LOCATION, "comparing final insns dumps");
    9145              : 
    9146          613 :                   if (compare_files (debug_check_temp_file))
    9147        29275 :                     this_file_error = 1;
    9148              :                 }
    9149              : 
    9150       282927 :               if (compare_debug)
    9151              :                 {
    9152          617 :                   free (debug_check_temp_file[0]);
    9153          617 :                   debug_check_temp_file[0] = NULL;
    9154              : 
    9155          617 :                   free (debug_check_temp_file[1]);
    9156          617 :                   debug_check_temp_file[1] = NULL;
    9157              :                 }
    9158              :             }
    9159              :         }
    9160              : 
    9161              :       /* If this file's name does not contain a recognized suffix,
    9162              :          record it as explicit linker input.  */
    9163              : 
    9164              :       else
    9165       255738 :         explicit_link_files[i] = 1;
    9166              : 
    9167              :       /* Clear the delete-on-failure queue, deleting the files in it
    9168              :          if this compilation failed.  */
    9169              : 
    9170       538665 :       if (this_file_error)
    9171              :         {
    9172        29275 :           delete_failure_queue ();
    9173        29275 :           errorcount++;
    9174              :         }
    9175              :       /* If this compilation succeeded, don't delete those files later.  */
    9176       538665 :       clear_failure_queue ();
    9177              :     }
    9178              : 
    9179              :   /* Reset the input file name to the first compile/object file name, for use
    9180              :      with %b in LINK_SPEC. We use the first input file that we can find
    9181              :      a compiler to compile it instead of using infiles.language since for
    9182              :      languages other than C we use aliases that we then lookup later.  */
    9183       281036 :   if (n_infiles > 0)
    9184              :     {
    9185              :       int i;
    9186              : 
    9187       293232 :       for (i = 0; i < n_infiles ; i++)
    9188       291320 :         if (infiles[i].incompiler
    9189        12196 :             || (infiles[i].language && infiles[i].language[0] != '*'))
    9190              :           {
    9191       279124 :             set_input (infiles[i].name);
    9192       279124 :             break;
    9193              :           }
    9194              :     }
    9195              : 
    9196       281036 :   if (!seen_error ())
    9197              :     {
    9198              :       /* Make sure INPUT_FILE_NUMBER points to first available open
    9199              :          slot.  */
    9200       251761 :       input_file_number = n_infiles;
    9201       251761 :       if (lang_specific_pre_link ())
    9202            0 :         errorcount++;
    9203              :     }
    9204       281036 : }
    9205              : 
    9206              : /* If we have to run the linker, do it now.  */
    9207              : 
    9208              : void
    9209       281036 : driver::maybe_run_linker (const char *argv0) const
    9210              : {
    9211       281036 :   size_t i;
    9212       281036 :   int linker_was_run = 0;
    9213       281036 :   int num_linker_inputs;
    9214              : 
    9215              :   /* Determine if there are any linker input files.  */
    9216       281036 :   num_linker_inputs = 0;
    9217       828817 :   for (i = 0; (int) i < n_infiles; i++)
    9218       547781 :     if (explicit_link_files[i] || outfiles[i] != NULL)
    9219       538244 :       num_linker_inputs++;
    9220              : 
    9221              :   /* Arrange for temporary file names created during linking to take
    9222              :      on names related with the linker output rather than with the
    9223              :      inputs when appropriate.  */
    9224       281036 :   if (outbase && *outbase)
    9225              :     {
    9226       258368 :       if (dumpdir)
    9227              :         {
    9228        88988 :           char *tofree = dumpdir;
    9229        88988 :           gcc_checking_assert (strlen (dumpdir) == dumpdir_length);
    9230        88988 :           dumpdir = concat (dumpdir, outbase, ".", NULL);
    9231        88988 :           free (tofree);
    9232              :         }
    9233              :       else
    9234       169380 :         dumpdir = concat (outbase, ".", NULL);
    9235       258368 :       dumpdir_length += strlen (outbase) + 1;
    9236       258368 :       dumpdir_trailing_dash_added = true;
    9237       258368 :     }
    9238        22668 :   else if (dumpdir_trailing_dash_added)
    9239              :     {
    9240        17798 :       gcc_assert (dumpdir[dumpdir_length - 1] == '-');
    9241        17798 :       dumpdir[dumpdir_length - 1] = '.';
    9242              :     }
    9243              : 
    9244       281036 :   if (dumpdir_trailing_dash_added)
    9245              :     {
    9246       276166 :       gcc_assert (dumpdir_length > 0);
    9247       276166 :       gcc_assert (dumpdir[dumpdir_length - 1] == '.');
    9248       276166 :       dumpdir_length--;
    9249              :     }
    9250              : 
    9251       281036 :   free (outbase);
    9252       281036 :   input_basename = outbase = NULL;
    9253       281036 :   outbase_length = suffixed_basename_length = basename_length = 0;
    9254              : 
    9255              :   /* Run ld to link all the compiler output files.  */
    9256              : 
    9257       281036 :   if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
    9258              :     {
    9259       251270 :       int tmp = execution_count;
    9260              : 
    9261       251270 :       detect_jobserver ();
    9262              : 
    9263       251270 :       if (! have_c)
    9264              :         {
    9265              : #if HAVE_LTO_PLUGIN > 0
    9266              : #if HAVE_LTO_PLUGIN == 2
    9267        94940 :           const char *fno_use_linker_plugin = "fno-use-linker-plugin";
    9268              : #else
    9269              :           const char *fuse_linker_plugin = "fuse-linker-plugin";
    9270              : #endif
    9271              : #endif
    9272              : 
    9273              :           /* We'll use ld if we can't find collect2.  */
    9274        94940 :           if (! strcmp (linker_name_spec, "collect2"))
    9275              :             {
    9276        94940 :               char *s = find_a_program ("collect2");
    9277        94940 :               if (s == NULL)
    9278         1129 :                 set_static_spec_shared (&linker_name_spec, "ld");
    9279              :             }
    9280              : 
    9281              : #if HAVE_LTO_PLUGIN > 0
    9282              : #if HAVE_LTO_PLUGIN == 2
    9283        94940 :           if (!switch_matches (fno_use_linker_plugin,
    9284              :                                fno_use_linker_plugin
    9285              :                                + strlen (fno_use_linker_plugin), 0))
    9286              : #else
    9287              :           if (switch_matches (fuse_linker_plugin,
    9288              :                               fuse_linker_plugin
    9289              :                               + strlen (fuse_linker_plugin), 0))
    9290              : #endif
    9291              :             {
    9292        89450 :               char *temp_spec = find_a_file (&exec_prefixes,
    9293              :                                              LTOPLUGINSONAME, R_OK,
    9294              :                                              false);
    9295        89450 :               if (!temp_spec)
    9296            0 :                 fatal_error (input_location,
    9297              :                              "%<-fuse-linker-plugin%>, but %s not found",
    9298              :                              LTOPLUGINSONAME);
    9299        89450 :               linker_plugin_file_spec = convert_white_space (temp_spec);
    9300              :             }
    9301              : #endif
    9302        94940 :           set_static_spec_shared (&lto_gcc_spec, argv0);
    9303              :         }
    9304              : 
    9305              :       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    9306              :          for collect.  */
    9307       251270 :       putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
    9308       251270 :       putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
    9309              : 
    9310       251270 :       if (print_subprocess_help == 1)
    9311              :         {
    9312            0 :           printf (_("\nLinker options\n==============\n\n"));
    9313            0 :           printf (_("Use \"-Wl,OPTION\" to pass \"OPTION\""
    9314              :                     " to the linker.\n\n"));
    9315            0 :           fflush (stdout);
    9316              :         }
    9317       251270 :       int value = do_spec (link_command_spec);
    9318       251270 :       if (value < 0)
    9319          131 :         errorcount = 1;
    9320       251270 :       linker_was_run = (tmp != execution_count);
    9321              :     }
    9322              : 
    9323              :   /* If options said don't run linker,
    9324              :      complain about input files to be given to the linker.  */
    9325              : 
    9326       281036 :   if (! linker_was_run && !seen_error ())
    9327       344415 :     for (i = 0; (int) i < n_infiles; i++)
    9328       187590 :       if (explicit_link_files[i]
    9329        21664 :           && !(infiles[i].language && infiles[i].language[0] == '*'))
    9330              :         {
    9331           38 :           warning (0, "%s: linker input file unused because linking not done",
    9332           19 :                    outfiles[i]);
    9333           19 :           if (access (outfiles[i], F_OK) < 0)
    9334              :             /* This is can be an indication the user specifed an errorneous
    9335              :                separated option value, (or used the wrong prefix for an
    9336              :                option).  */
    9337            7 :             error ("%s: linker input file not found: %m", outfiles[i]);
    9338              :         }
    9339       281036 : }
    9340              : 
    9341              : /* The end of "main".  */
    9342              : 
    9343              : void
    9344       281036 : driver::final_actions () const
    9345              : {
    9346              :   /* Delete some or all of the temporary files we made.  */
    9347              : 
    9348       281036 :   if (seen_error ())
    9349        29411 :     delete_failure_queue ();
    9350       281036 :   delete_temp_files ();
    9351              : 
    9352       281036 :   if (totruncate_file != NULL && !seen_error ())
    9353              :     /* Truncate file specified by -truncate.
    9354              :        Used by lto-wrapper to reduce temporary disk-space usage. */
    9355         8111 :     truncate(totruncate_file, 0);
    9356              : 
    9357       281036 :   if (print_help_list)
    9358              :     {
    9359            3 :       printf (("\nFor bug reporting instructions, please see:\n"));
    9360            3 :       printf ("%s\n", bug_report_url);
    9361              :     }
    9362       281036 : }
    9363              : 
    9364              : /* Detect whether jobserver is active and working.  If not drop
    9365              :    --jobserver-auth from MAKEFLAGS.  */
    9366              : 
    9367              : void
    9368       251270 : driver::detect_jobserver () const
    9369              : {
    9370       251270 :   jobserver_info jinfo;
    9371       251270 :   if (!jinfo.is_active && !jinfo.skipped_makeflags.empty ())
    9372            0 :     xputenv (xstrdup (jinfo.skipped_makeflags.c_str ()));
    9373       251270 : }
    9374              : 
    9375              : /* Determine what the exit code of the driver should be.  */
    9376              : 
    9377              : int
    9378       281481 : driver::get_exit_code () const
    9379              : {
    9380       281481 :   return (signal_count != 0 ? 2
    9381       281481 :           : seen_error () ? (pass_exit_codes ? greatest_status : 1)
    9382            0 :           : 0);
    9383              : }
    9384              : 
    9385              : /* Find the proper compilation spec for the file name NAME,
    9386              :    whose length is LENGTH.  LANGUAGE is the specified language,
    9387              :    or 0 if this file is to be passed to the linker.  */
    9388              : 
    9389              : static struct compiler *
    9390      1086446 : lookup_compiler (const char *name, size_t length, const char *language)
    9391              : {
    9392      1589753 :   struct compiler *cp;
    9393              : 
    9394              :   /* If this was specified by the user to be a linker input, indicate that.  */
    9395      1589753 :   if (language != 0 && language[0] == '*')
    9396              :     return 0;
    9397              : 
    9398              :   /* Otherwise, look for the language, if one is spec'd.  */
    9399      1125553 :   if (language != 0)
    9400              :     {
    9401     22926627 :       for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9402     22926627 :         if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language))
    9403              :           {
    9404       574956 :             if (name != NULL && strcmp (name, "-") == 0
    9405         2080 :                 && (strcmp (cp->suffix, "@c-header") == 0
    9406         2080 :                     || strcmp (cp->suffix, "@c++-header") == 0)
    9407            0 :                 && !have_E)
    9408            0 :               fatal_error (input_location,
    9409              :                            "cannot use %<-%> as input filename for a "
    9410              :                            "precompiled header");
    9411              : 
    9412              :             return cp;
    9413              :           }
    9414              : 
    9415            0 :       error ("language %s not recognized", language);
    9416            0 :       return 0;
    9417              :     }
    9418              : 
    9419              :   /* Look for a suffix.  */
    9420     30622315 :   for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9421              :     {
    9422     30575039 :       if (/* The suffix `-' matches only the file name `-'.  */
    9423     30575039 :           (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9424     30575025 :           || (strlen (cp->suffix) < length
    9425              :               /* See if the suffix matches the end of NAME.  */
    9426     30129226 :               && !strcmp (cp->suffix,
    9427     30129226 :                           name + length - strlen (cp->suffix))
    9428              :          ))
    9429              :         break;
    9430              :     }
    9431              : 
    9432              : #if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
    9433              :   /* Look again, but case-insensitively this time.  */
    9434              :   if (cp < compilers)
    9435              :     for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9436              :       {
    9437              :         if (/* The suffix `-' matches only the file name `-'.  */
    9438              :             (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9439              :             || (strlen (cp->suffix) < length
    9440              :                 /* See if the suffix matches the end of NAME.  */
    9441              :                 && ((!strcmp (cp->suffix,
    9442              :                              name + length - strlen (cp->suffix))
    9443              :                      || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
    9444              :                     && !strcasecmp (cp->suffix,
    9445              :                                     name + length - strlen (cp->suffix)))
    9446              :            ))
    9447              :           break;
    9448              :       }
    9449              : #endif
    9450              : 
    9451       550597 :   if (cp >= compilers)
    9452              :     {
    9453       503321 :       if (cp->spec[0] != '@')
    9454              :         /* A non-alias entry: return it.  */
    9455              :         return cp;
    9456              : 
    9457              :       /* An alias entry maps a suffix to a language.
    9458              :          Search for the language; pass 0 for NAME and LENGTH
    9459              :          to avoid infinite recursion if language not found.  */
    9460       503307 :       return lookup_compiler (NULL, 0, cp->spec + 1);
    9461              :     }
    9462              :   return 0;
    9463              : }
    9464              : 
    9465              : static char *
    9466     45796811 : save_string (const char *s, int len)
    9467              : {
    9468     45796811 :   char *result = XNEWVEC (char, len + 1);
    9469              : 
    9470     45796811 :   gcc_checking_assert (strlen (s) >= (unsigned int) len);
    9471     45796811 :   memcpy (result, s, len);
    9472     45796811 :   result[len] = 0;
    9473     45796811 :   return result;
    9474              : }
    9475              : 
    9476              : 
    9477              : static inline void
    9478     45523190 : validate_switches_from_spec (const char *spec, bool user)
    9479              : {
    9480     45523190 :   const char *p = spec;
    9481     45523190 :   char c;
    9482    561844277 :   while ((c = *p++))
    9483    470797897 :     if (c == '%'
    9484    470797897 :         && (*p == '{'
    9485     11160524 :             || *p == '<'
    9486     10279430 :             || (*p == 'W' && *++p == '{')
    9487     10279430 :             || (*p == '@' && *++p == '{')))
    9488              :       /* We have a switch spec.  */
    9489     45229494 :       p = validate_switches (p + 1, user, *p == '{');
    9490     45523190 : }
    9491              : 
    9492              : static void
    9493       293698 : validate_all_switches (void)
    9494              : {
    9495       293698 :   struct compiler *comp;
    9496       293698 :   struct spec_list *spec;
    9497              : 
    9498     32013082 :   for (comp = compilers; comp->spec; comp++)
    9499     31719384 :     validate_switches_from_spec (comp->spec, false);
    9500              : 
    9501              :   /* Look through the linked list of specs read from the specs file.  */
    9502     13803806 :   for (spec = specs; spec; spec = spec->next)
    9503     13510108 :     validate_switches_from_spec (*spec->ptr_spec, spec->user_p);
    9504              : 
    9505       293698 :   validate_switches_from_spec (link_command_spec, false);
    9506       293698 : }
    9507              : 
    9508              : /* Look at the switch-name that comes after START and mark as valid
    9509              :    all supplied switches that match it.  If BRACED, handle other
    9510              :    switches after '|' and '&', and specs after ':' until ';' or '}',
    9511              :    going back for more switches after ';'.  Without BRACED, handle
    9512              :    only one atom.  Return a pointer to whatever follows the handled
    9513              :    items, after the closing brace if BRACED.  */
    9514              : 
    9515              : static const char *
    9516    195602870 : validate_switches (const char *start, bool user_spec, bool braced)
    9517              : {
    9518    195602870 :   const char *p = start;
    9519    252286584 :   const char *atom;
    9520    252286584 :   size_t len;
    9521    252286584 :   int i;
    9522    252286584 :   bool suffix;
    9523    252286584 :   bool starred;
    9524              : 
    9525              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    9526              : 
    9527    252286584 : next_member:
    9528    252286584 :   suffix = false;
    9529    252286584 :   starred = false;
    9530              : 
    9531    278719404 :   SKIP_WHITE ();
    9532              : 
    9533    252286584 :   if (*p == '!')
    9534     78123669 :     p++;
    9535              : 
    9536    252286584 :   SKIP_WHITE ();
    9537    252286584 :   if (*p == '.' || *p == ',')
    9538            0 :     suffix = true, p++;
    9539              : 
    9540    252286584 :   atom = p;
    9541    252286584 :   while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    9542   1689057214 :          || *p == ',' || *p == '.' || *p == '@')
    9543   1436770630 :     p++;
    9544    252286584 :   len = p - atom;
    9545              : 
    9546    252286584 :   if (*p == '*')
    9547     66669446 :     starred = true, p++;
    9548              : 
    9549    253461376 :   SKIP_WHITE ();
    9550              : 
    9551    252286584 :   if (!suffix)
    9552              :     {
    9553              :       /* Mark all matching switches as valid.  */
    9554   5957333396 :       for (i = 0; i < n_switches; i++)
    9555   5705046812 :         if (!strncmp (switches[i].part1, atom, len)
    9556    474708827 :             && (starred || switches[i].part1[len] == '\0')
    9557     49450598 :             && (switches[i].known || user_spec))
    9558     49448174 :               switches[i].validated = true;
    9559              :     }
    9560              : 
    9561    252286584 :   if (!braced)
    9562              :     return p;
    9563              : 
    9564    250818094 :   if (*p) p++;
    9565    250818094 :   if (*p && (p[-1] == '|' || p[-1] == '&'))
    9566     38768136 :     goto next_member;
    9567              : 
    9568    212049958 :   if (*p && p[-1] == ':')
    9569              :     {
    9570   2847695804 :       while (*p && *p != ';' && *p != '}')
    9571              :         {
    9572   2684106015 :           if (*p == '%')
    9573              :             {
    9574    252580280 :               p++;
    9575    252580280 :               if (*p == '{' || *p == '<')
    9576    147730094 :                 p = validate_switches (p+1, user_spec, *p == '{');
    9577    104850186 :               else if (p[0] == 'W' && p[1] == '{')
    9578      2349584 :                 p = validate_switches (p+2, user_spec, true);
    9579    102500602 :               else if (p[0] == '@' && p[1] == '{')
    9580       293698 :                 p = validate_switches (p+2, user_spec, true);
    9581              :             }
    9582              :           else
    9583   2431525735 :             p++;
    9584              :         }
    9585              : 
    9586    163589789 :       if (*p) p++;
    9587    163589789 :       if (*p && p[-1] == ';')
    9588     17915578 :         goto next_member;
    9589              :     }
    9590              : 
    9591              :   return p;
    9592              : #undef SKIP_WHITE
    9593              : }
    9594              : 
    9595              : struct mdswitchstr
    9596              : {
    9597              :   const char *str;
    9598              :   int len;
    9599              : };
    9600              : 
    9601              : static struct mdswitchstr *mdswitches;
    9602              : static int n_mdswitches;
    9603              : 
    9604              : /* Check whether a particular argument was used.  The first time we
    9605              :    canonicalize the switches to keep only the ones we care about.  */
    9606              : 
    9607              : struct used_arg_t
    9608              : {
    9609              :  public:
    9610              :   int operator () (const char *p, int len);
    9611              :   void finalize ();
    9612              : 
    9613              :  private:
    9614              :   struct mswitchstr
    9615              :   {
    9616              :     const char *str;
    9617              :     const char *replace;
    9618              :     int len;
    9619              :     int rep_len;
    9620              :   };
    9621              : 
    9622              :   mswitchstr *mswitches;
    9623              :   int n_mswitches;
    9624              : 
    9625              : };
    9626              : 
    9627              : used_arg_t used_arg;
    9628              : 
    9629              : int
    9630      1775645 : used_arg_t::operator () (const char *p, int len)
    9631              : {
    9632      1775645 :   int i, j;
    9633              : 
    9634      1775645 :   if (!mswitches)
    9635              :     {
    9636       293698 :       struct mswitchstr *matches;
    9637       293698 :       const char *q;
    9638       293698 :       int cnt = 0;
    9639              : 
    9640              :       /* Break multilib_matches into the component strings of string
    9641              :          and replacement string.  */
    9642      4992866 :       for (q = multilib_matches; *q != '\0'; q++)
    9643      4699168 :         if (*q == ';')
    9644       587396 :           cnt++;
    9645              : 
    9646       293698 :       matches
    9647       293698 :         = (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
    9648       293698 :       i = 0;
    9649       293698 :       q = multilib_matches;
    9650       881094 :       while (*q != '\0')
    9651              :         {
    9652       587396 :           matches[i].str = q;
    9653      2349584 :           while (*q != ' ')
    9654              :             {
    9655      1762188 :               if (*q == '\0')
    9656              :                 {
    9657            0 :                 invalid_matches:
    9658            0 :                   fatal_error (input_location, "multilib spec %qs is invalid",
    9659              :                                multilib_matches);
    9660              :                 }
    9661      1762188 :               q++;
    9662              :             }
    9663       587396 :           matches[i].len = q - matches[i].str;
    9664              : 
    9665       587396 :           matches[i].replace = ++q;
    9666      2349584 :           while (*q != ';' && *q != '\0')
    9667              :             {
    9668      1762188 :               if (*q == ' ')
    9669            0 :                 goto invalid_matches;
    9670      1762188 :               q++;
    9671              :             }
    9672       587396 :           matches[i].rep_len = q - matches[i].replace;
    9673       587396 :           i++;
    9674       587396 :           if (*q == ';')
    9675       587396 :             q++;
    9676              :         }
    9677              : 
    9678              :       /* Now build a list of the replacement string for switches that we care
    9679              :          about.  Make sure we allocate at least one entry.  This prevents
    9680              :          xmalloc from calling fatal, and prevents us from re-executing this
    9681              :          block of code.  */
    9682       293698 :       mswitches
    9683       587396 :         = XNEWVEC (struct mswitchstr, n_mdswitches + (n_switches ? n_switches : 1));
    9684      6935196 :       for (i = 0; i < n_switches; i++)
    9685      6641498 :         if ((switches[i].live_cond & SWITCH_IGNORE) == 0)
    9686              :           {
    9687      6641492 :             int xlen = strlen (switches[i].part1);
    9688     19911650 :             for (j = 0; j < cnt; j++)
    9689     13280545 :               if (xlen == matches[j].len
    9690        19197 :                   && ! strncmp (switches[i].part1, matches[j].str, xlen))
    9691              :                 {
    9692        10387 :                   mswitches[n_mswitches].str = matches[j].replace;
    9693        10387 :                   mswitches[n_mswitches].len = matches[j].rep_len;
    9694        10387 :                   mswitches[n_mswitches].replace = (char *) 0;
    9695        10387 :                   mswitches[n_mswitches].rep_len = 0;
    9696        10387 :                   n_mswitches++;
    9697        10387 :                   break;
    9698              :                 }
    9699              :           }
    9700              : 
    9701              :       /* Add MULTILIB_DEFAULTS switches too, as long as they were not present
    9702              :          on the command line nor any options mutually incompatible with
    9703              :          them.  */
    9704       587396 :       for (i = 0; i < n_mdswitches; i++)
    9705              :         {
    9706       293698 :           const char *r;
    9707              : 
    9708       587396 :           for (q = multilib_options; *q != '\0'; *q && q++)
    9709              :             {
    9710       293698 :               while (*q == ' ')
    9711            0 :                 q++;
    9712              : 
    9713       293698 :               r = q;
    9714       293698 :               while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
    9715       293698 :                      || strchr (" /", q[mdswitches[i].len]) == NULL)
    9716              :                 {
    9717            0 :                   while (*q != ' ' && *q != '/' && *q != '\0')
    9718            0 :                     q++;
    9719            0 :                   if (*q != '/')
    9720              :                     break;
    9721            0 :                   q++;
    9722              :                 }
    9723              : 
    9724       293698 :               if (*q != ' ' && *q != '\0')
    9725              :                 {
    9726       584957 :                   while (*r != ' ' && *r != '\0')
    9727              :                     {
    9728              :                       q = r;
    9729      2339828 :                       while (*q != ' ' && *q != '/' && *q != '\0')
    9730      1754871 :                         q++;
    9731              : 
    9732       584957 :                       if (used_arg (r, q - r))
    9733              :                         break;
    9734              : 
    9735       574570 :                       if (*q != '/')
    9736              :                         {
    9737       283311 :                           mswitches[n_mswitches].str = mdswitches[i].str;
    9738       283311 :                           mswitches[n_mswitches].len = mdswitches[i].len;
    9739       283311 :                           mswitches[n_mswitches].replace = (char *) 0;
    9740       283311 :                           mswitches[n_mswitches].rep_len = 0;
    9741       283311 :                           n_mswitches++;
    9742       283311 :                           break;
    9743              :                         }
    9744              : 
    9745       291259 :                       r = q + 1;
    9746              :                     }
    9747              :                   break;
    9748              :                 }
    9749              :             }
    9750              :         }
    9751              :     }
    9752              : 
    9753      2378937 :   for (i = 0; i < n_mswitches; i++)
    9754      1209023 :     if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
    9755              :       return 1;
    9756              : 
    9757              :   return 0;
    9758              : }
    9759              : 
    9760         1134 : void used_arg_t::finalize ()
    9761              : {
    9762         1134 :   XDELETEVEC (mswitches);
    9763         1134 :   mswitches = NULL;
    9764         1134 :   n_mswitches = 0;
    9765         1134 : }
    9766              : 
    9767              : 
    9768              : static int
    9769      1206716 : default_arg (const char *p, int len)
    9770              : {
    9771      1206716 :   int i;
    9772              : 
    9773      1806067 :   for (i = 0; i < n_mdswitches; i++)
    9774      1206716 :     if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
    9775              :       return 1;
    9776              : 
    9777              :   return 0;
    9778              : }
    9779              : 
    9780              : /* Use multilib_dir as key to find corresponding multilib_os_dir and
    9781              :    multiarch_dir.  */
    9782              : 
    9783              : static void
    9784            0 : find_multilib_os_dir_by_multilib_dir (const char *multilib_dir,
    9785              :                                       const char **p_multilib_os_dir,
    9786              :                                       const char **p_multiarch_dir)
    9787              : {
    9788            0 :   const char *p = multilib_select;
    9789            0 :   unsigned int this_path_len;
    9790            0 :   const char *this_path;
    9791            0 :   int ok = 0;
    9792              : 
    9793            0 :   while (*p != '\0')
    9794              :     {
    9795              :       /* Ignore newlines.  */
    9796            0 :       if (*p == '\n')
    9797              :         {
    9798            0 :           ++p;
    9799            0 :           continue;
    9800              :         }
    9801              : 
    9802              :       /* Get the initial path.  */
    9803              :       this_path = p;
    9804            0 :       while (*p != ' ')
    9805              :         {
    9806            0 :           if (*p == '\0')
    9807              :             {
    9808            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
    9809              :                            multilib_select, multilib_reuse);
    9810              :             }
    9811            0 :           ++p;
    9812              :         }
    9813            0 :       this_path_len = p - this_path;
    9814              : 
    9815            0 :       ok = 0;
    9816              : 
    9817              :       /* Skip any arguments, we don't care at this stage.  */
    9818            0 :       while (*++p != ';');
    9819              : 
    9820            0 :       if (this_path_len != 1
    9821            0 :           || this_path[0] != '.')
    9822              :         {
    9823            0 :           char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
    9824            0 :           char *q;
    9825              : 
    9826            0 :           strncpy (new_multilib_dir, this_path, this_path_len);
    9827            0 :           new_multilib_dir[this_path_len] = '\0';
    9828            0 :           q = strchr (new_multilib_dir, ':');
    9829            0 :           if (q != NULL)
    9830            0 :             *q = '\0';
    9831              : 
    9832            0 :           if (strcmp (new_multilib_dir, multilib_dir) == 0)
    9833            0 :             ok = 1;
    9834              :         }
    9835              : 
    9836              :       /* Found matched multilib_dir, update multilib_os_dir and
    9837              :          multiarch_dir.  */
    9838            0 :       if (ok)
    9839              :         {
    9840            0 :           const char *q = this_path, *end = this_path + this_path_len;
    9841              : 
    9842            0 :           while (q < end && *q != ':')
    9843            0 :             q++;
    9844            0 :           if (q < end)
    9845              :             {
    9846            0 :               const char *q2 = q + 1, *ml_end = end;
    9847            0 :               char *new_multilib_os_dir;
    9848              : 
    9849            0 :               while (q2 < end && *q2 != ':')
    9850            0 :                 q2++;
    9851            0 :               if (*q2 == ':')
    9852            0 :                 ml_end = q2;
    9853            0 :               if (ml_end - q == 1)
    9854            0 :                 *p_multilib_os_dir = xstrdup (".");
    9855              :               else
    9856              :                 {
    9857            0 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
    9858            0 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
    9859            0 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
    9860            0 :                   *p_multilib_os_dir = new_multilib_os_dir;
    9861              :                 }
    9862              : 
    9863            0 :               if (q2 < end && *q2 == ':')
    9864              :                 {
    9865            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
    9866            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
    9867            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
    9868            0 :                   *p_multiarch_dir = new_multiarch_dir;
    9869              :                 }
    9870              :               break;
    9871              :             }
    9872              :         }
    9873            0 :       ++p;
    9874              :     }
    9875            0 : }
    9876              : 
    9877              : /* Work out the subdirectory to use based on the options. The format of
    9878              :    multilib_select is a list of elements. Each element is a subdirectory
    9879              :    name followed by a list of options followed by a semicolon. The format
    9880              :    of multilib_exclusions is the same, but without the preceding
    9881              :    directory. First gcc will check the exclusions, if none of the options
    9882              :    beginning with an exclamation point are present, and all of the other
    9883              :    options are present, then we will ignore this completely. Passing
    9884              :    that, gcc will consider each multilib_select in turn using the same
    9885              :    rules for matching the options. If a match is found, that subdirectory
    9886              :    will be used.
    9887              :    A subdirectory name is optionally followed by a colon and the corresponding
    9888              :    multiarch name.  */
    9889              : 
    9890              : static void
    9891       293698 : set_multilib_dir (void)
    9892              : {
    9893       293698 :   const char *p;
    9894       293698 :   unsigned int this_path_len;
    9895       293698 :   const char *this_path, *this_arg;
    9896       293698 :   const char *start, *end;
    9897       293698 :   int not_arg;
    9898       293698 :   int ok, ndfltok, first;
    9899              : 
    9900       293698 :   n_mdswitches = 0;
    9901       293698 :   start = multilib_defaults;
    9902       293698 :   while (*start == ' ' || *start == '\t')
    9903            0 :     start++;
    9904       587396 :   while (*start != '\0')
    9905              :     {
    9906       293698 :       n_mdswitches++;
    9907      1174792 :       while (*start != ' ' && *start != '\t' && *start != '\0')
    9908       881094 :         start++;
    9909       293698 :       while (*start == ' ' || *start == '\t')
    9910            0 :         start++;
    9911              :     }
    9912              : 
    9913       293698 :   if (n_mdswitches)
    9914              :     {
    9915       293698 :       int i = 0;
    9916              : 
    9917       293698 :       mdswitches = XNEWVEC (struct mdswitchstr, n_mdswitches);
    9918       293698 :       for (start = multilib_defaults; *start != '\0'; start = end + 1)
    9919              :         {
    9920       293698 :           while (*start == ' ' || *start == '\t')
    9921            0 :             start++;
    9922              : 
    9923       293698 :           if (*start == '\0')
    9924              :             break;
    9925              : 
    9926       881094 :           for (end = start + 1;
    9927       881094 :                *end != ' ' && *end != '\t' && *end != '\0'; end++)
    9928              :             ;
    9929              : 
    9930       293698 :           obstack_grow (&multilib_obstack, start, end - start);
    9931       293698 :           obstack_1grow (&multilib_obstack, 0);
    9932       293698 :           mdswitches[i].str = XOBFINISH (&multilib_obstack, const char *);
    9933       293698 :           mdswitches[i++].len = end - start;
    9934              : 
    9935       293698 :           if (*end == '\0')
    9936              :             break;
    9937              :         }
    9938              :     }
    9939              : 
    9940       293698 :   p = multilib_exclusions;
    9941       293698 :   while (*p != '\0')
    9942              :     {
    9943              :       /* Ignore newlines.  */
    9944            0 :       if (*p == '\n')
    9945              :         {
    9946            0 :           ++p;
    9947            0 :           continue;
    9948              :         }
    9949              : 
    9950              :       /* Check the arguments.  */
    9951              :       ok = 1;
    9952            0 :       while (*p != ';')
    9953              :         {
    9954            0 :           if (*p == '\0')
    9955              :             {
    9956            0 :             invalid_exclusions:
    9957            0 :               fatal_error (input_location, "multilib exclusions %qs is invalid",
    9958              :                            multilib_exclusions);
    9959              :             }
    9960              : 
    9961            0 :           if (! ok)
    9962              :             {
    9963            0 :               ++p;
    9964            0 :               continue;
    9965              :             }
    9966              : 
    9967            0 :           this_arg = p;
    9968            0 :           while (*p != ' ' && *p != ';')
    9969              :             {
    9970            0 :               if (*p == '\0')
    9971            0 :                 goto invalid_exclusions;
    9972            0 :               ++p;
    9973              :             }
    9974              : 
    9975            0 :           if (*this_arg != '!')
    9976              :             not_arg = 0;
    9977              :           else
    9978              :             {
    9979            0 :               not_arg = 1;
    9980            0 :               ++this_arg;
    9981              :             }
    9982              : 
    9983            0 :           ok = used_arg (this_arg, p - this_arg);
    9984            0 :           if (not_arg)
    9985            0 :             ok = ! ok;
    9986              : 
    9987            0 :           if (*p == ' ')
    9988            0 :             ++p;
    9989              :         }
    9990              : 
    9991            0 :       if (ok)
    9992              :         return;
    9993              : 
    9994            0 :       ++p;
    9995              :     }
    9996              : 
    9997       293698 :   first = 1;
    9998       293698 :   p = multilib_select;
    9999              : 
   10000              :   /* Append multilib reuse rules if any.  With those rules, we can reuse
   10001              :      one multilib for certain different options sets.  */
   10002       293698 :   if (strlen (multilib_reuse) > 0)
   10003            0 :     p = concat (p, multilib_reuse, NULL);
   10004              : 
   10005       595344 :   while (*p != '\0')
   10006              :     {
   10007              :       /* Ignore newlines.  */
   10008       595344 :       if (*p == '\n')
   10009              :         {
   10010            0 :           ++p;
   10011            0 :           continue;
   10012              :         }
   10013              : 
   10014              :       /* Get the initial path.  */
   10015              :       this_path = p;
   10016      4191252 :       while (*p != ' ')
   10017              :         {
   10018      3595908 :           if (*p == '\0')
   10019              :             {
   10020            0 :             invalid_select:
   10021            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
   10022              :                            multilib_select, multilib_reuse);
   10023              :             }
   10024      3595908 :           ++p;
   10025              :         }
   10026       595344 :       this_path_len = p - this_path;
   10027              : 
   10028              :       /* Check the arguments.  */
   10029       595344 :       ok = 1;
   10030       595344 :       ndfltok = 1;
   10031       595344 :       ++p;
   10032      1786032 :       while (*p != ';')
   10033              :         {
   10034      1190688 :           if (*p == '\0')
   10035            0 :             goto invalid_select;
   10036              : 
   10037      1190688 :           if (! ok)
   10038              :             {
   10039            0 :               ++p;
   10040            0 :               continue;
   10041              :             }
   10042              : 
   10043      5651794 :           this_arg = p;
   10044      5651794 :           while (*p != ' ' && *p != ';')
   10045              :             {
   10046      4461106 :               if (*p == '\0')
   10047            0 :                 goto invalid_select;
   10048      4461106 :               ++p;
   10049              :             }
   10050              : 
   10051      1190688 :           if (*this_arg != '!')
   10052              :             not_arg = 0;
   10053              :           else
   10054              :             {
   10055       889042 :               not_arg = 1;
   10056       889042 :               ++this_arg;
   10057              :             }
   10058              : 
   10059              :           /* If this is a default argument, we can just ignore it.
   10060              :              This is true even if this_arg begins with '!'.  Beginning
   10061              :              with '!' does not mean that this argument is necessarily
   10062              :              inappropriate for this library: it merely means that
   10063              :              there is a more specific library which uses this
   10064              :              argument.  If this argument is a default, we need not
   10065              :              consider that more specific library.  */
   10066      1190688 :           ok = used_arg (this_arg, p - this_arg);
   10067      1190688 :           if (not_arg)
   10068       889042 :             ok = ! ok;
   10069              : 
   10070      1190688 :           if (! ok)
   10071       309594 :             ndfltok = 0;
   10072              : 
   10073      1190688 :           if (default_arg (this_arg, p - this_arg))
   10074       595344 :             ok = 1;
   10075              : 
   10076      1190688 :           if (*p == ' ')
   10077       595344 :             ++p;
   10078              :         }
   10079              : 
   10080       595344 :       if (ok && first)
   10081              :         {
   10082       293698 :           if (this_path_len != 1
   10083       285750 :               || this_path[0] != '.')
   10084              :             {
   10085         7948 :               char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
   10086         7948 :               char *q;
   10087              : 
   10088         7948 :               strncpy (new_multilib_dir, this_path, this_path_len);
   10089         7948 :               new_multilib_dir[this_path_len] = '\0';
   10090         7948 :               q = strchr (new_multilib_dir, ':');
   10091         7948 :               if (q != NULL)
   10092         7948 :                 *q = '\0';
   10093         7948 :               multilib_dir = new_multilib_dir;
   10094              :             }
   10095              :           first = 0;
   10096              :         }
   10097              : 
   10098       595344 :       if (ndfltok)
   10099              :         {
   10100       293698 :           const char *q = this_path, *end = this_path + this_path_len;
   10101              : 
   10102       881094 :           while (q < end && *q != ':')
   10103       587396 :             q++;
   10104       293698 :           if (q < end)
   10105              :             {
   10106       293698 :               const char *q2 = q + 1, *ml_end = end;
   10107       293698 :               char *new_multilib_os_dir;
   10108              : 
   10109      2627386 :               while (q2 < end && *q2 != ':')
   10110      2333688 :                 q2++;
   10111       293698 :               if (*q2 == ':')
   10112            0 :                 ml_end = q2;
   10113       293698 :               if (ml_end - q == 1)
   10114            0 :                 multilib_os_dir = xstrdup (".");
   10115              :               else
   10116              :                 {
   10117       293698 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
   10118       293698 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
   10119       293698 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
   10120       293698 :                   multilib_os_dir = new_multilib_os_dir;
   10121              :                 }
   10122              : 
   10123       293698 :               if (q2 < end && *q2 == ':')
   10124              :                 {
   10125            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
   10126            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
   10127            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
   10128            0 :                   multiarch_dir = new_multiarch_dir;
   10129              :                 }
   10130              :               break;
   10131              :             }
   10132              :         }
   10133              : 
   10134       301646 :       ++p;
   10135              :     }
   10136              : 
   10137       587396 :   multilib_dir =
   10138       293698 :     targetm_common.compute_multilib (
   10139              :       switches,
   10140              :       n_switches,
   10141              :       multilib_dir,
   10142              :       multilib_defaults,
   10143              :       multilib_select,
   10144              :       multilib_matches,
   10145              :       multilib_exclusions,
   10146              :       multilib_reuse);
   10147              : 
   10148       293698 :   if (multilib_dir == NULL && multilib_os_dir != NULL
   10149       285750 :       && strcmp (multilib_os_dir, ".") == 0)
   10150              :     {
   10151            0 :       free (const_cast<char *> (multilib_os_dir));
   10152            0 :       multilib_os_dir = NULL;
   10153              :     }
   10154       293698 :   else if (multilib_dir != NULL && multilib_os_dir == NULL)
   10155              :     {
   10156              :       /* Give second chance to search matched multilib_os_dir again by matching
   10157              :          the multilib_dir since some target may use TARGET_COMPUTE_MULTILIB
   10158              :          hook rather than the builtin way.  */
   10159            0 :       find_multilib_os_dir_by_multilib_dir (multilib_dir, &multilib_os_dir,
   10160              :                                             &multiarch_dir);
   10161              : 
   10162            0 :       if (multilib_os_dir == NULL)
   10163            0 :         multilib_os_dir = multilib_dir;
   10164              :     }
   10165              : }
   10166              : 
   10167              : /* Print out the multiple library subdirectory selection
   10168              :    information.  This prints out a series of lines.  Each line looks
   10169              :    like SUBDIRECTORY;@OPTION@OPTION, with as many options as is
   10170              :    required.  Only the desired options are printed out, the negative
   10171              :    matches.  The options are print without a leading dash.  There are
   10172              :    no spaces to make it easy to use the information in the shell.
   10173              :    Each subdirectory is printed only once.  This assumes the ordering
   10174              :    generated by the genmultilib script. Also, we leave out ones that match
   10175              :    the exclusions.  */
   10176              : 
   10177              : static void
   10178         4007 : print_multilib_info (void)
   10179              : {
   10180         4007 :   const char *p = multilib_select;
   10181         4007 :   const char *last_path = 0, *this_path;
   10182         4007 :   int skip;
   10183         4007 :   int not_arg;
   10184         4007 :   unsigned int last_path_len = 0;
   10185              : 
   10186        16028 :   while (*p != '\0')
   10187              :     {
   10188        12021 :       skip = 0;
   10189              :       /* Ignore newlines.  */
   10190        12021 :       if (*p == '\n')
   10191              :         {
   10192            0 :           ++p;
   10193            0 :           continue;
   10194              :         }
   10195              : 
   10196              :       /* Get the initial path.  */
   10197              :       this_path = p;
   10198        96168 :       while (*p != ' ')
   10199              :         {
   10200        84147 :           if (*p == '\0')
   10201              :             {
   10202            0 :             invalid_select:
   10203            0 :               fatal_error (input_location,
   10204              :                            "multilib select %qs is invalid", multilib_select);
   10205              :             }
   10206              : 
   10207        84147 :           ++p;
   10208              :         }
   10209              : 
   10210              :       /* When --disable-multilib was used but target defines
   10211              :          MULTILIB_OSDIRNAMES, entries starting with .: (and not starting
   10212              :          with .:: for multiarch configurations) are there just to find
   10213              :          multilib_os_dir, so skip them from output.  */
   10214        12021 :       if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
   10215        12021 :         skip = 1;
   10216              : 
   10217              :       /* Check for matches with the multilib_exclusions. We don't bother
   10218              :          with the '!' in either list. If any of the exclusion rules match
   10219              :          all of its options with the select rule, we skip it.  */
   10220        12021 :       {
   10221        12021 :         const char *e = multilib_exclusions;
   10222        12021 :         const char *this_arg;
   10223              : 
   10224        12021 :         while (*e != '\0')
   10225              :           {
   10226            0 :             int m = 1;
   10227              :             /* Ignore newlines.  */
   10228            0 :             if (*e == '\n')
   10229              :               {
   10230            0 :                 ++e;
   10231            0 :                 continue;
   10232              :               }
   10233              : 
   10234              :             /* Check the arguments.  */
   10235            0 :             while (*e != ';')
   10236              :               {
   10237            0 :                 const char *q;
   10238            0 :                 int mp = 0;
   10239              : 
   10240            0 :                 if (*e == '\0')
   10241              :                   {
   10242            0 :                   invalid_exclusion:
   10243            0 :                     fatal_error (input_location,
   10244              :                                  "multilib exclusion %qs is invalid",
   10245              :                                  multilib_exclusions);
   10246              :                   }
   10247              : 
   10248            0 :                 if (! m)
   10249              :                   {
   10250            0 :                     ++e;
   10251            0 :                     continue;
   10252              :                   }
   10253              : 
   10254              :                 this_arg = e;
   10255              : 
   10256            0 :                 while (*e != ' ' && *e != ';')
   10257              :                   {
   10258            0 :                     if (*e == '\0')
   10259            0 :                       goto invalid_exclusion;
   10260            0 :                     ++e;
   10261              :                   }
   10262              : 
   10263            0 :                 q = p + 1;
   10264            0 :                 while (*q != ';')
   10265              :                   {
   10266            0 :                     const char *arg;
   10267            0 :                     int len = e - this_arg;
   10268              : 
   10269            0 :                     if (*q == '\0')
   10270            0 :                       goto invalid_select;
   10271              : 
   10272              :                     arg = q;
   10273              : 
   10274            0 :                     while (*q != ' ' && *q != ';')
   10275              :                       {
   10276            0 :                         if (*q == '\0')
   10277            0 :                           goto invalid_select;
   10278            0 :                         ++q;
   10279              :                       }
   10280              : 
   10281            0 :                     if (! strncmp (arg, this_arg,
   10282            0 :                                    (len < q - arg) ? q - arg : len)
   10283            0 :                         || default_arg (this_arg, e - this_arg))
   10284              :                       {
   10285              :                         mp = 1;
   10286              :                         break;
   10287              :                       }
   10288              : 
   10289            0 :                     if (*q == ' ')
   10290            0 :                       ++q;
   10291              :                   }
   10292              : 
   10293            0 :                 if (! mp)
   10294            0 :                   m = 0;
   10295              : 
   10296            0 :                 if (*e == ' ')
   10297            0 :                   ++e;
   10298              :               }
   10299              : 
   10300            0 :             if (m)
   10301              :               {
   10302              :                 skip = 1;
   10303              :                 break;
   10304              :               }
   10305              : 
   10306            0 :             if (*e != '\0')
   10307            0 :               ++e;
   10308              :           }
   10309              :       }
   10310              : 
   10311        12021 :       if (! skip)
   10312              :         {
   10313              :           /* If this is a duplicate, skip it.  */
   10314        24042 :           skip = (last_path != 0
   10315         8014 :                   && (unsigned int) (p - this_path) == last_path_len
   10316        12021 :                   && ! filename_ncmp (last_path, this_path, last_path_len));
   10317              : 
   10318        12021 :           last_path = this_path;
   10319        12021 :           last_path_len = p - this_path;
   10320              :         }
   10321              : 
   10322              :       /* If all required arguments are default arguments, and no default
   10323              :          arguments appear in the ! argument list, then we can skip it.
   10324              :          We will already have printed a directory identical to this one
   10325              :          which does not require that default argument.  */
   10326        12021 :       if (! skip)
   10327              :         {
   10328        12021 :           const char *q;
   10329        12021 :           bool default_arg_ok = false;
   10330              : 
   10331        12021 :           q = p + 1;
   10332        20035 :           while (*q != ';')
   10333              :             {
   10334        16028 :               const char *arg;
   10335              : 
   10336        16028 :               if (*q == '\0')
   10337            0 :                 goto invalid_select;
   10338              : 
   10339        16028 :               if (*q == '!')
   10340              :                 {
   10341        12021 :                   not_arg = 1;
   10342        12021 :                   q++;
   10343              :                 }
   10344              :               else
   10345              :                 not_arg = 0;
   10346        16028 :               arg = q;
   10347              : 
   10348        64112 :               while (*q != ' ' && *q != ';')
   10349              :                 {
   10350        48084 :                   if (*q == '\0')
   10351            0 :                     goto invalid_select;
   10352        48084 :                   ++q;
   10353              :                 }
   10354              : 
   10355        16028 :               if (default_arg (arg, q - arg))
   10356              :                 {
   10357              :                   /* Stop checking if any default arguments appeared in not
   10358              :                      list.  */
   10359        12021 :                   if (not_arg)
   10360              :                     {
   10361              :                       default_arg_ok = false;
   10362              :                       break;
   10363              :                     }
   10364              : 
   10365              :                   default_arg_ok = true;
   10366              :                 }
   10367         4007 :               else if (!not_arg)
   10368              :                 {
   10369              :                   /* Stop checking if any required argument is not provided by
   10370              :                      default arguments.  */
   10371              :                   default_arg_ok = false;
   10372              :                   break;
   10373              :                 }
   10374              : 
   10375         8014 :               if (*q == ' ')
   10376         4007 :                 ++q;
   10377              :             }
   10378              : 
   10379              :           /* Make sure all default argument is OK for this multi-lib set.  */
   10380        12021 :           if (default_arg_ok)
   10381              :             skip = 1;
   10382              :           else
   10383              :             skip = 0;
   10384              :         }
   10385              : 
   10386              :       if (! skip)
   10387              :         {
   10388              :           const char *p1;
   10389              : 
   10390        20035 :           for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
   10391        12021 :             putchar (*p1);
   10392         8014 :           putchar (';');
   10393              :         }
   10394              : 
   10395        12021 :       ++p;
   10396        60105 :       while (*p != ';')
   10397              :         {
   10398        48084 :           int use_arg;
   10399              : 
   10400        48084 :           if (*p == '\0')
   10401            0 :             goto invalid_select;
   10402              : 
   10403        48084 :           if (skip)
   10404              :             {
   10405        32056 :               ++p;
   10406        32056 :               continue;
   10407              :             }
   10408              : 
   10409        16028 :           use_arg = *p != '!';
   10410              : 
   10411        16028 :           if (use_arg)
   10412         4007 :             putchar ('@');
   10413              : 
   10414        76133 :           while (*p != ' ' && *p != ';')
   10415              :             {
   10416        60105 :               if (*p == '\0')
   10417            0 :                 goto invalid_select;
   10418        60105 :               if (use_arg)
   10419        12021 :                 putchar (*p);
   10420        60105 :               ++p;
   10421              :             }
   10422              : 
   10423        16028 :           if (*p == ' ')
   10424         8014 :             ++p;
   10425              :         }
   10426              : 
   10427        12021 :       if (! skip)
   10428              :         {
   10429              :           /* If there are extra options, print them now.  */
   10430         8014 :           if (multilib_extra && *multilib_extra)
   10431              :             {
   10432              :               int print_at = true;
   10433              :               const char *q;
   10434              : 
   10435            0 :               for (q = multilib_extra; *q != '\0'; q++)
   10436              :                 {
   10437            0 :                   if (*q == ' ')
   10438              :                     print_at = true;
   10439              :                   else
   10440              :                     {
   10441            0 :                       if (print_at)
   10442            0 :                         putchar ('@');
   10443            0 :                       putchar (*q);
   10444            0 :                       print_at = false;
   10445              :                     }
   10446              :                 }
   10447              :             }
   10448              : 
   10449         8014 :           putchar ('\n');
   10450              :         }
   10451              : 
   10452        12021 :       ++p;
   10453              :     }
   10454         4007 : }
   10455              : 
   10456              : /* getenv built-in spec function.
   10457              : 
   10458              :    Returns the value of the environment variable given by its first argument,
   10459              :    concatenated with the second argument.  If the variable is not defined, a
   10460              :    fatal error is issued unless such undefs are internally allowed, in which
   10461              :    case the variable name prefixed by a '/' is used as the variable value.
   10462              : 
   10463              :    The leading '/' allows using the result at a spot where a full path would
   10464              :    normally be expected and when the actual value doesn't really matter since
   10465              :    undef vars are allowed.  */
   10466              : 
   10467              : static const char *
   10468            0 : getenv_spec_function (int argc, const char **argv)
   10469              : {
   10470            0 :   const char *value;
   10471            0 :   const char *varname;
   10472              : 
   10473            0 :   char *result;
   10474            0 :   char *ptr;
   10475            0 :   size_t len;
   10476              : 
   10477            0 :   if (argc != 2)
   10478              :     return NULL;
   10479              : 
   10480            0 :   varname = argv[0];
   10481            0 :   value = env.get (varname);
   10482              : 
   10483              :   /* If the variable isn't defined and this is allowed, craft our expected
   10484              :      return value.  Assume variable names used in specs strings don't contain
   10485              :      any active spec character so don't need escaping.  */
   10486            0 :   if (!value && spec_undefvar_allowed)
   10487              :     {
   10488            0 :       result = XNEWVAR (char, strlen(varname) + 2);
   10489            0 :       sprintf (result, "/%s", varname);
   10490            0 :       return result;
   10491              :     }
   10492              : 
   10493            0 :   if (!value)
   10494            0 :     fatal_error (input_location,
   10495              :                  "environment variable %qs not defined", varname);
   10496              : 
   10497              :   /* We have to escape every character of the environment variable so
   10498              :      they are not interpreted as active spec characters.  A
   10499              :      particularly painful case is when we are reading a variable
   10500              :      holding a windows path complete with \ separators.  */
   10501            0 :   len = strlen (value) * 2 + strlen (argv[1]) + 1;
   10502            0 :   result = XNEWVAR (char, len);
   10503            0 :   for (ptr = result; *value; ptr += 2)
   10504              :     {
   10505            0 :       ptr[0] = '\\';
   10506            0 :       ptr[1] = *value++;
   10507              :     }
   10508              : 
   10509            0 :   strcpy (ptr, argv[1]);
   10510              : 
   10511            0 :   return result;
   10512              : }
   10513              : 
   10514              : /* if-exists built-in spec function.
   10515              : 
   10516              :    Checks to see if the file specified by the absolute pathname in
   10517              :    ARGS exists.  Returns that pathname if found.
   10518              : 
   10519              :    The usual use for this function is to check for a library file
   10520              :    (whose name has been expanded with %s).  */
   10521              : 
   10522              : static const char *
   10523            0 : if_exists_spec_function (int argc, const char **argv)
   10524              : {
   10525              :   /* Must have only one argument.  */
   10526            0 :   if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10527            0 :     return argv[0];
   10528              : 
   10529              :   return NULL;
   10530              : }
   10531              : 
   10532              : /* if-exists-else built-in spec function.
   10533              : 
   10534              :    This is like if-exists, but takes an additional argument which
   10535              :    is returned if the first argument does not exist.  */
   10536              : 
   10537              : static const char *
   10538            0 : if_exists_else_spec_function (int argc, const char **argv)
   10539              : {
   10540              :   /* Must have exactly two arguments.  */
   10541            0 :   if (argc != 2)
   10542              :     return NULL;
   10543              : 
   10544            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10545            0 :     return argv[0];
   10546              : 
   10547            0 :   return argv[1];
   10548              : }
   10549              : 
   10550              : /* if-exists-then-else built-in spec function.
   10551              : 
   10552              :    Checks to see if the file specified by the absolute pathname in
   10553              :    the first arg exists.  Returns the second arg if so, otherwise returns
   10554              :    the third arg if it is present.  */
   10555              : 
   10556              : static const char *
   10557            0 : if_exists_then_else_spec_function (int argc, const char **argv)
   10558              : {
   10559              : 
   10560              :   /* Must have two or three arguments.  */
   10561            0 :   if (argc != 2 && argc != 3)
   10562              :     return NULL;
   10563              : 
   10564            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10565            0 :     return argv[1];
   10566              : 
   10567            0 :   if (argc == 3)
   10568            0 :     return argv[2];
   10569              : 
   10570              :   return NULL;
   10571              : }
   10572              : 
   10573              : /* sanitize built-in spec function.
   10574              : 
   10575              :    This returns non-NULL, if sanitizing address, thread or
   10576              :    any of the undefined behavior sanitizers.  */
   10577              : 
   10578              : static const char *
   10579       852552 : sanitize_spec_function (int argc, const char **argv)
   10580              : {
   10581       852552 :   if (argc != 1)
   10582              :     return NULL;
   10583              : 
   10584       852552 :   if (strcmp (argv[0], "address") == 0)
   10585       376322 :     return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL;
   10586       663096 :   if (strcmp (argv[0], "hwaddress") == 0)
   10587       378716 :     return (flag_sanitize & SANITIZE_USER_HWADDRESS) ? "" : NULL;
   10588       473640 :   if (strcmp (argv[0], "kernel-address") == 0)
   10589            0 :     return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL;
   10590       473640 :   if (strcmp (argv[0], "kernel-hwaddress") == 0)
   10591            0 :     return (flag_sanitize & SANITIZE_KERNEL_HWADDRESS) ? "" : NULL;
   10592       473640 :   if (strcmp (argv[0], "memtag-stack") == 0)
   10593            0 :     return (flag_sanitize & SANITIZE_MEMTAG_STACK) ? "" : NULL;
   10594       473640 :   if (strcmp (argv[0], "thread") == 0)
   10595       378512 :     return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
   10596       284184 :   if (strcmp (argv[0], "undefined") == 0)
   10597        94728 :     return ((flag_sanitize
   10598        94728 :              & ~flag_sanitize_trap
   10599        94728 :              & (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)))
   10600       187589 :            ? "" : NULL;
   10601       189456 :   if (strcmp (argv[0], "leak") == 0)
   10602       189456 :     return ((flag_sanitize
   10603       189456 :              & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
   10604       378912 :             == SANITIZE_LEAK) ? "" : NULL;
   10605              :   return NULL;
   10606              : }
   10607              : 
   10608              : /* replace-outfile built-in spec function.
   10609              : 
   10610              :    This looks for the first argument in the outfiles array's name and
   10611              :    replaces it with the second argument.  */
   10612              : 
   10613              : static const char *
   10614            0 : replace_outfile_spec_function (int argc, const char **argv)
   10615              : {
   10616            0 :   int i;
   10617              :   /* Must have exactly two arguments.  */
   10618            0 :   if (argc != 2)
   10619            0 :     abort ();
   10620              : 
   10621            0 :   for (i = 0; i < n_infiles; i++)
   10622              :     {
   10623            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10624            0 :         outfiles[i] = xstrdup (argv[1]);
   10625              :     }
   10626            0 :   return NULL;
   10627              : }
   10628              : 
   10629              : /* remove-outfile built-in spec function.
   10630              :  *
   10631              :  *    This looks for the first argument in the outfiles array's name and
   10632              :  *       removes it.  */
   10633              : 
   10634              : static const char *
   10635            0 : remove_outfile_spec_function (int argc, const char **argv)
   10636              : {
   10637            0 :   int i;
   10638              :   /* Must have exactly one argument.  */
   10639            0 :   if (argc != 1)
   10640            0 :     abort ();
   10641              : 
   10642            0 :   for (i = 0; i < n_infiles; i++)
   10643              :     {
   10644            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10645            0 :         outfiles[i] = NULL;
   10646              :     }
   10647            0 :   return NULL;
   10648              : }
   10649              : 
   10650              : /* Given two version numbers, compares the two numbers.
   10651              :    A version number must match the regular expression
   10652              :    ([1-9][0-9]*|0)(\.([1-9][0-9]*|0))*
   10653              : */
   10654              : static int
   10655            0 : compare_version_strings (const char *v1, const char *v2)
   10656              : {
   10657            0 :   int rresult;
   10658            0 :   regex_t r;
   10659              : 
   10660            0 :   if (regcomp (&r, "^([1-9][0-9]*|0)(\\.([1-9][0-9]*|0))*$",
   10661              :                REG_EXTENDED | REG_NOSUB) != 0)
   10662            0 :     abort ();
   10663            0 :   rresult = regexec (&r, v1, 0, NULL, 0);
   10664            0 :   if (rresult == REG_NOMATCH)
   10665            0 :     fatal_error (input_location, "invalid version number %qs", v1);
   10666            0 :   else if (rresult != 0)
   10667            0 :     abort ();
   10668            0 :   rresult = regexec (&r, v2, 0, NULL, 0);
   10669            0 :   if (rresult == REG_NOMATCH)
   10670            0 :     fatal_error (input_location, "invalid version number %qs", v2);
   10671            0 :   else if (rresult != 0)
   10672            0 :     abort ();
   10673              : 
   10674            0 :   return strverscmp (v1, v2);
   10675              : }
   10676              : 
   10677              : 
   10678              : /* version_compare built-in spec function.
   10679              : 
   10680              :    This takes an argument of the following form:
   10681              : 
   10682              :    <comparison-op> <arg1> [<arg2>] <switch> <result>
   10683              : 
   10684              :    and produces "result" if the comparison evaluates to true,
   10685              :    and nothing if it doesn't.
   10686              : 
   10687              :    The supported <comparison-op> values are:
   10688              : 
   10689              :    >=  true if switch is a later (or same) version than arg1
   10690              :    !>  opposite of >=
   10691              :    <   true if switch is an earlier version than arg1
   10692              :    !<  opposite of <
   10693              :    ><  true if switch is arg1 or later, and earlier than arg2
   10694              :    <>  true if switch is earlier than arg1 or is arg2 or later
   10695              : 
   10696              :    If the switch is not present, the condition is false unless
   10697              :    the first character of the <comparison-op> is '!'.
   10698              : 
   10699              :    For example,
   10700              :    %:version-compare(>= 10.3 mmacosx-version-min= -lmx)
   10701              :    adds -lmx if -mmacosx-version-min=10.3.9 was passed.  */
   10702              : 
   10703              : static const char *
   10704            0 : version_compare_spec_function (int argc, const char **argv)
   10705              : {
   10706            0 :   int comp1, comp2;
   10707            0 :   size_t switch_len;
   10708            0 :   const char *switch_value = NULL;
   10709            0 :   int nargs = 1, i;
   10710            0 :   bool result;
   10711              : 
   10712            0 :   if (argc < 3)
   10713            0 :     fatal_error (input_location, "too few arguments to %%:version-compare");
   10714            0 :   if (argv[0][0] == '\0')
   10715            0 :     abort ();
   10716            0 :   if ((argv[0][1] == '<' || argv[0][1] == '>') && argv[0][0] != '!')
   10717            0 :     nargs = 2;
   10718            0 :   if (argc != nargs + 3)
   10719            0 :     fatal_error (input_location, "too many arguments to %%:version-compare");
   10720              : 
   10721            0 :   switch_len = strlen (argv[nargs + 1]);
   10722            0 :   for (i = 0; i < n_switches; i++)
   10723            0 :     if (!strncmp (switches[i].part1, argv[nargs + 1], switch_len)
   10724            0 :         && check_live_switch (i, switch_len))
   10725            0 :       switch_value = switches[i].part1 + switch_len;
   10726              : 
   10727            0 :   if (switch_value == NULL)
   10728              :     comp1 = comp2 = -1;
   10729              :   else
   10730              :     {
   10731            0 :       comp1 = compare_version_strings (switch_value, argv[1]);
   10732            0 :       if (nargs == 2)
   10733            0 :         comp2 = compare_version_strings (switch_value, argv[2]);
   10734              :       else
   10735              :         comp2 = -1;  /* This value unused.  */
   10736              :     }
   10737              : 
   10738            0 :   switch (argv[0][0] << 8 | argv[0][1])
   10739              :     {
   10740            0 :     case '>' << 8 | '=':
   10741            0 :       result = comp1 >= 0;
   10742            0 :       break;
   10743            0 :     case '!' << 8 | '<':
   10744            0 :       result = comp1 >= 0 || switch_value == NULL;
   10745            0 :       break;
   10746            0 :     case '<' << 8:
   10747            0 :       result = comp1 < 0;
   10748            0 :       break;
   10749            0 :     case '!' << 8 | '>':
   10750            0 :       result = comp1 < 0 || switch_value == NULL;
   10751            0 :       break;
   10752            0 :     case '>' << 8 | '<':
   10753            0 :       result = comp1 >= 0 && comp2 < 0;
   10754            0 :       break;
   10755            0 :     case '<' << 8 | '>':
   10756            0 :       result = comp1 < 0 || comp2 >= 0;
   10757            0 :       break;
   10758              : 
   10759            0 :     default:
   10760            0 :       fatal_error (input_location,
   10761              :                    "unknown operator %qs in %%:version-compare", argv[0]);
   10762              :     }
   10763            0 :   if (! result)
   10764              :     return NULL;
   10765              : 
   10766            0 :   return argv[nargs + 2];
   10767              : }
   10768              : 
   10769              : /* %:include builtin spec function.  This differs from %include in that it
   10770              :    can be nested inside a spec, and thus be conditionalized.  It takes
   10771              :    one argument, the filename, and looks for it in the startfile path.
   10772              :    The result is always NULL, i.e. an empty expansion.  */
   10773              : 
   10774              : static const char *
   10775        31052 : include_spec_function (int argc, const char **argv)
   10776              : {
   10777        31052 :   char *file;
   10778              : 
   10779        31052 :   if (argc != 1)
   10780            0 :     abort ();
   10781              : 
   10782        31052 :   file = find_a_file (&startfile_prefixes, argv[0], R_OK, true);
   10783        31052 :   read_specs (file ? file : argv[0], false, false);
   10784              : 
   10785        31052 :   return NULL;
   10786              : }
   10787              : 
   10788              : /* %:find-file spec function.  This function replaces its argument by
   10789              :     the file found through find_file, that is the -print-file-name gcc
   10790              :     program option. */
   10791              : static const char *
   10792            0 : find_file_spec_function (int argc, const char **argv)
   10793              : {
   10794            0 :   const char *file;
   10795              : 
   10796            0 :   if (argc != 1)
   10797            0 :     abort ();
   10798              : 
   10799            0 :   file = find_file (argv[0]);
   10800            0 :   return file;
   10801              : }
   10802              : 
   10803              : 
   10804              : /* %:find-plugindir spec function.  This function replaces its argument
   10805              :     by the -iplugindir=<dir> option.  `dir' is found through find_file, that
   10806              :     is the -print-file-name gcc program option. */
   10807              : static const char *
   10808          400 : find_plugindir_spec_function (int argc, const char **argv ATTRIBUTE_UNUSED)
   10809              : {
   10810          400 :   const char *option;
   10811              : 
   10812          400 :   if (argc != 0)
   10813            0 :     abort ();
   10814              : 
   10815          400 :   option = concat ("-iplugindir=", find_file ("plugin"), NULL);
   10816          400 :   return option;
   10817              : }
   10818              : 
   10819              : 
   10820              : /* %:print-asm-header spec function.  Print a banner to say that the
   10821              :    following output is from the assembler.  */
   10822              : 
   10823              : static const char *
   10824            0 : print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
   10825              :                                 const char **argv ATTRIBUTE_UNUSED)
   10826              : {
   10827            0 :   printf (_("Assembler options\n=================\n\n"));
   10828            0 :   printf (_("Use \"-Wa,OPTION\" to pass \"OPTION\" to the assembler.\n\n"));
   10829            0 :   fflush (stdout);
   10830            0 :   return NULL;
   10831              : }
   10832              : 
   10833              : /* Get a random number for -frandom-seed */
   10834              : 
   10835              : static unsigned HOST_WIDE_INT
   10836          620 : get_random_number (void)
   10837              : {
   10838          620 :   unsigned HOST_WIDE_INT ret = 0;
   10839          620 :   int fd;
   10840              : 
   10841          620 :   fd = open ("/dev/urandom", O_RDONLY);
   10842          620 :   if (fd >= 0)
   10843              :     {
   10844          620 :       read (fd, &ret, sizeof (HOST_WIDE_INT));
   10845          620 :       close (fd);
   10846          620 :       if (ret)
   10847              :         return ret;
   10848              :     }
   10849              : 
   10850              :   /* Get some more or less random data.  */
   10851              : #ifdef HAVE_GETTIMEOFDAY
   10852            0 :   {
   10853            0 :     struct timeval tv;
   10854              : 
   10855            0 :     gettimeofday (&tv, NULL);
   10856            0 :     ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
   10857              :   }
   10858              : #else
   10859              :   {
   10860              :     time_t now = time (NULL);
   10861              : 
   10862              :     if (now != (time_t)-1)
   10863              :       ret = (unsigned) now;
   10864              :   }
   10865              : #endif
   10866              : 
   10867            0 :   return ret ^ getpid ();
   10868              : }
   10869              : 
   10870              : /* %:compare-debug-dump-opt spec function.  Save the last argument,
   10871              :    expected to be the last -fdump-final-insns option, or generate a
   10872              :    temporary.  */
   10873              : 
   10874              : static const char *
   10875         1233 : compare_debug_dump_opt_spec_function (int arg,
   10876              :                                       const char **argv ATTRIBUTE_UNUSED)
   10877              : {
   10878         1233 :   char *ret;
   10879         1233 :   char *name;
   10880         1233 :   int which;
   10881         1233 :   static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
   10882              : 
   10883         1233 :   if (arg != 0)
   10884            0 :     fatal_error (input_location,
   10885              :                  "too many arguments to %%:compare-debug-dump-opt");
   10886              : 
   10887         1233 :   do_spec_2 ("%{fdump-final-insns=*:%*}", NULL);
   10888         1233 :   do_spec_1 (" ", 0, NULL);
   10889              : 
   10890         1233 :   if (argbuf.length () > 0
   10891         1233 :       && strcmp (argv[argbuf.length () - 1], ".") != 0)
   10892              :     {
   10893            0 :       if (!compare_debug)
   10894              :         return NULL;
   10895              : 
   10896            0 :       name = xstrdup (argv[argbuf.length () - 1]);
   10897            0 :       ret = NULL;
   10898              :     }
   10899              :   else
   10900              :     {
   10901         1233 :       if (argbuf.length () > 0)
   10902            6 :         do_spec_2 ("%B.gkd", NULL);
   10903         1227 :       else if (!compare_debug)
   10904              :         return NULL;
   10905              :       else
   10906         1227 :         do_spec_2 ("%{!save-temps*:%g.gkd}%{save-temps*:%B.gkd}", NULL);
   10907              : 
   10908         1233 :       do_spec_1 (" ", 0, NULL);
   10909              : 
   10910         1233 :       gcc_assert (argbuf.length () > 0);
   10911              : 
   10912         1233 :       name = xstrdup (argbuf.last ());
   10913              : 
   10914         1233 :       char *arg = quote_spec (xstrdup (name));
   10915         1233 :       ret = concat ("-fdump-final-insns=", arg, NULL);
   10916         1233 :       free (arg);
   10917              :     }
   10918              : 
   10919         1233 :   which = compare_debug < 0;
   10920         1233 :   debug_check_temp_file[which] = name;
   10921              : 
   10922         1233 :   if (!which)
   10923              :     {
   10924          620 :       unsigned HOST_WIDE_INT value = get_random_number ();
   10925              : 
   10926          620 :       sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
   10927              :     }
   10928              : 
   10929         1233 :   if (*random_seed)
   10930              :     {
   10931         1233 :       char *tmp = ret;
   10932         1233 :       ret = concat ("%{!frandom-seed=*:-frandom-seed=", random_seed, "} ",
   10933              :                     ret, NULL);
   10934         1233 :       free (tmp);
   10935              :     }
   10936              : 
   10937         1233 :   if (which)
   10938          613 :     *random_seed = 0;
   10939              : 
   10940              :   return ret;
   10941              : }
   10942              : 
   10943              : /* %:compare-debug-self-opt spec function.  Expands to the options
   10944              :     that are to be passed in the second compilation of
   10945              :     compare-debug.  */
   10946              : 
   10947              : static const char *
   10948         1238 : compare_debug_self_opt_spec_function (int arg,
   10949              :                                       const char **argv ATTRIBUTE_UNUSED)
   10950              : {
   10951         1238 :   if (arg != 0)
   10952            0 :     fatal_error (input_location,
   10953              :                  "too many arguments to %%:compare-debug-self-opt");
   10954              : 
   10955         1238 :   if (compare_debug >= 0)
   10956              :     return NULL;
   10957              : 
   10958          619 :   return concat ("\
   10959              : %<o %<MD %<MMD %<MF* %<MG %<MP %<MQ* %<MT* \
   10960              : %<fdump-final-insns=* -w -S -o %j \
   10961              : %{!fcompare-debug-second:-fcompare-debug-second} \
   10962          619 : ", compare_debug_opt, NULL);
   10963              : }
   10964              : 
   10965              : /* %:pass-through-libs spec function.  Finds all -l options and input
   10966              :    file names in the lib spec passed to it, and makes a list of them
   10967              :    prepended with the plugin option to cause them to be passed through
   10968              :    to the final link after all the new object files have been added.  */
   10969              : 
   10970              : const char *
   10971        89247 : pass_through_libs_spec_func (int argc, const char **argv)
   10972              : {
   10973        89247 :   char *prepended = xstrdup (" ");
   10974        89247 :   int n;
   10975              :   /* Shlemiel the painter's algorithm.  Innately horrible, but at least
   10976              :      we know that there will never be more than a handful of strings to
   10977              :      concat, and it's only once per run, so it's not worth optimising.  */
   10978       716041 :   for (n = 0; n < argc; n++)
   10979              :     {
   10980       626794 :       char *old = prepended;
   10981              :       /* Anything that isn't an option is a full path to an output
   10982              :          file; pass it through if it ends in '.a'.  Among options,
   10983              :          pass only -l.  */
   10984       626794 :       if (argv[n][0] == '-' && argv[n][1] == 'l')
   10985              :         {
   10986       584044 :           const char *lopt = argv[n] + 2;
   10987              :           /* Handle both joined and non-joined -l options.  If for any
   10988              :              reason there's a trailing -l with no joined or following
   10989              :              arg just discard it.  */
   10990       584044 :           if (!*lopt && ++n >= argc)
   10991              :             break;
   10992       584044 :           else if (!*lopt)
   10993            0 :             lopt = argv[n];
   10994       584044 :           prepended = concat (prepended, "-plugin-opt=-pass-through=-l",
   10995              :                 lopt, " ", NULL);
   10996       584044 :         }
   10997        42750 :       else if (!strcmp (".a", argv[n] + strlen (argv[n]) - 2))
   10998              :         {
   10999            0 :           prepended = concat (prepended, "-plugin-opt=-pass-through=",
   11000              :                 argv[n], " ", NULL);
   11001              :         }
   11002       626794 :       if (prepended != old)
   11003       584044 :         free (old);
   11004              :     }
   11005        89247 :   return prepended;
   11006              : }
   11007              : 
   11008              : static bool
   11009       514331 : not_actual_file_p (const char *name)
   11010              : {
   11011       514331 :   return (strcmp (name, "-") == 0
   11012       514331 :           || strcmp (name, HOST_BIT_BUCKET) == 0);
   11013              : }
   11014              : 
   11015              : /* %:dumps spec function.  Take an optional argument that overrides
   11016              :    the default extension for -dumpbase and -dumpbase-ext.
   11017              :    Return -dumpdir, -dumpbase and -dumpbase-ext, if needed.  */
   11018              : const char *
   11019       280714 : dumps_spec_func (int argc, const char **argv ATTRIBUTE_UNUSED)
   11020              : {
   11021       280714 :   const char *ext = dumpbase_ext;
   11022       280714 :   char *p;
   11023              : 
   11024       280714 :   char *args[3] = { NULL, NULL, NULL };
   11025       280714 :   int nargs = 0;
   11026              : 
   11027              :   /* Do not compute a default for -dumpbase-ext when -dumpbase was
   11028              :      given explicitly.  */
   11029       280714 :   if (dumpbase && *dumpbase && !ext)
   11030       280714 :     ext = "";
   11031              : 
   11032       280714 :   if (argc == 1)
   11033              :     {
   11034              :       /* Do not override the explicitly-specified -dumpbase-ext with
   11035              :          the specs-provided overrider.  */
   11036            0 :       if (!ext)
   11037            0 :         ext = argv[0];
   11038              :     }
   11039       280714 :   else if (argc != 0)
   11040            0 :     fatal_error (input_location, "too many arguments for %%:dumps");
   11041              : 
   11042       280714 :   if (dumpdir)
   11043              :     {
   11044       105896 :       p = quote_spec_arg (xstrdup (dumpdir));
   11045       105896 :       args[nargs++] = concat (" -dumpdir ", p, NULL);
   11046       105896 :       free (p);
   11047              :     }
   11048              : 
   11049       280714 :   if (!ext)
   11050       260471 :     ext = input_basename + basename_length;
   11051              : 
   11052              :   /* Use the precomputed outbase, or compute dumpbase from
   11053              :      input_basename, just like %b would.  */
   11054       280714 :   char *base;
   11055              : 
   11056       280714 :   if (dumpbase && *dumpbase)
   11057              :     {
   11058        20243 :       base = xstrdup (dumpbase);
   11059        20243 :       p = base + outbase_length;
   11060        20243 :       gcc_checking_assert (strncmp (base, outbase, outbase_length) == 0);
   11061        20243 :       gcc_checking_assert (strcmp (p, ext) == 0);
   11062              :     }
   11063       260471 :   else if (outbase_length)
   11064              :     {
   11065       161017 :       base = xstrndup (outbase, outbase_length);
   11066       161017 :       p = NULL;
   11067              :     }
   11068              :   else
   11069              :     {
   11070        99454 :       base = xstrndup (input_basename, suffixed_basename_length);
   11071        99454 :       p = base + basename_length;
   11072              :     }
   11073              : 
   11074       280714 :   if (compare_debug < 0 || !p || strcmp (p, ext) != 0)
   11075              :     {
   11076          613 :       if (p)
   11077            9 :         *p = '\0';
   11078              : 
   11079       161026 :       const char *gk;
   11080       161026 :       if (compare_debug < 0)
   11081              :         gk = ".gk";
   11082              :       else
   11083       160413 :         gk = "";
   11084              : 
   11085       161026 :       p = concat (base, gk, ext, NULL);
   11086              : 
   11087       161026 :       free (base);
   11088       161026 :       base = p;
   11089              :     }
   11090              : 
   11091       280714 :   base = quote_spec_arg (base);
   11092       280714 :   args[nargs++] = concat (" -dumpbase ", base, NULL);
   11093       280714 :   free (base);
   11094              : 
   11095       280714 :   if (*ext)
   11096              :     {
   11097       259429 :       p = quote_spec_arg (xstrdup (ext));
   11098       259429 :       args[nargs++] = concat (" -dumpbase-ext ", p, NULL);
   11099       259429 :       free (p);
   11100              :     }
   11101              : 
   11102       280714 :   const char *ret = concat (args[0], args[1], args[2], NULL);
   11103      1207467 :   while (nargs > 0)
   11104       646039 :     free (args[--nargs]);
   11105              : 
   11106       280714 :   return ret;
   11107              : }
   11108              : 
   11109              : /* Returns "" if ARGV[ARGC - 2] is greater than ARGV[ARGC-1].
   11110              :    Otherwise, return NULL.  */
   11111              : 
   11112              : static const char *
   11113       388635 : greater_than_spec_func (int argc, const char **argv)
   11114              : {
   11115       388635 :   char *converted;
   11116              : 
   11117       388635 :   if (argc == 1)
   11118              :     return NULL;
   11119              : 
   11120          252 :   gcc_assert (argc >= 2);
   11121              : 
   11122          252 :   long arg = strtol (argv[argc - 2], &converted, 10);
   11123          252 :   gcc_assert (converted != argv[argc - 2]);
   11124              : 
   11125          252 :   long lim = strtol (argv[argc - 1], &converted, 10);
   11126          252 :   gcc_assert (converted != argv[argc - 1]);
   11127              : 
   11128          252 :   if (arg > lim)
   11129              :     return "";
   11130              : 
   11131              :   return NULL;
   11132              : }
   11133              : 
   11134              : /* Returns "" if debug_info_level is greater than ARGV[ARGC-1].
   11135              :    Otherwise, return NULL.  */
   11136              : 
   11137              : static const char *
   11138       251539 : debug_level_greater_than_spec_func (int argc, const char **argv)
   11139              : {
   11140       251539 :   char *converted;
   11141              : 
   11142       251539 :   if (argc != 1)
   11143            0 :     fatal_error (input_location,
   11144              :                  "wrong number of arguments to %%:debug-level-gt");
   11145              : 
   11146       251539 :   long arg = strtol (argv[0], &converted, 10);
   11147       251539 :   gcc_assert (converted != argv[0]);
   11148              : 
   11149       251539 :   if (debug_info_level > arg)
   11150        45144 :     return "";
   11151              : 
   11152              :   return NULL;
   11153              : }
   11154              : 
   11155              : /* Returns "" if dwarf_version is greater than ARGV[ARGC-1].
   11156              :    Otherwise, return NULL.  */
   11157              : 
   11158              : static const char *
   11159       127896 : dwarf_version_greater_than_spec_func (int argc, const char **argv)
   11160              : {
   11161       127896 :   char *converted;
   11162              : 
   11163       127896 :   if (argc != 1)
   11164            0 :     fatal_error (input_location,
   11165              :                  "wrong number of arguments to %%:dwarf-version-gt");
   11166              : 
   11167       127896 :   long arg = strtol (argv[0], &converted, 10);
   11168       127896 :   gcc_assert (converted != argv[0]);
   11169              : 
   11170       127896 :   if (dwarf_version > arg)
   11171       127025 :     return "";
   11172              : 
   11173              :   return NULL;
   11174              : }
   11175              : 
   11176              : static void
   11177        34688 : path_prefix_reset (path_prefix *prefix)
   11178              : {
   11179        34688 :   struct prefix_list *iter, *next;
   11180        34688 :   iter = prefix->plist;
   11181       137618 :   while (iter)
   11182              :     {
   11183       102930 :       next = iter->next;
   11184       102930 :       free (const_cast <char *> (iter->prefix));
   11185       102930 :       XDELETE (iter);
   11186       102930 :       iter = next;
   11187              :     }
   11188        34688 :   prefix->plist = 0;
   11189        34688 :   prefix->max_len = 0;
   11190        34688 : }
   11191              : 
   11192              : /* The function takes 3 arguments: OPTION name, file name and location
   11193              :    where we search for Fortran modules.
   11194              :    When the FILE is found by find_file, return OPTION=path_to_file.  */
   11195              : 
   11196              : static const char *
   11197        31286 : find_fortran_preinclude_file (int argc, const char **argv)
   11198              : {
   11199        31286 :   char *result = NULL;
   11200        31286 :   if (argc != 3)
   11201              :     return NULL;
   11202              : 
   11203        31286 :   struct path_prefix prefixes = { 0, 0, "preinclude" };
   11204              : 
   11205              :   /* Search first for 'finclude' folder location for a header file
   11206              :      installed by the compiler (similar to omp_lib.h).  */
   11207        31286 :   add_prefix (&prefixes, argv[2], NULL, 0, 0, 0);
   11208              : #ifdef TOOL_INCLUDE_DIR
   11209              :   /* Then search: <prefix>/<target>/<include>/finclude */
   11210        31286 :   add_prefix (&prefixes, TOOL_INCLUDE_DIR "/finclude/",
   11211              :               NULL, 0, 0, 0);
   11212              : #endif
   11213              : #ifdef NATIVE_SYSTEM_HEADER_DIR
   11214              :   /* Then search: <sysroot>/usr/include/finclude/<multilib> */
   11215        31286 :   add_sysrooted_hdrs_prefix (&prefixes, NATIVE_SYSTEM_HEADER_DIR "/finclude/",
   11216              :                              NULL, 0, 0, 0);
   11217              : #endif
   11218              : 
   11219        31286 :   const char *path = find_a_file (&include_prefixes, argv[1], R_OK, false);
   11220        31286 :   if (path != NULL)
   11221            0 :     result = concat (argv[0], path, NULL);
   11222              :   else
   11223              :     {
   11224        31286 :       path = find_a_file (&prefixes, argv[1], R_OK, false);
   11225        31286 :       if (path != NULL)
   11226        31286 :         result = concat (argv[0], path, NULL);
   11227              :     }
   11228              : 
   11229        31286 :   path_prefix_reset (&prefixes);
   11230        31286 :   return result;
   11231              : }
   11232              : 
   11233              : /* The function takes any number of arguments and joins them together,
   11234              :    escaping any special characters.
   11235              : 
   11236              :    This seems to be necessary to build "-fjoined=foo.b" from "-fseparate foo.a"
   11237              :    with a %{fseparate*:-fjoined=%.b$*} rule without adding undesired spaces:
   11238              :    when doing $* replacement we first replace $* with the rest of the switch
   11239              :    (in this case ""), and then add any arguments as arguments after the result,
   11240              :    resulting in "-fjoined= foo.b".  Using this function with e.g.
   11241              :    %{fseparate*:-fjoined=%:join(%.b$*)} gets multiple words as separate argv
   11242              :    elements instead of separated by spaces, and we paste them together.  */
   11243              : 
   11244              : static const char *
   11245           39 : join_spec_func (int argc, const char **argv)
   11246              : {
   11247           39 :   const char *result = argv[0];
   11248           39 :   if (argc != 1)
   11249              :     {
   11250          117 :       for (int i = 0; i < argc; ++i)
   11251           78 :         obstack_grow (&obstack, argv[i], strlen (argv[i]));
   11252           39 :       obstack_1grow (&obstack, '\0');
   11253           39 :       result = XOBFINISH (&obstack, const char *);
   11254              :     }
   11255           39 :   return quote_spec (xstrdup (result));
   11256              : }
   11257              : 
   11258              : /* If any character in ORIG fits QUOTE_P (_, P), reallocate the string
   11259              :    so as to precede every one of them with a backslash.  Return the
   11260              :    original string or the reallocated one.  */
   11261              : 
   11262              : static inline char *
   11263       841848 : quote_string (char *orig, bool (*quote_p)(char, void *), void *p)
   11264              : {
   11265       841848 :   int len, number_of_space = 0;
   11266              : 
   11267     19095688 :   for (len = 0; orig[len]; len++)
   11268     18253840 :     if (quote_p (orig[len], p))
   11269            0 :       number_of_space++;
   11270              : 
   11271       841848 :   if (number_of_space)
   11272              :     {
   11273            0 :       char *new_spec = (char *) xmalloc (len + number_of_space + 1);
   11274            0 :       int j, k;
   11275            0 :       for (j = 0, k = 0; j <= len; j++, k++)
   11276              :         {
   11277            0 :           if (quote_p (orig[j], p))
   11278            0 :             new_spec[k++] = '\\';
   11279            0 :           new_spec[k] = orig[j];
   11280              :         }
   11281            0 :       free (orig);
   11282            0 :       return new_spec;
   11283              :     }
   11284              :   else
   11285              :     return orig;
   11286              : }
   11287              : 
   11288              : /* Return true iff C is any of the characters convert_white_space
   11289              :    should quote.  */
   11290              : 
   11291              : static inline bool
   11292     12102281 : whitespace_to_convert_p (char c, void *)
   11293              : {
   11294     12102281 :   return (c == ' ' || c == '\t');
   11295              : }
   11296              : 
   11297              : /* Insert backslash before spaces in ORIG (usually a file path), to
   11298              :    avoid being broken by spec parser.
   11299              : 
   11300              :    This function is needed as do_spec_1 treats white space (' ' and '\t')
   11301              :    as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
   11302              :    the file name should be treated as a single argument rather than being
   11303              :    broken into multiple. Solution is to insert '\\' before the space in a
   11304              :    file name.
   11305              : 
   11306              :    This function converts and only converts all occurrence of ' '
   11307              :    to '\\' + ' ' and '\t' to '\\' + '\t'.  For example:
   11308              :    "a b"  -> "a\\ b"
   11309              :    "a  b" -> "a\\ \\ b"
   11310              :    "a\tb" -> "a\\\tb"
   11311              :    "a\\ b" -> "a\\\\ b"
   11312              : 
   11313              :    orig: input null-terminating string that was allocated by xalloc. The
   11314              :    memory it points to might be freed in this function. Behavior undefined
   11315              :    if ORIG wasn't xalloced or was freed already at entry.
   11316              : 
   11317              :    Return: ORIG if no conversion needed. Otherwise a newly allocated string
   11318              :    that was converted from ORIG.  */
   11319              : 
   11320              : static char *
   11321       194546 : convert_white_space (char *orig)
   11322              : {
   11323       194546 :   return quote_string (orig, whitespace_to_convert_p, NULL);
   11324              : }
   11325              : 
   11326              : /* Return true iff C matches any of the spec active characters.  */
   11327              : static inline bool
   11328      6151559 : quote_spec_char_p (char c, void *)
   11329              : {
   11330      6151559 :   switch (c)
   11331              :     {
   11332              :     case ' ':
   11333              :     case '\t':
   11334              :     case '\n':
   11335              :     case '|':
   11336              :     case '%':
   11337              :     case '\\':
   11338              :       return true;
   11339              : 
   11340      6151559 :     default:
   11341      6151559 :       return false;
   11342              :     }
   11343              : }
   11344              : 
   11345              : /* Like convert_white_space, but deactivate all active spec chars by
   11346              :    quoting them.  */
   11347              : 
   11348              : static inline char *
   11349       647302 : quote_spec (char *orig)
   11350              : {
   11351         1272 :   return quote_string (orig, quote_spec_char_p, NULL);
   11352              : }
   11353              : 
   11354              : /* Like quote_spec, but also turn an empty string into the spec for an
   11355              :    empty argument.  */
   11356              : 
   11357              : static inline char *
   11358       646039 : quote_spec_arg (char *orig)
   11359              : {
   11360       646039 :   if (!*orig)
   11361              :     {
   11362            9 :       free (orig);
   11363            9 :       return xstrdup ("%\"");
   11364              :     }
   11365              : 
   11366       646030 :   return quote_spec (orig);
   11367              : }
   11368              : 
   11369              : /* Restore all state within gcc.cc to the initial state, so that the driver
   11370              :    code can be safely re-run in-process.
   11371              : 
   11372              :    Many const char * variables are referenced by static specs (see
   11373              :    INIT_STATIC_SPEC above).  These variables are restored to their default
   11374              :    values by a simple loop over the static specs.
   11375              : 
   11376              :    For other variables, we directly restore them all to their initial
   11377              :    values (often implicitly 0).
   11378              : 
   11379              :    Free the various obstacks in this file, along with "opts_obstack"
   11380              :    from opts.cc.
   11381              : 
   11382              :    This function also restores any environment variables that were changed.  */
   11383              : 
   11384              : void
   11385         1134 : driver::finalize ()
   11386              : {
   11387         1134 :   env.restore ();
   11388         1134 :   diagnostic_finish (global_dc);
   11389              : 
   11390         1134 :   is_cpp_driver = 0;
   11391         1134 :   at_file_supplied = 0;
   11392         1134 :   print_help_list = 0;
   11393         1134 :   print_version = 0;
   11394         1134 :   verbose_only_flag = 0;
   11395         1134 :   print_subprocess_help = 0;
   11396         1134 :   use_ld = NULL;
   11397         1134 :   report_times_to_file = NULL;
   11398         1134 :   target_system_root = DEFAULT_TARGET_SYSTEM_ROOT;
   11399         1134 :   target_system_root_changed = 0;
   11400         1134 :   target_sysroot_suffix = 0;
   11401         1134 :   target_sysroot_hdrs_suffix = 0;
   11402         1134 :   save_temps_flag = SAVE_TEMPS_NONE;
   11403         1134 :   save_temps_overrides_dumpdir = false;
   11404         1134 :   dumpdir_trailing_dash_added = false;
   11405         1134 :   free (dumpdir);
   11406         1134 :   free (dumpbase);
   11407         1134 :   free (dumpbase_ext);
   11408         1134 :   free (outbase);
   11409         1134 :   dumpdir = dumpbase = dumpbase_ext = outbase = NULL;
   11410         1134 :   dumpdir_length = outbase_length = 0;
   11411         1134 :   spec_machine = DEFAULT_TARGET_MACHINE;
   11412         1134 :   greatest_status = 1;
   11413              : 
   11414         1134 :   obstack_free (&obstack, NULL);
   11415         1134 :   obstack_free (&opts_obstack, NULL); /* in opts.cc */
   11416         1134 :   obstack_free (&collect_obstack, NULL);
   11417              : 
   11418         1134 :   link_command_spec = LINK_COMMAND_SPEC;
   11419              : 
   11420         1134 :   obstack_free (&multilib_obstack, NULL);
   11421              : 
   11422         1134 :   user_specs_head = NULL;
   11423         1134 :   user_specs_tail = NULL;
   11424              : 
   11425              :   /* Within the "compilers" vec, the fields "suffix" and "spec" were
   11426              :      statically allocated for the default compilers, but dynamically
   11427              :      allocated for additional compilers.  Delete them for the latter. */
   11428         1134 :   for (int i = n_default_compilers; i < n_compilers; i++)
   11429              :     {
   11430            0 :       free (const_cast <char *> (compilers[i].suffix));
   11431            0 :       free (const_cast <char *> (compilers[i].spec));
   11432              :     }
   11433         1134 :   XDELETEVEC (compilers);
   11434         1134 :   compilers = NULL;
   11435         1134 :   n_compilers = 0;
   11436              : 
   11437         1134 :   linker_options.truncate (0);
   11438         1134 :   assembler_options.truncate (0);
   11439         1134 :   preprocessor_options.truncate (0);
   11440              : 
   11441         1134 :   path_prefix_reset (&exec_prefixes);
   11442         1134 :   path_prefix_reset (&startfile_prefixes);
   11443         1134 :   path_prefix_reset (&include_prefixes);
   11444              : 
   11445         1134 :   machine_suffix = 0;
   11446         1134 :   just_machine_suffix = 0;
   11447         1134 :   gcc_exec_prefix = 0;
   11448         1134 :   gcc_libexec_prefix = 0;
   11449         1134 :   set_static_spec_shared (&md_exec_prefix, MD_EXEC_PREFIX);
   11450         1134 :   set_static_spec_shared (&md_startfile_prefix, MD_STARTFILE_PREFIX);
   11451         1134 :   set_static_spec_shared (&md_startfile_prefix_1, MD_STARTFILE_PREFIX_1);
   11452         1134 :   multilib_dir = 0;
   11453         1134 :   multilib_os_dir = 0;
   11454         1134 :   multiarch_dir = 0;
   11455              : 
   11456              :   /* Free any specs dynamically-allocated by set_spec.
   11457              :      These will be at the head of the list, before the
   11458              :      statically-allocated ones.  */
   11459         1134 :   if (specs)
   11460              :     {
   11461         2268 :       while (specs != static_specs)
   11462              :         {
   11463         1134 :           spec_list *next = specs->next;
   11464         1134 :           free (const_cast <char *> (specs->name));
   11465         1134 :           XDELETE (specs);
   11466         1134 :           specs = next;
   11467              :         }
   11468         1134 :       specs = 0;
   11469              :     }
   11470        52164 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
   11471              :     {
   11472        51030 :       spec_list *sl = &static_specs[i];
   11473        51030 :       if (sl->alloc_p)
   11474              :         {
   11475        45370 :           free (const_cast <char *> (*(sl->ptr_spec)));
   11476        45370 :           sl->alloc_p = false;
   11477              :         }
   11478        51030 :       *(sl->ptr_spec) = sl->default_ptr;
   11479              :     }
   11480              : #ifdef EXTRA_SPECS
   11481         1134 :   extra_specs = NULL;
   11482              : #endif
   11483              : 
   11484         1134 :   processing_spec_function = 0;
   11485              : 
   11486         1134 :   clear_args ();
   11487              : 
   11488         1134 :   have_c = 0;
   11489         1134 :   have_o = 0;
   11490              : 
   11491         1134 :   temp_names = NULL;
   11492         1134 :   execution_count = 0;
   11493         1134 :   signal_count = 0;
   11494              : 
   11495         1134 :   temp_filename = NULL;
   11496         1134 :   temp_filename_length = 0;
   11497         1134 :   always_delete_queue = NULL;
   11498         1134 :   failure_delete_queue = NULL;
   11499              : 
   11500         1134 :   XDELETEVEC (switches);
   11501         1134 :   switches = NULL;
   11502         1134 :   n_switches = 0;
   11503         1134 :   n_switches_alloc = 0;
   11504              : 
   11505         1134 :   compare_debug = 0;
   11506         1134 :   compare_debug_second = 0;
   11507         1134 :   compare_debug_opt = NULL;
   11508         3402 :   for (int i = 0; i < 2; i++)
   11509              :     {
   11510         2268 :       switches_debug_check[i] = NULL;
   11511         2268 :       n_switches_debug_check[i] = 0;
   11512         2268 :       n_switches_alloc_debug_check[i] = 0;
   11513         2268 :       debug_check_temp_file[i] = NULL;
   11514              :     }
   11515              : 
   11516         1134 :   XDELETEVEC (infiles);
   11517         1134 :   infiles = NULL;
   11518         1134 :   n_infiles = 0;
   11519         1134 :   n_infiles_alloc = 0;
   11520              : 
   11521         1134 :   combine_inputs = false;
   11522         1134 :   added_libraries = 0;
   11523         1134 :   XDELETEVEC (outfiles);
   11524         1134 :   outfiles = NULL;
   11525         1134 :   spec_lang = 0;
   11526         1134 :   last_language_n_infiles = 0;
   11527         1134 :   gcc_input_filename = NULL;
   11528         1134 :   input_file_number = 0;
   11529         1134 :   input_filename_length = 0;
   11530         1134 :   basename_length = 0;
   11531         1134 :   suffixed_basename_length = 0;
   11532         1134 :   input_basename = NULL;
   11533         1134 :   input_suffix = NULL;
   11534              :   /* We don't need to purge "input_stat", just to unset "input_stat_set".  */
   11535         1134 :   input_stat_set = 0;
   11536         1134 :   input_file_compiler = NULL;
   11537         1134 :   arg_going = 0;
   11538         1134 :   delete_this_arg = 0;
   11539         1134 :   this_is_output_file = 0;
   11540         1134 :   this_is_library_file = 0;
   11541         1134 :   this_is_linker_script = 0;
   11542         1134 :   input_from_pipe = 0;
   11543         1134 :   suffix_subst = NULL;
   11544              : 
   11545         1134 :   XDELETEVEC (mdswitches);
   11546         1134 :   mdswitches = NULL;
   11547         1134 :   n_mdswitches = 0;
   11548              : 
   11549         1134 :   used_arg.finalize ();
   11550         1134 : }
   11551              : 
   11552              : /* PR jit/64810.
   11553              :    Targets can provide configure-time default options in
   11554              :    OPTION_DEFAULT_SPECS.  The jit needs to access these, but
   11555              :    they are expressed in the spec language.
   11556              : 
   11557              :    Run just enough of the driver to be able to expand these
   11558              :    specs, and then call the callback CB on each
   11559              :    such option.  The options strings are *without* a leading
   11560              :    '-' character e.g. ("march=x86-64").  Finally, clean up.  */
   11561              : 
   11562              : void
   11563          131 : driver_get_configure_time_options (void (*cb) (const char *option,
   11564              :                                                void *user_data),
   11565              :                                    void *user_data)
   11566              : {
   11567          131 :   size_t i;
   11568              : 
   11569          131 :   obstack_init (&obstack);
   11570          131 :   init_opts_obstack ();
   11571          131 :   n_switches = 0;
   11572              : 
   11573         1441 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
   11574         1310 :     do_option_spec (option_default_specs[i].name,
   11575         1310 :                     option_default_specs[i].spec);
   11576              : 
   11577          393 :   for (i = 0; (int) i < n_switches; i++)
   11578              :     {
   11579          262 :       gcc_assert (switches[i].part1);
   11580          262 :       (*cb) (switches[i].part1, user_data);
   11581              :     }
   11582              : 
   11583          131 :   obstack_free (&opts_obstack, NULL);
   11584          131 :   obstack_free (&obstack, NULL);
   11585          131 :   n_switches = 0;
   11586          131 : }
        

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.