LCOV - code coverage report
Current view: top level - gcc - gcc.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 74.1 % 4384 3250
Test Date: 2026-03-28 14:25:54 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              : #include "auto-profile.h" /* for AUTO_PROFILE_VERSION.  */
      58              : 
      59              : #ifndef MATH_LIBRARY
      60              : #define MATH_LIBRARY "m"
      61              : #endif
      62              : 
      63              : 
      64              : /* Manage the manipulation of env vars.
      65              : 
      66              :    We poison "getenv" and "putenv", so that all enviroment-handling is
      67              :    done through this class.  Note that poisoning happens in the
      68              :    preprocessor at the identifier level, and doesn't distinguish between
      69              :      env.getenv ();
      70              :    and
      71              :      getenv ();
      72              :    Hence we need to use "get" for the accessor method, not "getenv".  */
      73              : 
      74              : struct env_manager
      75              : {
      76              :  public:
      77              :   void init (bool can_restore, bool debug);
      78              :   const char *get (const char *name);
      79              :   void xput (const char *string);
      80              :   void restore ();
      81              : 
      82              :  private:
      83              :   bool m_can_restore;
      84              :   bool m_debug;
      85              :   struct kv
      86              :   {
      87              :     char *m_key;
      88              :     char *m_value;
      89              :   };
      90              :   vec<kv> m_keys;
      91              : 
      92              : };
      93              : 
      94              : /* The singleton instance of class env_manager.  */
      95              : 
      96              : static env_manager env;
      97              : 
      98              : /* Initializer for class env_manager.
      99              : 
     100              :    We can't do this as a constructor since we have a statically
     101              :    allocated instance ("env" above).  */
     102              : 
     103              : void
     104       305022 : env_manager::init (bool can_restore, bool debug)
     105              : {
     106       305022 :   m_can_restore = can_restore;
     107       305022 :   m_debug = debug;
     108       305022 : }
     109              : 
     110              : /* Get the value of NAME within the environment.  Essentially
     111              :    a wrapper for ::getenv, but adding logging, and the possibility
     112              :    of caching results.  */
     113              : 
     114              : const char *
     115      1524193 : env_manager::get (const char *name)
     116              : {
     117      1524193 :   const char *result = ::getenv (name);
     118      1524193 :   if (m_debug)
     119            0 :     fprintf (stderr, "env_manager::getenv (%s) -> %s\n", name, result);
     120      1524193 :   return result;
     121              : }
     122              : 
     123              : /* Put the given KEY=VALUE entry STRING into the environment.
     124              :    If the env_manager was initialized with CAN_RESTORE set, then
     125              :    also record the old value of KEY within the environment, so that it
     126              :    can be later restored.  */
     127              : 
     128              : void
     129      1776374 : env_manager::xput (const char *string)
     130              : {
     131      1776374 :   if (m_debug)
     132            0 :     fprintf (stderr, "env_manager::xput (%s)\n", string);
     133      1776374 :   if (verbose_flag)
     134         6193 :     fnotice (stderr, "%s\n", string);
     135              : 
     136      1776374 :   if (m_can_restore)
     137              :     {
     138         6799 :       char *equals = strchr (const_cast <char *> (string), '=');
     139         6799 :       gcc_assert (equals);
     140              : 
     141         6799 :       struct kv kv;
     142         6799 :       kv.m_key = xstrndup (string, equals - string);
     143         6799 :       const char *cur_value = ::getenv (kv.m_key);
     144         6799 :       if (m_debug)
     145            0 :         fprintf (stderr, "saving old value: %s\n",cur_value);
     146         6799 :       kv.m_value = cur_value ? xstrdup (cur_value) : NULL;
     147         6799 :       m_keys.safe_push (kv);
     148              :     }
     149              : 
     150      1776374 :   ::putenv (const_cast<char *> (string));
     151      1776374 : }
     152              : 
     153              : /* Undo any xputenv changes made since last restore.
     154              :    Can only be called if the env_manager was initialized with
     155              :    CAN_RESTORE enabled.  */
     156              : 
     157              : void
     158         1134 : env_manager::restore ()
     159              : {
     160         1134 :   unsigned int i;
     161         1134 :   struct kv *item;
     162              : 
     163         1134 :   gcc_assert (m_can_restore);
     164              : 
     165         9067 :   FOR_EACH_VEC_ELT_REVERSE (m_keys, i, item)
     166              :     {
     167         6799 :       if (m_debug)
     168            0 :         printf ("restoring saved key: %s value: %s\n", item->m_key, item->m_value);
     169         6799 :       if (item->m_value)
     170         3397 :         ::setenv (item->m_key, item->m_value, 1);
     171              :       else
     172         3402 :         ::unsetenv (item->m_key);
     173         6799 :       free (item->m_key);
     174         6799 :       free (item->m_value);
     175              :     }
     176              : 
     177         1134 :   m_keys.truncate (0);
     178         1134 : }
     179              : 
     180              : /* Forbid other uses of getenv and putenv.  */
     181              : #if (GCC_VERSION >= 3000)
     182              : #pragma GCC poison getenv putenv
     183              : #endif
     184              : 
     185              : 
     186              : 
     187              : /* By default there is no special suffix for target executables.  */
     188              : #ifdef TARGET_EXECUTABLE_SUFFIX
     189              : #define HAVE_TARGET_EXECUTABLE_SUFFIX
     190              : #else
     191              : #define TARGET_EXECUTABLE_SUFFIX ""
     192              : #endif
     193              : 
     194              : /* By default there is no special suffix for host executables.  */
     195              : #ifdef HOST_EXECUTABLE_SUFFIX
     196              : #define HAVE_HOST_EXECUTABLE_SUFFIX
     197              : #else
     198              : #define HOST_EXECUTABLE_SUFFIX ""
     199              : #endif
     200              : 
     201              : /* By default, the suffix for target object files is ".o".  */
     202              : #ifdef TARGET_OBJECT_SUFFIX
     203              : #define HAVE_TARGET_OBJECT_SUFFIX
     204              : #else
     205              : #define TARGET_OBJECT_SUFFIX ".o"
     206              : #endif
     207              : 
     208              : static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
     209              : 
     210              : /* Most every one is fine with LIBRARY_PATH.  For some, it conflicts.  */
     211              : #ifndef LIBRARY_PATH_ENV
     212              : #define LIBRARY_PATH_ENV "LIBRARY_PATH"
     213              : #endif
     214              : 
     215              : /* If a stage of compilation returns an exit status >= 1,
     216              :    compilation of that file ceases.  */
     217              : 
     218              : #define MIN_FATAL_STATUS 1
     219              : 
     220              : /* Flag set by cppspec.cc to 1.  */
     221              : int is_cpp_driver;
     222              : 
     223              : /* Flag set to nonzero if an @file argument has been supplied to gcc.  */
     224              : static bool at_file_supplied;
     225              : 
     226              : /* Definition of string containing the arguments given to configure.  */
     227              : #include "configargs.h"
     228              : 
     229              : /* Flag saying to print the command line options understood by gcc and its
     230              :    sub-processes.  */
     231              : 
     232              : static int print_help_list;
     233              : 
     234              : /* Flag saying to print the version of gcc and its sub-processes.  */
     235              : 
     236              : static int print_version;
     237              : 
     238              : /* Flag that stores string prefix for which we provide bash completion.  */
     239              : 
     240              : static const char *completion = NULL;
     241              : 
     242              : /* Flag indicating whether we should ONLY print the command and
     243              :    arguments (like verbose_flag) without executing the command.
     244              :    Displayed arguments are quoted so that the generated command
     245              :    line is suitable for execution.  This is intended for use in
     246              :    shell scripts to capture the driver-generated command line.  */
     247              : static int verbose_only_flag;
     248              : 
     249              : /* Flag indicating how to print command line options of sub-processes.  */
     250              : 
     251              : static int print_subprocess_help;
     252              : 
     253              : /* Linker suffix passed to -fuse-ld=... */
     254              : static const char *use_ld;
     255              : 
     256              : /* Whether we should report subprocess execution times to a file.  */
     257              : 
     258              : FILE *report_times_to_file = NULL;
     259              : 
     260              : /* Nonzero means place this string before uses of /, so that include
     261              :    and library files can be found in an alternate location.  */
     262              : 
     263              : #ifdef TARGET_SYSTEM_ROOT
     264              : #define DEFAULT_TARGET_SYSTEM_ROOT (TARGET_SYSTEM_ROOT)
     265              : #else
     266              : #define DEFAULT_TARGET_SYSTEM_ROOT (0)
     267              : #endif
     268              : static const char *target_system_root = DEFAULT_TARGET_SYSTEM_ROOT;
     269              : 
     270              : /* Nonzero means pass the updated target_system_root to the compiler.  */
     271              : 
     272              : static int target_system_root_changed;
     273              : 
     274              : /* Nonzero means append this string to target_system_root.  */
     275              : 
     276              : static const char *target_sysroot_suffix = 0;
     277              : 
     278              : /* Nonzero means append this string to target_system_root for headers.  */
     279              : 
     280              : static const char *target_sysroot_hdrs_suffix = 0;
     281              : 
     282              : /* Nonzero means write "temp" files in source directory
     283              :    and use the source file's name in them, and don't delete them.  */
     284              : 
     285              : static enum save_temps {
     286              :   SAVE_TEMPS_NONE,              /* no -save-temps */
     287              :   SAVE_TEMPS_CWD,               /* -save-temps in current directory */
     288              :   SAVE_TEMPS_DUMP,              /* -save-temps in dumpdir */
     289              :   SAVE_TEMPS_OBJ                /* -save-temps in object directory */
     290              : } save_temps_flag;
     291              : 
     292              : /* Set this iff the dumppfx implied by a -save-temps=* option is to
     293              :    override a -dumpdir option, if any.  */
     294              : static bool save_temps_overrides_dumpdir = false;
     295              : 
     296              : /* -dumpdir, -dumpbase and -dumpbase-ext flags passed in, possibly
     297              :    rearranged as they are to be passed down, e.g., dumpbase and
     298              :    dumpbase_ext may be cleared if integrated with dumpdir or
     299              :    dropped.  */
     300              : static char *dumpdir, *dumpbase, *dumpbase_ext;
     301              : 
     302              : /* Usually the length of the string in dumpdir.  However, during
     303              :    linking, it may be shortened to omit a driver-added trailing dash,
     304              :    by then replaced with a trailing period, that is still to be passed
     305              :    to sub-processes in -dumpdir, but not to be generally used in spec
     306              :    filename expansions.  See maybe_run_linker.  */
     307              : static size_t dumpdir_length = 0;
     308              : 
     309              : /* Set if the last character in dumpdir is (or was) a dash that the
     310              :    driver added to dumpdir after dumpbase or linker output name.  */
     311              : static bool dumpdir_trailing_dash_added = false;
     312              : 
     313              : /* True if -r, -shared, -pie, -no-pie, -z lazy, or -z norelro were
     314              :    specified on the command line, and therefore -fhardened should not
     315              :    add -z now/relro.  */
     316              : static bool avoid_linker_hardening_p;
     317              : 
     318              : /* True if -static was specified on the command line.  */
     319              : static bool static_p;
     320              : 
     321              : /* Basename of dump and aux outputs, computed from dumpbase (given or
     322              :    derived from output name), to override input_basename in non-%w %b
     323              :    et al.  */
     324              : static char *outbase;
     325              : static size_t outbase_length = 0;
     326              : 
     327              : /* The compiler version.  */
     328              : 
     329              : static const char *compiler_version;
     330              : 
     331              : /* The target version.  */
     332              : 
     333              : static const char *const spec_version = DEFAULT_TARGET_VERSION;
     334              : 
     335              : /* The target machine.  */
     336              : 
     337              : static const char *spec_machine = DEFAULT_TARGET_MACHINE;
     338              : static const char *spec_host_machine = DEFAULT_REAL_TARGET_MACHINE;
     339              : 
     340              : /* List of offload targets.  Separated by colon.  Empty string for
     341              :    -foffload=disable.  */
     342              : 
     343              : static char *offload_targets = NULL;
     344              : 
     345              : #if OFFLOAD_DEFAULTED
     346              : /* Set to true if -foffload has not been used and offload_targets
     347              :    is set to the configured in default.  */
     348              : static bool offload_targets_default;
     349              : #endif
     350              : 
     351              : /* Nonzero if cross-compiling.
     352              :    When -b is used, the value comes from the `specs' file.  */
     353              : 
     354              : #ifdef CROSS_DIRECTORY_STRUCTURE
     355              : static const char *cross_compile = "1";
     356              : #else
     357              : static const char *cross_compile = "0";
     358              : #endif
     359              : 
     360              : /* Greatest exit code of sub-processes that has been encountered up to
     361              :    now.  */
     362              : static int greatest_status = 1;
     363              : 
     364              : /* This is the obstack which we use to allocate many strings.  */
     365              : 
     366              : static struct obstack obstack;
     367              : 
     368              : /* This is the obstack to build an environment variable to pass to
     369              :    collect2 that describes all of the relevant switches of what to
     370              :    pass the compiler in building the list of pointers to constructors
     371              :    and destructors.  */
     372              : 
     373              : static struct obstack collect_obstack;
     374              : 
     375              : /* Forward declaration for prototypes.  */
     376              : struct path_prefix;
     377              : struct prefix_list;
     378              : 
     379              : static void init_spec (void);
     380              : static void store_arg (const char *, int, int);
     381              : static void insert_wrapper (const char *);
     382              : static char *load_specs (const char *);
     383              : static void read_specs (const char *, bool, bool);
     384              : static void set_spec (const char *, const char *, bool);
     385              : static struct compiler *lookup_compiler (const char *, size_t, const char *);
     386              : static char *build_search_list (const struct path_prefix *, const char *,
     387              :                                 bool, bool);
     388              : static void xputenv (const char *);
     389              : static void putenv_from_prefixes (const struct path_prefix *, const char *,
     390              :                                   bool);
     391              : static int access_check (const char *, int);
     392              : static char *find_a_file (const struct path_prefix *, const char *, int, bool);
     393              : static char *find_a_program (const char *);
     394              : static void add_prefix (struct path_prefix *, const char *, const char *,
     395              :                         int, int, int);
     396              : static void add_sysrooted_prefix (struct path_prefix *, const char *,
     397              :                                   const char *, int, int, int);
     398              : static char *skip_whitespace (char *);
     399              : static void delete_if_ordinary (const char *);
     400              : static void delete_temp_files (void);
     401              : static void delete_failure_queue (void);
     402              : static void clear_failure_queue (void);
     403              : static int check_live_switch (int, int);
     404              : static const char *handle_braces (const char *);
     405              : static inline bool input_suffix_matches (const char *, const char *);
     406              : static inline bool switch_matches (const char *, const char *, int);
     407              : static inline void mark_matching_switches (const char *, const char *, int);
     408              : static inline void process_marked_switches (void);
     409              : static const char *process_brace_body (const char *, const char *, const char *, int, int);
     410              : static const struct spec_function *lookup_spec_function (const char *);
     411              : static const char *eval_spec_function (const char *, const char *, const char *);
     412              : static const char *handle_spec_function (const char *, bool *, const char *);
     413              : static char *save_string (const char *, int);
     414              : static void set_collect_gcc_options (void);
     415              : static int do_spec_1 (const char *, int, const char *);
     416              : static int do_spec_2 (const char *, const char *);
     417              : static void do_option_spec (const char *, const char *);
     418              : static void do_self_spec (const char *);
     419              : static const char *find_file (const char *);
     420              : static int is_directory (const char *);
     421              : static const char *validate_switches (const char *, bool, bool);
     422              : static void validate_all_switches (void);
     423              : static inline void validate_switches_from_spec (const char *, bool);
     424              : static void give_switch (int, int);
     425              : static int default_arg (const char *, int);
     426              : static void set_multilib_dir (void);
     427              : static void print_multilib_info (void);
     428              : static void display_help (void);
     429              : static void add_preprocessor_option (const char *, int);
     430              : static void add_assembler_option (const char *, int);
     431              : static void add_linker_option (const char *, int);
     432              : static void process_command (unsigned int, struct cl_decoded_option *);
     433              : static int execute (void);
     434              : static void alloc_args (void);
     435              : static void clear_args (void);
     436              : static void fatal_signal (int);
     437              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
     438              : static void init_gcc_specs (struct obstack *, const char *, const char *,
     439              :                             const char *);
     440              : #endif
     441              : #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
     442              : static const char *convert_filename (const char *, int, int);
     443              : #endif
     444              : 
     445              : static void try_generate_repro (const char **argv);
     446              : static const char *getenv_spec_function (int, const char **);
     447              : static const char *if_exists_spec_function (int, const char **);
     448              : static const char *if_exists_else_spec_function (int, const char **);
     449              : static const char *if_exists_then_else_spec_function (int, const char **);
     450              : static const char *sanitize_spec_function (int, const char **);
     451              : static const char *replace_outfile_spec_function (int, const char **);
     452              : static const char *remove_outfile_spec_function (int, const char **);
     453              : static const char *version_compare_spec_function (int, const char **);
     454              : static const char *include_spec_function (int, const char **);
     455              : static const char *find_file_spec_function (int, const char **);
     456              : static const char *find_plugindir_spec_function (int, const char **);
     457              : static const char *print_asm_header_spec_function (int, const char **);
     458              : static const char *compare_debug_dump_opt_spec_function (int, const char **);
     459              : static const char *compare_debug_self_opt_spec_function (int, const char **);
     460              : static const char *pass_through_libs_spec_func (int, const char **);
     461              : static const char *dumps_spec_func (int, const char **);
     462              : static const char *greater_than_spec_func (int, const char **);
     463              : static const char *debug_level_greater_than_spec_func (int, const char **);
     464              : static const char *dwarf_version_greater_than_spec_func (int, const char **);
     465              : static const char *find_fortran_preinclude_file (int, const char **);
     466              : static const char *join_spec_func (int, const char **);
     467              : static char *convert_white_space (char *);
     468              : static char *quote_spec (char *);
     469              : static char *quote_spec_arg (char *);
     470              : static bool not_actual_file_p (const char *);
     471              : 
     472              : 
     473              : /* The Specs Language
     474              : 
     475              : Specs are strings containing lines, each of which (if not blank)
     476              : is made up of a program name, and arguments separated by spaces.
     477              : The program name must be exact and start from root, since no path
     478              : is searched and it is unreliable to depend on the current working directory.
     479              : Redirection of input or output is not supported; the subprograms must
     480              : accept filenames saying what files to read and write.
     481              : 
     482              : In addition, the specs can contain %-sequences to substitute variable text
     483              : or for conditional text.  Here is a table of all defined %-sequences.
     484              : Note that spaces are not generated automatically around the results of
     485              : expanding these sequences; therefore, you can concatenate them together
     486              : or with constant text in a single argument.
     487              : 
     488              :  %%     substitute one % into the program name or argument.
     489              :  %"     substitute an empty argument.
     490              :  %i     substitute the name of the input file being processed.
     491              :  %b     substitute the basename for outputs related with the input file
     492              :         being processed.  This is often a substring of the input file name,
     493              :         up to (and not including) the last period but, unless %w is active,
     494              :         it is affected by the directory selected by -save-temps=*, by
     495              :         -dumpdir, and, in case of multiple compilations, even by -dumpbase
     496              :         and -dumpbase-ext and, in case of linking, by the linker output
     497              :         name.  When %w is active, it derives the main output name only from
     498              :         the input file base name; when it is not, it names aux/dump output
     499              :         file.
     500              :  %B     same as %b, but include the input file suffix (text after the last
     501              :         period).
     502              :  %gSUFFIX
     503              :         substitute a file name that has suffix SUFFIX and is chosen
     504              :         once per compilation, and mark the argument a la %d.  To reduce
     505              :         exposure to denial-of-service attacks, the file name is now
     506              :         chosen in a way that is hard to predict even when previously
     507              :         chosen file names are known.  For example, `%g.s ... %g.o ... %g.s'
     508              :         might turn into `ccUVUUAU.s ccXYAXZ12.o ccUVUUAU.s'.  SUFFIX matches
     509              :         the regexp "[.0-9A-Za-z]*%O"; "%O" is treated exactly as if it
     510              :         had been pre-processed.  Previously, %g was simply substituted
     511              :         with a file name chosen once per compilation, without regard
     512              :         to any appended suffix (which was therefore treated just like
     513              :         ordinary text), making such attacks more likely to succeed.
     514              :  %|SUFFIX
     515              :         like %g, but if -pipe is in effect, expands simply to "-".
     516              :  %mSUFFIX
     517              :         like %g, but if -pipe is in effect, expands to nothing.  (We have both
     518              :         %| and %m to accommodate differences between system assemblers; see
     519              :         the AS_NEEDS_DASH_FOR_PIPED_INPUT target macro.)
     520              :  %uSUFFIX
     521              :         like %g, but generates a new temporary file name even if %uSUFFIX
     522              :         was already seen.
     523              :  %USUFFIX
     524              :         substitutes the last file name generated with %uSUFFIX, generating a
     525              :         new one if there is no such last file name.  In the absence of any
     526              :         %uSUFFIX, this is just like %gSUFFIX, except they don't share
     527              :         the same suffix "space", so `%g.s ... %U.s ... %g.s ... %U.s'
     528              :         would involve the generation of two distinct file names, one
     529              :         for each `%g.s' and another for each `%U.s'.  Previously, %U was
     530              :         simply substituted with a file name chosen for the previous %u,
     531              :         without regard to any appended suffix.
     532              :  %jSUFFIX
     533              :         substitutes the name of the HOST_BIT_BUCKET, if any, and if it is
     534              :         writable, and if save-temps is off; otherwise, substitute the name
     535              :         of a temporary file, just like %u.  This temporary file is not
     536              :         meant for communication between processes, but rather as a junk
     537              :         disposal mechanism.
     538              :  %.SUFFIX
     539              :         substitutes .SUFFIX for the suffixes of a matched switch's args when
     540              :         it is subsequently output with %*. SUFFIX is terminated by the next
     541              :         space or %.
     542              :  %d     marks the argument containing or following the %d as a
     543              :         temporary file name, so that file will be deleted if GCC exits
     544              :         successfully.  Unlike %g, this contributes no text to the argument.
     545              :  %w     marks the argument containing or following the %w as the
     546              :         "output file" of this compilation.  This puts the argument
     547              :         into the sequence of arguments that %o will substitute later.
     548              :  %V     indicates that this compilation produces no "output file".
     549              :  %W{...}
     550              :         like %{...} but marks the last argument supplied within as a file
     551              :         to be deleted on failure.
     552              :  %@{...}
     553              :         like %{...} but puts the result into a FILE and substitutes @FILE
     554              :         if an @file argument has been supplied.
     555              :  %o     substitutes the names of all the output files, with spaces
     556              :         automatically placed around them.  You should write spaces
     557              :         around the %o as well or the results are undefined.
     558              :         %o is for use in the specs for running the linker.
     559              :         Input files whose names have no recognized suffix are not compiled
     560              :         at all, but they are included among the output files, so they will
     561              :         be linked.
     562              :  %O     substitutes the suffix for object files.  Note that this is
     563              :         handled specially when it immediately follows %g, %u, or %U
     564              :         (with or without a suffix argument) because of the need for
     565              :         those to form complete file names.  The handling is such that
     566              :         %O is treated exactly as if it had already been substituted,
     567              :         except that %g, %u, and %U do not currently support additional
     568              :         SUFFIX characters following %O as they would following, for
     569              :         example, `.o'.
     570              :  %I     Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
     571              :         (made from TARGET_SYSTEM_ROOT), -isystem (made from COMPILER_PATH
     572              :         and -B options) and -imultilib as necessary.
     573              :  %s     current argument is the name of a library or startup file of some sort.
     574              :         Search for that file in a standard list of directories
     575              :         and substitute the full name found.
     576              :  %T     current argument is the name of a linker script.
     577              :         Search for that file in the current list of directories to scan for
     578              :         libraries.  If the file is located, insert a --script option into the
     579              :         command line followed by the full path name found.  If the file is
     580              :         not found then generate an error message.
     581              :         Note: the current working directory is not searched.
     582              :  %eSTR  Print STR as an error message.  STR is terminated by a newline.
     583              :         Use this when inconsistent options are detected.
     584              :  %nSTR  Print STR as a notice.  STR is terminated by a newline.
     585              :  %x{OPTION}     Accumulate an option for %X.
     586              :  %X     Output the accumulated linker options specified by compilations.
     587              :  %Y     Output the accumulated assembler options specified by compilations.
     588              :  %Z     Output the accumulated preprocessor options specified by compilations.
     589              :  %a     process ASM_SPEC as a spec.
     590              :         This allows config.h to specify part of the spec for running as.
     591              :  %A     process ASM_FINAL_SPEC as a spec.  A capital A is actually
     592              :         used here.  This can be used to run a post-processor after the
     593              :         assembler has done its job.
     594              :  %D     Dump out a -L option for each directory in startfile_prefixes.
     595              :         If multilib_dir is set, extra entries are generated with it affixed.
     596              :  %l     process LINK_SPEC as a spec.
     597              :  %L     process LIB_SPEC as a spec.
     598              :  %M     Output multilib_os_dir.
     599              :  %P     Output a RUNPATH_OPTION for each directory in startfile_prefixes.
     600              :  %G     process LIBGCC_SPEC as a spec.
     601              :  %R     Output the concatenation of target_system_root and
     602              :         target_sysroot_suffix.
     603              :  %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
     604              :  %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
     605              :  %C     process CPP_SPEC as a spec.
     606              :  %1     process CC1_SPEC as a spec.
     607              :  %2     process CC1PLUS_SPEC as a spec.
     608              :  %*     substitute the variable part of a matched option.  (See below.)
     609              :         Note that each comma in the substituted string is replaced by
     610              :         a single space.  A space is appended after the last substition
     611              :         unless there is more text in current sequence.
     612              :  %<S    remove all occurrences of -S from the command line.
     613              :         Note - this command is position dependent.  % commands in the
     614              :         spec string before this one will see -S, % commands in the
     615              :         spec string after this one will not.
     616              :  %>S Similar to "%<S", but keep it in the GCC command line.
     617              :  %<S*        remove all occurrences of all switches beginning with -S from the
     618              :         command line.
     619              :  %:function(args)
     620              :         Call the named function FUNCTION, passing it ARGS.  ARGS is
     621              :         first processed as a nested spec string, then split into an
     622              :         argument vector in the usual fashion.  The function returns
     623              :         a string which is processed as if it had appeared literally
     624              :         as part of the current spec.
     625              :  %{S}   substitutes the -S switch, if that switch was given to GCC.
     626              :         If that switch was not specified, this substitutes nothing.
     627              :         Here S is a metasyntactic variable.
     628              :  %{S*}  substitutes all the switches specified to GCC whose names start
     629              :         with -S.  This is used for -o, -I, etc; switches that take
     630              :         arguments.  GCC considers `-o foo' as being one switch whose
     631              :         name starts with `o'.  %{o*} would substitute this text,
     632              :         including the space; thus, two arguments would be generated.
     633              :  %{S*&T*} likewise, but preserve order of S and T options (the order
     634              :         of S and T in the spec is not significant).  Can be any number
     635              :         of ampersand-separated variables; for each the wild card is
     636              :         optional.  Useful for CPP as %{D*&U*&A*}.
     637              : 
     638              :  %{S:X}   substitutes X, if the -S switch was given to GCC.
     639              :  %{!S:X}  substitutes X, if the -S switch was NOT given to GCC.
     640              :  %{S*:X}  substitutes X if one or more switches whose names start
     641              :           with -S was given to GCC.  Normally X is substituted only
     642              :           once, no matter how many such switches appeared.  However,
     643              :           if %* appears somewhere in X, then X will be substituted
     644              :           once for each matching switch, with the %* replaced by the
     645              :           part of that switch that matched the '*'.  A space will be
     646              :           appended after the last substition unless there is more
     647              :           text in current sequence.
     648              :  %{.S:X}  substitutes X, if processing a file with suffix S.
     649              :  %{!.S:X} substitutes X, if NOT processing a file with suffix S.
     650              :  %{,S:X}  substitutes X, if processing a file which will use spec S.
     651              :  %{!,S:X} substitutes X, if NOT processing a file which will use spec S.
     652              : 
     653              :  %{S|T:X} substitutes X if either -S or -T was given to GCC.  This may be
     654              :           combined with '!', '.', ',', and '*' as above binding stronger
     655              :           than the OR.
     656              :           If %* appears in X, all of the alternatives must be starred, and
     657              :           only the first matching alternative is substituted.
     658              :  %{%:function(args):X}
     659              :           Call function named FUNCTION with args ARGS.  If the function
     660              :           returns non-NULL, then X is substituted, if it returns
     661              :           NULL, it isn't substituted.
     662              :  %{S:X;   if S was given to GCC, substitutes X;
     663              :    T:Y;   else if T was given to GCC, substitutes Y;
     664              :     :D}   else substitutes D.  There can be as many clauses as you need.
     665              :           This may be combined with '.', '!', ',', '|', and '*' as above.
     666              : 
     667              :  %(Spec) processes a specification defined in a specs file as *Spec:
     668              : 
     669              : The switch matching text S in a %{S}, %{S:X}, or similar construct can use
     670              : a backslash to ignore the special meaning of the character following it,
     671              : thus allowing literal matching of a character that is otherwise specially
     672              : treated.  For example, %{std=iso9899\:1999:X} substitutes X if the
     673              : -std=iso9899:1999 option is given.
     674              : 
     675              : The conditional text X in a %{S:X} or similar construct may contain
     676              : other nested % constructs or spaces, or even newlines.  They are
     677              : processed as usual, as described above.  Trailing white space in X is
     678              : ignored.  White space may also appear anywhere on the left side of the
     679              : colon in these constructs, except between . or * and the corresponding
     680              : word.
     681              : 
     682              : The -O, -f, -g, -m, and -W switches are handled specifically in these
     683              : constructs.  If another value of -O or the negated form of a -f, -m, or
     684              : -W switch is found later in the command line, the earlier switch
     685              : value is ignored, except with {S*} where S is just one letter; this
     686              : passes all matching options.
     687              : 
     688              : The character | at the beginning of the predicate text is used to indicate
     689              : that a command should be piped to the following command, but only if -pipe
     690              : is specified.
     691              : 
     692              : Note that it is built into GCC which switches take arguments and which
     693              : do not.  You might think it would be useful to generalize this to
     694              : allow each compiler's spec to say which switches take arguments.  But
     695              : this cannot be done in a consistent fashion.  GCC cannot even decide
     696              : which input files have been specified without knowing which switches
     697              : take arguments, and it must know which input files to compile in order
     698              : to tell which compilers to run.
     699              : 
     700              : GCC also knows implicitly that arguments starting in `-l' are to be
     701              : treated as compiler output files, and passed to the linker in their
     702              : proper position among the other output files.  */
     703              : 
     704              : /* Define the macros used for specs %a, %l, %L, %S, %C, %1.  */
     705              : 
     706              : /* config.h can define ASM_SPEC to provide extra args to the assembler
     707              :    or extra switch-translations.  */
     708              : #ifndef ASM_SPEC
     709              : #define ASM_SPEC ""
     710              : #endif
     711              : 
     712              : /* config.h can define ASM_FINAL_SPEC to run a post processor after
     713              :    the assembler has run.  */
     714              : #ifndef ASM_FINAL_SPEC
     715              : #define ASM_FINAL_SPEC \
     716              :   "%{gsplit-dwarf: \n\
     717              :        objcopy --extract-dwo \
     718              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     719              :          %b.dwo \n\
     720              :        objcopy --strip-dwo \
     721              :          %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
     722              :     }"
     723              : #endif
     724              : 
     725              : /* config.h can define CPP_SPEC to provide extra args to the C preprocessor
     726              :    or extra switch-translations.  */
     727              : #ifndef CPP_SPEC
     728              : #define CPP_SPEC ""
     729              : #endif
     730              : 
     731              : /* libc can define LIBC_CPP_SPEC to provide extra args to the C preprocessor
     732              :    or extra switch-translations. */
     733              : 
     734              : #ifndef LIBC_CPP_SPEC
     735              : #define LIBC_CPP_SPEC ""
     736              : #endif
     737              : 
     738              : /* Operating systems can define OS_CC1_SPEC to provide extra args to cc1 and
     739              :    cc1plus or extra switch-translations.  The OS_CC1_SPEC is appended
     740              :    to CC1_SPEC in the initialization of cc1_spec.  */
     741              : #ifndef OS_CC1_SPEC
     742              : #define OS_CC1_SPEC ""
     743              : #endif
     744              : 
     745              : /* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus
     746              :    or extra switch-translations.  */
     747              : #ifndef CC1_SPEC
     748              : #define CC1_SPEC ""
     749              : #endif
     750              : 
     751              : /* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus
     752              :    or extra switch-translations.  */
     753              : #ifndef CC1PLUS_SPEC
     754              : #define CC1PLUS_SPEC ""
     755              : #endif
     756              : 
     757              : /* config.h can define LINK_SPEC to provide extra args to the linker
     758              :    or extra switch-translations.  */
     759              : #ifndef LINK_SPEC
     760              : #define LINK_SPEC ""
     761              : #endif
     762              : 
     763              : /* libc can define LIBC_LINK_SPEC to provide extra args to the linker
     764              :    or extra switch-translations.  */
     765              : #ifndef LIBC_LINK_SPEC
     766              : #define LIBC_LINK_SPEC ""
     767              : #endif
     768              : 
     769              : /* config.h can define LIB_SPEC to override the default libraries.  */
     770              : #ifndef LIB_SPEC
     771              : #define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
     772              : #endif
     773              : 
     774              : /* When using -fsplit-stack we need to wrap pthread_create, in order
     775              :    to initialize the stack guard.  We always use wrapping, rather than
     776              :    shared library ordering, and we keep the wrapper function in
     777              :    libgcc.  This is not yet a real spec, though it could become one;
     778              :    it is currently just stuffed into LINK_SPEC.  FIXME: This wrapping
     779              :    only works with GNU ld and gold.  */
     780              : #ifdef HAVE_GOLD_NON_DEFAULT_SPLIT_STACK
     781              : #define STACK_SPLIT_SPEC " %{fsplit-stack: -fuse-ld=gold --wrap=pthread_create}"
     782              : #else
     783              : #define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
     784              : #endif
     785              : 
     786              : #ifndef LIBASAN_SPEC
     787              : #define STATIC_LIBASAN_LIBS \
     788              :   " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}"
     789              : #ifdef LIBASAN_EARLY_SPEC
     790              : #define LIBASAN_SPEC STATIC_LIBASAN_LIBS
     791              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     792              : #define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
     793              :                      "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
     794              :                      STATIC_LIBASAN_LIBS
     795              : #else
     796              : #define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS
     797              : #endif
     798              : #endif
     799              : 
     800              : #ifndef LIBASAN_EARLY_SPEC
     801              : #define LIBASAN_EARLY_SPEC ""
     802              : #endif
     803              : 
     804              : #ifndef LIBHWASAN_SPEC
     805              : #define STATIC_LIBHWASAN_LIBS \
     806              :   " %{static-libhwasan|static:%:include(libsanitizer.spec)%(link_libhwasan)}"
     807              : #ifdef LIBHWASAN_EARLY_SPEC
     808              : #define LIBHWASAN_SPEC STATIC_LIBHWASAN_LIBS
     809              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     810              : #define LIBHWASAN_SPEC "%{static-libhwasan:" LD_STATIC_OPTION \
     811              :                      "} -lhwasan %{static-libhwasan:" LD_DYNAMIC_OPTION "}" \
     812              :                      STATIC_LIBHWASAN_LIBS
     813              : #else
     814              : #define LIBHWASAN_SPEC "-lhwasan" STATIC_LIBHWASAN_LIBS
     815              : #endif
     816              : #endif
     817              : 
     818              : #ifndef LIBHWASAN_EARLY_SPEC
     819              : #define LIBHWASAN_EARLY_SPEC ""
     820              : #endif
     821              : 
     822              : #ifndef LIBTSAN_SPEC
     823              : #define STATIC_LIBTSAN_LIBS \
     824              :   " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}"
     825              : #ifdef LIBTSAN_EARLY_SPEC
     826              : #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS
     827              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     828              : #define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
     829              :                      "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \
     830              :                      STATIC_LIBTSAN_LIBS
     831              : #else
     832              : #define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS
     833              : #endif
     834              : #endif
     835              : 
     836              : #ifndef LIBTSAN_EARLY_SPEC
     837              : #define LIBTSAN_EARLY_SPEC ""
     838              : #endif
     839              : 
     840              : #ifndef LIBLSAN_SPEC
     841              : #define STATIC_LIBLSAN_LIBS \
     842              :   " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}"
     843              : #ifdef LIBLSAN_EARLY_SPEC
     844              : #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS
     845              : #elif defined(HAVE_LD_STATIC_DYNAMIC)
     846              : #define LIBLSAN_SPEC "%{static-liblsan:" LD_STATIC_OPTION \
     847              :                      "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \
     848              :                      STATIC_LIBLSAN_LIBS
     849              : #else
     850              : #define LIBLSAN_SPEC "-llsan" STATIC_LIBLSAN_LIBS
     851              : #endif
     852              : #endif
     853              : 
     854              : #ifndef LIBLSAN_EARLY_SPEC
     855              : #define LIBLSAN_EARLY_SPEC ""
     856              : #endif
     857              : 
     858              : #ifndef LIBUBSAN_SPEC
     859              : #define STATIC_LIBUBSAN_LIBS \
     860              :   " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}"
     861              : #ifdef HAVE_LD_STATIC_DYNAMIC
     862              : #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
     863              :                      "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
     864              :                      STATIC_LIBUBSAN_LIBS
     865              : #else
     866              : #define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS
     867              : #endif
     868              : #endif
     869              : 
     870              : /* Linker options for compressed debug sections.  */
     871              : #if HAVE_LD_COMPRESS_DEBUG == 0
     872              : /* No linker support.  */
     873              : #define LINK_COMPRESS_DEBUG_SPEC \
     874              :         " %{gz*:%e-gz is not supported in this configuration} "
     875              : #elif HAVE_LD_COMPRESS_DEBUG == 1
     876              : /* ELF gABI style.  */
     877              : #define LINK_COMPRESS_DEBUG_SPEC \
     878              :         " %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
     879              :         " %{gz=none:"   LD_COMPRESS_DEBUG_OPTION "=none}" \
     880              :         " %{gz=zstd:%e-gz=zstd is not supported in this configuration} " \
     881              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     882              : #elif HAVE_LD_COMPRESS_DEBUG == 2
     883              : /* ELF gABI style and ZSTD.  */
     884              : #define LINK_COMPRESS_DEBUG_SPEC \
     885              :         " %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
     886              :         " %{gz=none:"   LD_COMPRESS_DEBUG_OPTION "=none}" \
     887              :         " %{gz=zstd:"   LD_COMPRESS_DEBUG_OPTION "=zstd}" \
     888              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     889              : #else
     890              : #error Unknown value for HAVE_LD_COMPRESS_DEBUG.
     891              : #endif
     892              : 
     893              : /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
     894              :    included.  */
     895              : #ifndef LIBGCC_SPEC
     896              : #if defined(REAL_LIBGCC_SPEC)
     897              : #define LIBGCC_SPEC REAL_LIBGCC_SPEC
     898              : #elif defined(LINK_LIBGCC_SPECIAL_1)
     899              : /* Have gcc do the search for libgcc.a.  */
     900              : #define LIBGCC_SPEC "libgcc.a%s"
     901              : #else
     902              : #define LIBGCC_SPEC "-lgcc"
     903              : #endif
     904              : #endif
     905              : 
     906              : /* config.h can define STARTFILE_SPEC to override the default crt0 files.  */
     907              : #ifndef STARTFILE_SPEC
     908              : #define STARTFILE_SPEC  \
     909              :   "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
     910              : #endif
     911              : 
     912              : /* config.h can define ENDFILE_SPEC to override the default crtn files.  */
     913              : #ifndef ENDFILE_SPEC
     914              : #define ENDFILE_SPEC ""
     915              : #endif
     916              : 
     917              : #ifndef LINKER_NAME
     918              : #define LINKER_NAME "collect2"
     919              : #endif
     920              : 
     921              : #ifdef HAVE_AS_DEBUG_PREFIX_MAP
     922              : #define ASM_MAP " %{ffile-prefix-map=*:--debug-prefix-map %*} %{fdebug-prefix-map=*:--debug-prefix-map %*}"
     923              : #else
     924              : #define ASM_MAP ""
     925              : #endif
     926              : 
     927              : /* Assembler options for compressed debug sections.  */
     928              : #if HAVE_LD_COMPRESS_DEBUG == 0
     929              : /* Reject if the linker cannot write compressed debug sections.  */
     930              : #define ASM_COMPRESS_DEBUG_SPEC \
     931              :         " %{gz*:%e-gz is not supported in this configuration} "
     932              : #else /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     933              : #if HAVE_AS_COMPRESS_DEBUG == 0
     934              : /* No assembler support.  Ignore silently.  */
     935              : #define ASM_COMPRESS_DEBUG_SPEC \
     936              :         " %{gz*:} "
     937              : #elif HAVE_AS_COMPRESS_DEBUG == 1
     938              : /* ELF gABI style.  */
     939              : #define ASM_COMPRESS_DEBUG_SPEC \
     940              :         " %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
     941              :         " %{gz=none:"   AS_COMPRESS_DEBUG_OPTION "=none}" \
     942              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     943              : #elif HAVE_AS_COMPRESS_DEBUG == 2
     944              : /* ELF gABI style and ZSTD.  */
     945              : #define ASM_COMPRESS_DEBUG_SPEC \
     946              :         " %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
     947              :         " %{gz=none:"   AS_COMPRESS_DEBUG_OPTION "=none}" \
     948              :         " %{gz=zstd:"   AS_COMPRESS_DEBUG_OPTION "=zstd}" \
     949              :         " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value.  */
     950              : #else
     951              : #error Unknown value for HAVE_AS_COMPRESS_DEBUG.
     952              : #endif
     953              : #endif /* HAVE_LD_COMPRESS_DEBUG >= 1 */
     954              : 
     955              : /* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
     956              :    to the assembler, when compiling assembly sources only.  */
     957              : #ifndef ASM_DEBUG_SPEC
     958              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     959              : /* If --gdwarf-N is supported and as can handle even compiler generated
     960              :    .debug_line with it, supply --gdwarf-N in ASM_DEBUG_OPTION_SPEC rather
     961              :    than in ASM_DEBUG_SPEC, so that it applies to both .s and .c etc.
     962              :    compilations.  */
     963              : #  define ASM_DEBUG_DWARF_OPTION ""
     964              : # elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && !defined(HAVE_LD_BROKEN_PE_DWARF5)
     965              : #  define ASM_DEBUG_DWARF_OPTION "%{%:dwarf-version-gt(4):--gdwarf-5;" \
     966              :         "%:dwarf-version-gt(3):--gdwarf-4;"                           \
     967              :         "%:dwarf-version-gt(2):--gdwarf-3;"                           \
     968              :         ":--gdwarf2}"
     969              : # else
     970              : #  define ASM_DEBUG_DWARF_OPTION "--gdwarf2"
     971              : # endif
     972              : #  if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
     973              : #   define ASM_DEBUG_SPEC "%{g*:%{%:debug-level-gt(0):" \
     974              :         ASM_DEBUG_DWARF_OPTION "}}" ASM_MAP
     975              : #  endif
     976              : # endif
     977              : #ifndef ASM_DEBUG_SPEC
     978              : # define ASM_DEBUG_SPEC ""
     979              : #endif
     980              : 
     981              : /* Define ASM_DEBUG_OPTION_SPEC to be a spec suitable for translating '-g'
     982              :    to the assembler when compiling all sources.  */
     983              : #ifndef ASM_DEBUG_OPTION_SPEC
     984              : # if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
     985              : #  define ASM_DEBUG_OPTION_DWARF_OPT                                    \
     986              :         "%{%:dwarf-version-gt(4):--gdwarf-5 ;"                                \
     987              :         "%:dwarf-version-gt(3):--gdwarf-4 ;"                          \
     988              :         "%:dwarf-version-gt(2):--gdwarf-3 ;"                          \
     989              :         ":--gdwarf2 }"
     990              : # if defined(DWARF2_DEBUGGING_INFO)
     991              : #   define ASM_DEBUG_OPTION_SPEC "%{g*:%{%:debug-level-gt(0):" \
     992              :         ASM_DEBUG_OPTION_DWARF_OPT "}}"
     993              : #  endif
     994              : # endif
     995              : #endif
     996              : #ifndef ASM_DEBUG_OPTION_SPEC
     997              : # define ASM_DEBUG_OPTION_SPEC ""
     998              : #endif
     999              : 
    1000              : /* Here is the spec for running the linker, after compiling all files.  */
    1001              : 
    1002              : #if defined(TARGET_PROVIDES_LIBATOMIC) && defined(USE_LD_AS_NEEDED)
    1003              : #ifdef USE_LD_AS_NEEDED_LDSCRIPT
    1004              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:-latomic_asneeded} "
    1005              : #else
    1006              : #define LINK_LIBATOMIC_SPEC "%{!fno-link-libatomic:" LD_AS_NEEDED_OPTION \
    1007              :                             " -latomic " LD_NO_AS_NEEDED_OPTION "} "
    1008              : #endif
    1009              : #else
    1010              : #define LINK_LIBATOMIC_SPEC ""
    1011              : #endif
    1012              : 
    1013              : /* This is overridable by the target in case they need to specify the
    1014              :    -lgcc and -lc order specially, yet not require them to override all
    1015              :    of LINK_COMMAND_SPEC.  */
    1016              : #ifndef LINK_GCC_C_SEQUENCE_SPEC
    1017              : #define LINK_GCC_C_SEQUENCE_SPEC "%G %{!nolibc:%L %G}"
    1018              : #endif
    1019              : 
    1020              : #ifndef LINK_SSP_SPEC
    1021              : #ifdef TARGET_LIBC_PROVIDES_SSP
    1022              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1023              :                        "|fstack-protector-strong|fstack-protector-explicit:}"
    1024              : #else
    1025              : #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
    1026              :                        "|fstack-protector-strong|fstack-protector-explicit" \
    1027              :                        ":-lssp_nonshared -lssp}"
    1028              : #endif
    1029              : #endif
    1030              : 
    1031              : #ifdef ENABLE_DEFAULT_PIE
    1032              : #define PIE_SPEC                "!no-pie"
    1033              : #define NO_FPIE1_SPEC           "fno-pie"
    1034              : #define FPIE1_SPEC              NO_FPIE1_SPEC ":;"
    1035              : #define NO_FPIE2_SPEC           "fno-PIE"
    1036              : #define FPIE2_SPEC              NO_FPIE2_SPEC ":;"
    1037              : #define NO_FPIE_SPEC            NO_FPIE1_SPEC "|" NO_FPIE2_SPEC
    1038              : #define FPIE_SPEC               NO_FPIE_SPEC ":;"
    1039              : #define NO_FPIC1_SPEC           "fno-pic"
    1040              : #define FPIC1_SPEC              NO_FPIC1_SPEC ":;"
    1041              : #define NO_FPIC2_SPEC           "fno-PIC"
    1042              : #define FPIC2_SPEC              NO_FPIC2_SPEC ":;"
    1043              : #define NO_FPIC_SPEC            NO_FPIC1_SPEC "|" NO_FPIC2_SPEC
    1044              : #define FPIC_SPEC               NO_FPIC_SPEC ":;"
    1045              : #define NO_FPIE1_AND_FPIC1_SPEC NO_FPIE1_SPEC "|" NO_FPIC1_SPEC
    1046              : #define FPIE1_OR_FPIC1_SPEC     NO_FPIE1_AND_FPIC1_SPEC ":;"
    1047              : #define NO_FPIE2_AND_FPIC2_SPEC NO_FPIE2_SPEC "|" NO_FPIC2_SPEC
    1048              : #define FPIE2_OR_FPIC2_SPEC     NO_FPIE2_AND_FPIC2_SPEC ":;"
    1049              : #define NO_FPIE_AND_FPIC_SPEC   NO_FPIE_SPEC "|" NO_FPIC_SPEC
    1050              : #define FPIE_OR_FPIC_SPEC       NO_FPIE_AND_FPIC_SPEC ":;"
    1051              : #else
    1052              : #define PIE_SPEC                "pie"
    1053              : #define FPIE1_SPEC              "fpie"
    1054              : #define NO_FPIE1_SPEC           FPIE1_SPEC ":;"
    1055              : #define FPIE2_SPEC              "fPIE"
    1056              : #define NO_FPIE2_SPEC           FPIE2_SPEC ":;"
    1057              : #define FPIE_SPEC               FPIE1_SPEC "|" FPIE2_SPEC
    1058              : #define NO_FPIE_SPEC            FPIE_SPEC ":;"
    1059              : #define FPIC1_SPEC              "fpic"
    1060              : #define NO_FPIC1_SPEC           FPIC1_SPEC ":;"
    1061              : #define FPIC2_SPEC              "fPIC"
    1062              : #define NO_FPIC2_SPEC           FPIC2_SPEC ":;"
    1063              : #define FPIC_SPEC               FPIC1_SPEC "|" FPIC2_SPEC
    1064              : #define NO_FPIC_SPEC            FPIC_SPEC ":;"
    1065              : #define FPIE1_OR_FPIC1_SPEC     FPIE1_SPEC "|" FPIC1_SPEC
    1066              : #define NO_FPIE1_AND_FPIC1_SPEC FPIE1_OR_FPIC1_SPEC ":;"
    1067              : #define FPIE2_OR_FPIC2_SPEC     FPIE2_SPEC "|" FPIC2_SPEC
    1068              : #define NO_FPIE2_AND_FPIC2_SPEC FPIE1_OR_FPIC2_SPEC ":;"
    1069              : #define FPIE_OR_FPIC_SPEC       FPIE_SPEC "|" FPIC_SPEC
    1070              : #define NO_FPIE_AND_FPIC_SPEC   FPIE_OR_FPIC_SPEC ":;"
    1071              : #endif
    1072              : 
    1073              : #ifndef LINK_PIE_SPEC
    1074              : #ifdef HAVE_LD_PIE
    1075              : #ifndef LD_PIE_SPEC
    1076              : #define LD_PIE_SPEC "-pie"
    1077              : #endif
    1078              : #else
    1079              : #define LD_PIE_SPEC ""
    1080              : #endif
    1081              : #define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} "
    1082              : #endif
    1083              : 
    1084              : #ifndef LINK_BUILDID_SPEC
    1085              : # if defined(HAVE_LD_BUILDID) && defined(ENABLE_LD_BUILDID)
    1086              : #  define LINK_BUILDID_SPEC "%{!r:--build-id} "
    1087              : # endif
    1088              : #endif
    1089              : 
    1090              : #ifndef LTO_PLUGIN_SPEC
    1091              : #define LTO_PLUGIN_SPEC ""
    1092              : #endif
    1093              : 
    1094              : /* Conditional to test whether the LTO plugin is used or not.
    1095              :    FIXME: For slim LTO we will need to enable plugin unconditionally.  This
    1096              :    still cause problems with PLUGIN_LD != LD and when plugin is built but
    1097              :    not useable.  For GCC 4.6 we don't support slim LTO and thus we can enable
    1098              :    plugin only when LTO is enabled.  We still honor explicit
    1099              :    -fuse-linker-plugin if the linker used understands -plugin.  */
    1100              : 
    1101              : /* The linker has some plugin support.  */
    1102              : #if HAVE_LTO_PLUGIN > 0
    1103              : /* The linker used has full plugin support, use LTO plugin by default.  */
    1104              : #if HAVE_LTO_PLUGIN == 2
    1105              : #define PLUGIN_COND "!fno-use-linker-plugin:%{!fno-lto"
    1106              : #define PLUGIN_COND_CLOSE "}"
    1107              : #else
    1108              : /* The linker used has limited plugin support, use LTO plugin with explicit
    1109              :    -fuse-linker-plugin.  */
    1110              : #define PLUGIN_COND "fuse-linker-plugin"
    1111              : #define PLUGIN_COND_CLOSE ""
    1112              : #endif
    1113              : #define LINK_PLUGIN_SPEC \
    1114              :     "%{" PLUGIN_COND": \
    1115              :     -plugin %(linker_plugin_file) \
    1116              :     -plugin-opt=%(lto_wrapper) \
    1117              :     -plugin-opt=-fresolution=%u.res \
    1118              :     " LTO_PLUGIN_SPEC "\
    1119              :     %{flinker-output=*:-plugin-opt=-linker-output-known} \
    1120              :     %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
    1121              :     }" PLUGIN_COND_CLOSE
    1122              : #else
    1123              : /* The linker used doesn't support -plugin, reject -fuse-linker-plugin.  */
    1124              : #define LINK_PLUGIN_SPEC "%{fuse-linker-plugin:\
    1125              :     %e-fuse-linker-plugin is not supported in this configuration}"
    1126              : #endif
    1127              : 
    1128              : /* Linker command line options for -fsanitize= early on the command line.  */
    1129              : #ifndef SANITIZER_EARLY_SPEC
    1130              : #define SANITIZER_EARLY_SPEC "\
    1131              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
    1132              :     %{%:sanitize(hwaddress):" LIBHWASAN_EARLY_SPEC "} \
    1133              :     %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
    1134              :     %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}}"
    1135              : #endif
    1136              : 
    1137              : /* Linker command line options for -fsanitize= late on the command line.  */
    1138              : #ifndef SANITIZER_SPEC
    1139              : #define SANITIZER_SPEC "\
    1140              : %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
    1141              :     %{static:%ecannot specify -static with -fsanitize=address}}\
    1142              :     %{%:sanitize(hwaddress):" LIBHWASAN_SPEC "\
    1143              :         %{static:%ecannot specify -static with -fsanitize=hwaddress}}\
    1144              :     %{%:sanitize(thread):" LIBTSAN_SPEC "\
    1145              :     %{static:%ecannot specify -static with -fsanitize=thread}}\
    1146              :     %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
    1147              :     %{%:sanitize(leak):" LIBLSAN_SPEC "}}}}"
    1148              : #endif
    1149              : 
    1150              : #ifndef POST_LINK_SPEC
    1151              : #define POST_LINK_SPEC ""
    1152              : #endif
    1153              : 
    1154              : /*  This is the spec to use, once the code for creating the vtable
    1155              :     verification runtime library, libvtv.so, has been created.  Currently
    1156              :     the vtable verification runtime functions are in libstdc++, so we use
    1157              :     the spec just below this one.  */
    1158              : #ifndef VTABLE_VERIFICATION_SPEC
    1159              : #if ENABLE_VTABLE_VERIFY
    1160              : #define VTABLE_VERIFICATION_SPEC "\
    1161              : %{!nostdlib:%{!r:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
    1162              :     %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}}"
    1163              : #else
    1164              : #define VTABLE_VERIFICATION_SPEC "\
    1165              : %{fvtable-verify=none:} \
    1166              : %{fvtable-verify=std: \
    1167              :   %e-fvtable-verify=std is not supported in this configuration} \
    1168              : %{fvtable-verify=preinit: \
    1169              :   %e-fvtable-verify=preinit is not supported in this configuration}"
    1170              : #endif
    1171              : #endif
    1172              : 
    1173              : /* -u* was put back because both BSD and SysV seem to support it.  */
    1174              : /* %{static|no-pie|static-pie:} simply prevents an error message:
    1175              :    1. If the target machine doesn't handle -static.
    1176              :    2. If PIE isn't enabled by default.
    1177              :    3. If the target machine doesn't handle -static-pie.
    1178              :  */
    1179              : /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
    1180              :    scripts which exist in user specified directories, or in standard
    1181              :    directories.  */
    1182              : /* We pass any -flto flags on to the linker, which is expected
    1183              :    to understand them.  In practice, this means it had better be collect2.  */
    1184              : /* %{e*} includes -export-dynamic; see comment in common.opt.  */
    1185              : #ifndef LINK_COMMAND_SPEC
    1186              : #define LINK_COMMAND_SPEC "\
    1187              : %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
    1188              :     %(linker) " \
    1189              :     LINK_PLUGIN_SPEC \
    1190              :    "%{flto|flto=*:%<fcompare-debug*} \
    1191              :     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    1192              :    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    1193              :    "%X %{o*} %{e*} %{N} %{n} %{r}\
    1194              :     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
    1195              :     %{static|no-pie|static-pie:} %@{L*} %(link_libgcc) " \
    1196              :     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o "" \
    1197              :     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
    1198              :         %:include(libgomp.spec)%(link_gomp)}\
    1199              :     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
    1200              :     " STACK_SPLIT_SPEC "\
    1201              :     %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
    1202              :     %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\
    1203              :     %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*}  \n%(post_link) }}}}}}"
    1204              : #endif
    1205              : 
    1206              : #ifndef LINK_LIBGCC_SPEC
    1207              : /* Generate -L options for startfile prefix list.  */
    1208              : # define LINK_LIBGCC_SPEC "%D"
    1209              : #endif
    1210              : 
    1211              : #ifndef STARTFILE_PREFIX_SPEC
    1212              : # define STARTFILE_PREFIX_SPEC ""
    1213              : #endif
    1214              : 
    1215              : #ifndef SYSROOT_SPEC
    1216              : # define SYSROOT_SPEC "--sysroot=%R"
    1217              : #endif
    1218              : 
    1219              : #ifndef SYSROOT_SUFFIX_SPEC
    1220              : # define SYSROOT_SUFFIX_SPEC ""
    1221              : #endif
    1222              : 
    1223              : #ifndef SYSROOT_HEADERS_SUFFIX_SPEC
    1224              : # define SYSROOT_HEADERS_SUFFIX_SPEC ""
    1225              : #endif
    1226              : 
    1227              : #ifndef RUNPATH_OPTION
    1228              : # define RUNPATH_OPTION "-rpath"
    1229              : #endif
    1230              : 
    1231              : static const char *asm_debug = ASM_DEBUG_SPEC;
    1232              : static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC;
    1233              : static const char *cpp_spec = CPP_SPEC LIBC_CPP_SPEC;
    1234              : static const char *cc1_spec = CC1_SPEC OS_CC1_SPEC;
    1235              : static const char *cc1plus_spec = CC1PLUS_SPEC;
    1236              : static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
    1237              : static const char *link_ssp_spec = LINK_SSP_SPEC;
    1238              : static const char *asm_spec = ASM_SPEC;
    1239              : static const char *asm_final_spec = ASM_FINAL_SPEC;
    1240              : static const char *link_spec = LINK_SPEC LIBC_LINK_SPEC;
    1241              : static const char *lib_spec = LIB_SPEC;
    1242              : static const char *link_gomp_spec = "";
    1243              : static const char *libgcc_spec = LIBGCC_SPEC;
    1244              : static const char *endfile_spec = ENDFILE_SPEC;
    1245              : static const char *startfile_spec = STARTFILE_SPEC;
    1246              : static const char *linker_name_spec = LINKER_NAME;
    1247              : static const char *linker_plugin_file_spec = "";
    1248              : static const char *lto_wrapper_spec = "";
    1249              : static const char *lto_gcc_spec = "";
    1250              : static const char *post_link_spec = POST_LINK_SPEC;
    1251              : static const char *link_command_spec = LINK_COMMAND_SPEC;
    1252              : static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
    1253              : static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
    1254              : static const char *sysroot_spec = SYSROOT_SPEC;
    1255              : static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
    1256              : static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
    1257              : static const char *self_spec = "";
    1258              : 
    1259              : /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    1260              :    There should be no need to override these in target dependent files,
    1261              :    but we need to copy them to the specs file so that newer versions
    1262              :    of the GCC driver can correctly drive older tool chains with the
    1263              :    appropriate -B options.  */
    1264              : 
    1265              : /* When cpplib handles traditional preprocessing, get rid of this, and
    1266              :    call cc1 (or cc1obj in objc/lang-specs.h) from the main specs so
    1267              :    that we default the front end language better.  */
    1268              : static const char *trad_capable_cpp =
    1269              : "cc1 -E %{traditional|traditional-cpp:-traditional-cpp}";
    1270              : 
    1271              : /* We don't wrap .d files in %W{} since a missing .d file, and
    1272              :    therefore no dependency entry, confuses make into thinking a .o
    1273              :    file that happens to exist is up-to-date.  */
    1274              : static const char *cpp_unique_options =
    1275              : "%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %@{I*&F*} %{P} %I\
    1276              :  %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
    1277              :  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
    1278              :  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
    1279              :  %{Mmodules} %{Mno-modules}\
    1280              :  %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
    1281              :  %{remap} %{%:debug-level-gt(2):-dD}\
    1282              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1283              :  %{H} %C %{D*&U*&A*} %{i*} %Z %i\
    1284              :  %{E|M|MM:%W{o*}} %{-embed*}\
    1285              :  %{fdeps-format=*:%{!fdeps-file=*:-fdeps-file=%:join(%{!o:%b.ddi}%{o*:%.ddi%*})}}\
    1286              :  %{fdeps-format=*:%{!fdeps-target=*:-fdeps-target=%:join(%{!o:%b.o}%{o*:%.o%*})}}";
    1287              : 
    1288              : /* This contains cpp options which are common with cc1_options and are passed
    1289              :    only when preprocessing only to avoid duplication.  We pass the cc1 spec
    1290              :    options to the preprocessor so that it the cc1 spec may manipulate
    1291              :    options used to set target flags.  Those special target flags settings may
    1292              :    in turn cause preprocessor symbols to be defined specially.  */
    1293              : static const char *cpp_options =
    1294              : "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
    1295              :  %{f*} %{g*:%{%:debug-level-gt(0):%{g*}\
    1296              :  %{!fno-working-directory:-fworking-directory}}} %{O*}\
    1297              :  %{undef} %{save-temps*:-fpch-preprocess}";
    1298              : 
    1299              : /* Pass -d* flags, possibly modifying -dumpdir, -dumpbase et al.
    1300              : 
    1301              :    Make it easy for a language to override the argument for the
    1302              :    %:dumps specs function call.  */
    1303              : #define DUMPS_OPTIONS(EXTS) \
    1304              :   "%<dumpdir %<dumpbase %<dumpbase-ext %{d*} %:dumps(" EXTS ")"
    1305              : 
    1306              : /* This contains cpp options which are not passed when the preprocessor
    1307              :    output will be used by another program.  */
    1308              : static const char *cpp_debug_options = DUMPS_OPTIONS ("");
    1309              : 
    1310              : /* NB: This is shared amongst all front-ends, except for Ada.  */
    1311              : static const char *cc1_options =
    1312              : "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
    1313              :  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
    1314              :  %1 %{!Q:-quiet} %(cpp_debug_options) %{m*} %{aux-info*}\
    1315              :  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
    1316              :  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
    1317              :  %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
    1318              :  %{-target-help:--target-help}\
    1319              :  %{-version:--version}\
    1320              :  %{-help=*:--help=%*}\
    1321              :  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %w%b.s}}}\
    1322              :  %{fsyntax-only:-o %j} %{-param*}\
    1323              :  %{coverage:-fprofile-arcs -ftest-coverage}\
    1324              :  %{fprofile-arcs|fcondition-coverage|fpath-coverage|fprofile-generate*|coverage:\
    1325              :    %{!fprofile-update=single:\
    1326              :      %{pthread:-fprofile-update=prefer-atomic}}}";
    1327              : 
    1328              : static const char *asm_options =
    1329              : "%{-target-help:%:print-asm-header()} "
    1330              : #if HAVE_GNU_AS
    1331              : /* If GNU AS is used, then convert -w (no warnings), -I, and -v
    1332              :    to the assembler equivalents.  */
    1333              : "%{v} %{w:-W} %{I*} "
    1334              : #endif
    1335              : "%(asm_debug_option)"
    1336              : ASM_COMPRESS_DEBUG_SPEC
    1337              : "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
    1338              : 
    1339              : static const char *invoke_as =
    1340              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1341              : "%{!fwpa*:\
    1342              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1343              :    %{!S:-o %|.s |\n as %(asm_options) %|.s %A }\
    1344              :   }";
    1345              : #else
    1346              : "%{!fwpa*:\
    1347              :    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    1348              :    %{!S:-o %|.s |\n as %(asm_options) %m.s %A }\
    1349              :   }";
    1350              : #endif
    1351              : 
    1352              : /* Some compilers have limits on line lengths, and the multilib_select
    1353              :    and/or multilib_matches strings can be very long, so we build them at
    1354              :    run time.  */
    1355              : static struct obstack multilib_obstack;
    1356              : static const char *multilib_select;
    1357              : static const char *multilib_matches;
    1358              : static const char *multilib_defaults;
    1359              : static const char *multilib_exclusions;
    1360              : static const char *multilib_reuse;
    1361              : 
    1362              : /* Check whether a particular argument is a default argument.  */
    1363              : 
    1364              : #ifndef MULTILIB_DEFAULTS
    1365              : #define MULTILIB_DEFAULTS { "" }
    1366              : #endif
    1367              : 
    1368              : static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
    1369              : 
    1370              : #ifndef DRIVER_SELF_SPECS
    1371              : #define DRIVER_SELF_SPECS ""
    1372              : #endif
    1373              : 
    1374              : /* Linking to libgomp implies pthreads.  This is particularly important
    1375              :    for targets that use different start files and suchlike.  */
    1376              : #ifndef GOMP_SELF_SPECS
    1377              : #define GOMP_SELF_SPECS \
    1378              :   "%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): " \
    1379              :   "-pthread}"
    1380              : #endif
    1381              : 
    1382              : /* Likewise for -fgnu-tm.  */
    1383              : #ifndef GTM_SELF_SPECS
    1384              : #define GTM_SELF_SPECS "%{fgnu-tm: -pthread}"
    1385              : #endif
    1386              : 
    1387              : static const char *const driver_self_specs[] = {
    1388              :   "%{fdump-final-insns:-fdump-final-insns=.} %<fdump-final-insns",
    1389              :   DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS,
    1390              :   /* This discards -fmultiflags at the end of self specs processing in the
    1391              :      driver, so that it is effectively Ignored, without actually marking it as
    1392              :      Ignored, which would get it discarded before self specs could remap it.  */
    1393              :   "%<fmultiflags"
    1394              : };
    1395              : 
    1396              : #ifndef OPTION_DEFAULT_SPECS
    1397              : #define OPTION_DEFAULT_SPECS { "", "" }
    1398              : #endif
    1399              : 
    1400              : struct default_spec
    1401              : {
    1402              :   const char *name;
    1403              :   const char *spec;
    1404              : };
    1405              : 
    1406              : static const struct default_spec
    1407              :   option_default_specs[] = { OPTION_DEFAULT_SPECS };
    1408              : 
    1409              : struct user_specs
    1410              : {
    1411              :   struct user_specs *next;
    1412              :   const char *filename;
    1413              : };
    1414              : 
    1415              : static struct user_specs *user_specs_head, *user_specs_tail;
    1416              : 
    1417              : 
    1418              : /* Record the mapping from file suffixes for compilation specs.  */
    1419              : 
    1420              : struct compiler
    1421              : {
    1422              :   const char *suffix;           /* Use this compiler for input files
    1423              :                                    whose names end in this suffix.  */
    1424              : 
    1425              :   const char *spec;             /* To use this compiler, run this spec.  */
    1426              : 
    1427              :   const char *cpp_spec;         /* If non-NULL, substitute this spec
    1428              :                                    for `%C', rather than the usual
    1429              :                                    cpp_spec.  */
    1430              :   int combinable;               /* If nonzero, compiler can deal with
    1431              :                                     multiple source files at once (IMA).  */
    1432              :   int needs_preprocessing;       /* If nonzero, source files need to
    1433              :                                     be run through a preprocessor.  */
    1434              : };
    1435              : 
    1436              : /* Pointer to a vector of `struct compiler' that gives the spec for
    1437              :    compiling a file, based on its suffix.
    1438              :    A file that does not end in any of these suffixes will be passed
    1439              :    unchanged to the loader and nothing else will be done to it.
    1440              : 
    1441              :    An entry containing two 0s is used to terminate the vector.
    1442              : 
    1443              :    If multiple entries match a file, the last matching one is used.  */
    1444              : 
    1445              : static struct compiler *compilers;
    1446              : 
    1447              : /* Number of entries in `compilers', not counting the null terminator.  */
    1448              : 
    1449              : static int n_compilers;
    1450              : 
    1451              : /* The default list of file name suffixes and their compilation specs.  */
    1452              : 
    1453              : static const struct compiler default_compilers[] =
    1454              : {
    1455              :   /* Add lists of suffixes of known languages here.  If those languages
    1456              :      were not present when we built the driver, we will hit these copies
    1457              :      and be given a more meaningful error than "file not used since
    1458              :      linking is not done".  */
    1459              :   {".m",  "#Objective-C", 0, 0, 0}, {".mi",  "#Objective-C", 0, 0, 0},
    1460              :   {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
    1461              :   {".mii", "#Objective-C++", 0, 0, 0},
    1462              :   {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
    1463              :   {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
    1464              :   {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
    1465              :   {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
    1466              :   {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
    1467              :   {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
    1468              :   {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
    1469              :   {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0},
    1470              :   {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
    1471              :   {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0},
    1472              :   {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
    1473              :   {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0},
    1474              :   {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0},
    1475              :   {".r", "#Ratfor", 0, 0, 0},
    1476              :   {".go", "#Go", 0, 1, 0},
    1477              :   {".d", "#D", 0, 1, 0}, {".dd", "#D", 0, 1, 0}, {".di", "#D", 0, 1, 0},
    1478              :   {".mod", "#Modula-2", 0, 0, 0}, {".m2i", "#Modula-2", 0, 0, 0},
    1479              :   /* Next come the entries for C.  */
    1480              :   {".c", "@c", 0, 0, 1},
    1481              :   {"@c",
    1482              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1483              :       external preprocessor if -save-temps is given.  */
    1484              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1485              :       %{!E:%{!M:%{!MM:\
    1486              :           %{traditional:\
    1487              : %eGNU C no longer supports -traditional without -E}\
    1488              :       %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1489              :           %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1490              :             cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1491              :           %(cc1_options)}\
    1492              :       %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1493              :           cc1 %(cpp_unique_options) %(cc1_options)}}}\
    1494              :       %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
    1495              :   {"-",
    1496              :    "%{!E:%e-E or -x required when input is from standard input}\
    1497              :     %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
    1498              :   {".h", "@c-header", 0, 0, 0},
    1499              :   {"@c-header",
    1500              :    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
    1501              :       external preprocessor if -save-temps is given.  */
    1502              :      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
    1503              :       %{!E:%{!M:%{!MM:\
    1504              :           %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
    1505              :                 %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
    1506              :                     cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
    1507              :                         %(cc1_options)\
    1508              :                         %{!fsyntax-only:%{!S:-o %g.s} \
    1509              :                             %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1510              :                                                %W{o*:--output-pch %w%*}}%{!S:%V}}}\
    1511              :           %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
    1512              :                 cc1 %(cpp_unique_options) %(cc1_options)\
    1513              :                     %{!fsyntax-only:%{!S:-o %g.s} \
    1514              :                         %{!fdump-ada-spec*:%{!o*:--output-pch %w%i.gch}\
    1515              :                                            %W{o*:--output-pch %w%*}}%{!S:%V}}}}}}}}", 0, 0, 0},
    1516              :   {".i", "@cpp-output", 0, 0, 0},
    1517              :   {"@cpp-output",
    1518              :    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
    1519              :   {".s", "@assembler", 0, 0, 0},
    1520              :   {"@assembler",
    1521              :    "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
    1522              :   {".sx", "@assembler-with-cpp", 0, 0, 0},
    1523              :   {".S", "@assembler-with-cpp", 0, 0, 0},
    1524              :   {"@assembler-with-cpp",
    1525              : #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    1526              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1527              :       %{E|M|MM:%(cpp_debug_options)}\
    1528              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1529              :        as %(asm_debug) %(asm_options) %|.s %A }}}}"
    1530              : #else
    1531              :    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
    1532              :       %{E|M|MM:%(cpp_debug_options)}\
    1533              :       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
    1534              :        as %(asm_debug) %(asm_options) %m.s %A }}}}"
    1535              : #endif
    1536              :    , 0, 0, 0},
    1537              : 
    1538              : #ifndef EXTRA_DEFAULT_COMPILERS
    1539              : #define EXTRA_DEFAULT_COMPILERS
    1540              : #endif
    1541              :   EXTRA_DEFAULT_COMPILERS
    1542              : 
    1543              : #include "specs.h"
    1544              :   /* Mark end of table.  */
    1545              :   {0, 0, 0, 0, 0}
    1546              : };
    1547              : 
    1548              : /* Number of elements in default_compilers, not counting the terminator.  */
    1549              : 
    1550              : static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
    1551              : 
    1552              : typedef char *char_p; /* For DEF_VEC_P.  */
    1553              : 
    1554              : /* A vector of options to give to the linker.
    1555              :    These options are accumulated by %x,
    1556              :    and substituted into the linker command with %X.  */
    1557              : static vec<char_p> linker_options;
    1558              : 
    1559              : /* A vector of options to give to the assembler.
    1560              :    These options are accumulated by -Wa,
    1561              :    and substituted into the assembler command with %Y.  */
    1562              : static vec<char_p> assembler_options;
    1563              : 
    1564              : /* A vector of options to give to the preprocessor.
    1565              :    These options are accumulated by -Wp,
    1566              :    and substituted into the preprocessor command with %Z.  */
    1567              : static vec<char_p> preprocessor_options;
    1568              : 
    1569              : static char *
    1570     28949363 : skip_whitespace (char *p)
    1571              : {
    1572     67094697 :   while (1)
    1573              :     {
    1574              :       /* A fully-blank line is a delimiter in the SPEC file and shouldn't
    1575              :          be considered whitespace.  */
    1576     67094697 :       if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n')
    1577      4857552 :         return p + 1;
    1578     62237145 :       else if (*p == '\n' || *p == ' ' || *p == '\t')
    1579     38026180 :         p++;
    1580     24210965 :       else if (*p == '#')
    1581              :         {
    1582      3697451 :           while (*p != '\n')
    1583      3578297 :             p++;
    1584       119154 :           p++;
    1585              :         }
    1586              :       else
    1587              :         break;
    1588              :     }
    1589              : 
    1590              :   return p;
    1591              : }
    1592              : /* Structures to keep track of prefixes to try when looking for files.  */
    1593              : 
    1594              : struct prefix_list
    1595              : {
    1596              :   const char *prefix;         /* String to prepend to the path.  */
    1597              :   struct prefix_list *next;   /* Next in linked list.  */
    1598              :   int require_machine_suffix; /* Don't use without machine_suffix.  */
    1599              :   /* 2 means try both machine_suffix and just_machine_suffix.  */
    1600              :   int priority;               /* Sort key - priority within list.  */
    1601              :   int os_multilib;            /* 1 if OS multilib scheme should be used,
    1602              :                                  0 for GCC multilib scheme.  */
    1603              : };
    1604              : 
    1605              : struct path_prefix
    1606              : {
    1607              :   struct prefix_list *plist;  /* List of prefixes to try */
    1608              :   int max_len;                /* Max length of a prefix in PLIST */
    1609              :   const char *name;           /* Name of this list (used in config stuff) */
    1610              : };
    1611              : 
    1612              : /* List of prefixes to try when looking for executables.  */
    1613              : 
    1614              : static struct path_prefix exec_prefixes = { 0, 0, "exec" };
    1615              : 
    1616              : /* List of prefixes to try when looking for startup (crt0) files.  */
    1617              : 
    1618              : static struct path_prefix startfile_prefixes = { 0, 0, "startfile" };
    1619              : 
    1620              : /* List of prefixes to try when looking for include files.  */
    1621              : 
    1622              : static struct path_prefix include_prefixes = { 0, 0, "include" };
    1623              : 
    1624              : /* Suffix to attach to directories searched for commands.
    1625              :    This looks like `MACHINE/VERSION/'.  */
    1626              : 
    1627              : static const char *machine_suffix = 0;
    1628              : 
    1629              : /* Suffix to attach to directories searched for commands.
    1630              :    This is just `MACHINE/'.  */
    1631              : 
    1632              : static const char *just_machine_suffix = 0;
    1633              : 
    1634              : /* Adjusted value of GCC_EXEC_PREFIX envvar.  */
    1635              : 
    1636              : static const char *gcc_exec_prefix;
    1637              : 
    1638              : /* Adjusted value of standard_libexec_prefix.  */
    1639              : 
    1640              : static const char *gcc_libexec_prefix;
    1641              : 
    1642              : /* Default prefixes to attach to command names.  */
    1643              : 
    1644              : #ifndef STANDARD_STARTFILE_PREFIX_1
    1645              : #define STANDARD_STARTFILE_PREFIX_1 "/lib/"
    1646              : #endif
    1647              : #ifndef STANDARD_STARTFILE_PREFIX_2
    1648              : #define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
    1649              : #endif
    1650              : 
    1651              : #ifdef CROSS_DIRECTORY_STRUCTURE  /* Don't use these prefixes for a cross compiler.  */
    1652              : #undef MD_EXEC_PREFIX
    1653              : #undef MD_STARTFILE_PREFIX
    1654              : #undef MD_STARTFILE_PREFIX_1
    1655              : #endif
    1656              : 
    1657              : /* If no prefixes defined, use the null string, which will disable them.  */
    1658              : #ifndef MD_EXEC_PREFIX
    1659              : #define MD_EXEC_PREFIX ""
    1660              : #endif
    1661              : #ifndef MD_STARTFILE_PREFIX
    1662              : #define MD_STARTFILE_PREFIX ""
    1663              : #endif
    1664              : #ifndef MD_STARTFILE_PREFIX_1
    1665              : #define MD_STARTFILE_PREFIX_1 ""
    1666              : #endif
    1667              : 
    1668              : /* These directories are locations set at configure-time based on the
    1669              :    --prefix option provided to configure.  Their initializers are
    1670              :    defined in Makefile.in.  These paths are not *directly* used when
    1671              :    gcc_exec_prefix is set because, in that case, we know where the
    1672              :    compiler has been installed, and use paths relative to that
    1673              :    location instead.  */
    1674              : static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
    1675              : static const char *const standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
    1676              : static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
    1677              : static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
    1678              : 
    1679              : /* For native compilers, these are well-known paths containing
    1680              :    components that may be provided by the system.  For cross
    1681              :    compilers, these paths are not used.  */
    1682              : static const char *md_exec_prefix = MD_EXEC_PREFIX;
    1683              : static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
    1684              : static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
    1685              : static const char *const standard_startfile_prefix_1
    1686              :   = STANDARD_STARTFILE_PREFIX_1;
    1687              : static const char *const standard_startfile_prefix_2
    1688              :   = STANDARD_STARTFILE_PREFIX_2;
    1689              : 
    1690              : /* A relative path to be used in finding the location of tools
    1691              :    relative to the driver.  */
    1692              : static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
    1693              : 
    1694              : /* A prefix to be used when this is an accelerator compiler.  */
    1695              : static const char *const accel_dir_suffix = ACCEL_DIR_SUFFIX;
    1696              : 
    1697              : /* Subdirectory to use for locating libraries.  Set by
    1698              :    set_multilib_dir based on the compilation options.  */
    1699              : 
    1700              : static const char *multilib_dir;
    1701              : 
    1702              : /* Subdirectory to use for locating libraries in OS conventions.  Set by
    1703              :    set_multilib_dir based on the compilation options.  */
    1704              : 
    1705              : static const char *multilib_os_dir;
    1706              : 
    1707              : /* Subdirectory to use for locating libraries in multiarch conventions.  Set by
    1708              :    set_multilib_dir based on the compilation options.  */
    1709              : 
    1710              : static const char *multiarch_dir;
    1711              : 
    1712              : /* Structure to keep track of the specs that have been defined so far.
    1713              :    These are accessed using %(specname) in a compiler or link
    1714              :    spec.  */
    1715              : 
    1716              : struct spec_list
    1717              : {
    1718              :                                 /* The following 2 fields must be first */
    1719              :                                 /* to allow EXTRA_SPECS to be initialized */
    1720              :   const char *name;             /* name of the spec.  */
    1721              :   const char *ptr;              /* available ptr if no static pointer */
    1722              : 
    1723              :                                 /* The following fields are not initialized */
    1724              :                                 /* by EXTRA_SPECS */
    1725              :   const char **ptr_spec;        /* pointer to the spec itself.  */
    1726              :   struct spec_list *next;       /* Next spec in linked list.  */
    1727              :   int name_len;                 /* length of the name */
    1728              :   bool user_p;                  /* whether string come from file spec.  */
    1729              :   bool alloc_p;                 /* whether string was allocated */
    1730              :   const char *default_ptr;      /* The default value of *ptr_spec.  */
    1731              : };
    1732              : 
    1733              : #define INIT_STATIC_SPEC(NAME,PTR) \
    1734              :   { NAME, NULL, PTR, (struct spec_list *) 0, sizeof (NAME) - 1, false, false, \
    1735              :     *PTR }
    1736              : 
    1737              : /* List of statically defined specs.  */
    1738              : static struct spec_list static_specs[] =
    1739              : {
    1740              :   INIT_STATIC_SPEC ("asm",                    &asm_spec),
    1741              :   INIT_STATIC_SPEC ("asm_debug",              &asm_debug),
    1742              :   INIT_STATIC_SPEC ("asm_debug_option",               &asm_debug_option),
    1743              :   INIT_STATIC_SPEC ("asm_final",              &asm_final_spec),
    1744              :   INIT_STATIC_SPEC ("asm_options",            &asm_options),
    1745              :   INIT_STATIC_SPEC ("invoke_as",              &invoke_as),
    1746              :   INIT_STATIC_SPEC ("cpp",                    &cpp_spec),
    1747              :   INIT_STATIC_SPEC ("cpp_options",            &cpp_options),
    1748              :   INIT_STATIC_SPEC ("cpp_debug_options",      &cpp_debug_options),
    1749              :   INIT_STATIC_SPEC ("cpp_unique_options",     &cpp_unique_options),
    1750              :   INIT_STATIC_SPEC ("trad_capable_cpp",               &trad_capable_cpp),
    1751              :   INIT_STATIC_SPEC ("cc1",                    &cc1_spec),
    1752              :   INIT_STATIC_SPEC ("cc1_options",            &cc1_options),
    1753              :   INIT_STATIC_SPEC ("cc1plus",                        &cc1plus_spec),
    1754              :   INIT_STATIC_SPEC ("link_gcc_c_sequence",    &link_gcc_c_sequence_spec),
    1755              :   INIT_STATIC_SPEC ("link_ssp",                       &link_ssp_spec),
    1756              :   INIT_STATIC_SPEC ("endfile",                        &endfile_spec),
    1757              :   INIT_STATIC_SPEC ("link",                   &link_spec),
    1758              :   INIT_STATIC_SPEC ("lib",                    &lib_spec),
    1759              :   INIT_STATIC_SPEC ("link_gomp",              &link_gomp_spec),
    1760              :   INIT_STATIC_SPEC ("libgcc",                 &libgcc_spec),
    1761              :   INIT_STATIC_SPEC ("startfile",              &startfile_spec),
    1762              :   INIT_STATIC_SPEC ("cross_compile",          &cross_compile),
    1763              :   INIT_STATIC_SPEC ("version",                        &compiler_version),
    1764              :   INIT_STATIC_SPEC ("multilib",                       &multilib_select),
    1765              :   INIT_STATIC_SPEC ("multilib_defaults",      &multilib_defaults),
    1766              :   INIT_STATIC_SPEC ("multilib_extra",         &multilib_extra),
    1767              :   INIT_STATIC_SPEC ("multilib_matches",               &multilib_matches),
    1768              :   INIT_STATIC_SPEC ("multilib_exclusions",    &multilib_exclusions),
    1769              :   INIT_STATIC_SPEC ("multilib_options",               &multilib_options),
    1770              :   INIT_STATIC_SPEC ("multilib_reuse",         &multilib_reuse),
    1771              :   INIT_STATIC_SPEC ("linker",                 &linker_name_spec),
    1772              :   INIT_STATIC_SPEC ("linker_plugin_file",     &linker_plugin_file_spec),
    1773              :   INIT_STATIC_SPEC ("lto_wrapper",            &lto_wrapper_spec),
    1774              :   INIT_STATIC_SPEC ("lto_gcc",                        &lto_gcc_spec),
    1775              :   INIT_STATIC_SPEC ("post_link",              &post_link_spec),
    1776              :   INIT_STATIC_SPEC ("link_libgcc",            &link_libgcc_spec),
    1777              :   INIT_STATIC_SPEC ("md_exec_prefix",         &md_exec_prefix),
    1778              :   INIT_STATIC_SPEC ("md_startfile_prefix",    &md_startfile_prefix),
    1779              :   INIT_STATIC_SPEC ("md_startfile_prefix_1",  &md_startfile_prefix_1),
    1780              :   INIT_STATIC_SPEC ("startfile_prefix_spec",  &startfile_prefix_spec),
    1781              :   INIT_STATIC_SPEC ("sysroot_spec",             &sysroot_spec),
    1782              :   INIT_STATIC_SPEC ("sysroot_suffix_spec",    &sysroot_suffix_spec),
    1783              :   INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec",       &sysroot_hdrs_suffix_spec),
    1784              :   INIT_STATIC_SPEC ("self_spec",              &self_spec),
    1785              : };
    1786              : 
    1787              : #ifdef EXTRA_SPECS              /* additional specs needed */
    1788              : /* Structure to keep track of just the first two args of a spec_list.
    1789              :    That is all that the EXTRA_SPECS macro gives us.  */
    1790              : struct spec_list_1
    1791              : {
    1792              :   const char *const name;
    1793              :   const char *const ptr;
    1794              : };
    1795              : 
    1796              : static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
    1797              : static struct spec_list *extra_specs = (struct spec_list *) 0;
    1798              : #endif
    1799              : 
    1800              : /* List of dynamically allocates specs that have been defined so far.  */
    1801              : 
    1802              : static struct spec_list *specs = (struct spec_list *) 0;
    1803              : 
    1804              : /* List of static spec functions.  */
    1805              : 
    1806              : static const struct spec_function static_spec_functions[] =
    1807              : {
    1808              :   { "getenv",                   getenv_spec_function },
    1809              :   { "if-exists",              if_exists_spec_function },
    1810              :   { "if-exists-else",         if_exists_else_spec_function },
    1811              :   { "if-exists-then-else",    if_exists_then_else_spec_function },
    1812              :   { "sanitize",                       sanitize_spec_function },
    1813              :   { "replace-outfile",                replace_outfile_spec_function },
    1814              :   { "remove-outfile",         remove_outfile_spec_function },
    1815              :   { "version-compare",                version_compare_spec_function },
    1816              :   { "include",                        include_spec_function },
    1817              :   { "find-file",              find_file_spec_function },
    1818              :   { "find-plugindir",         find_plugindir_spec_function },
    1819              :   { "print-asm-header",               print_asm_header_spec_function },
    1820              :   { "compare-debug-dump-opt", compare_debug_dump_opt_spec_function },
    1821              :   { "compare-debug-self-opt", compare_debug_self_opt_spec_function },
    1822              :   { "pass-through-libs",      pass_through_libs_spec_func },
    1823              :   { "dumps",                    dumps_spec_func },
    1824              :   { "gt",                     greater_than_spec_func },
    1825              :   { "debug-level-gt",         debug_level_greater_than_spec_func },
    1826              :   { "dwarf-version-gt",               dwarf_version_greater_than_spec_func },
    1827              :   { "fortran-preinclude-file",        find_fortran_preinclude_file},
    1828              :   { "join",                   join_spec_func},
    1829              : #ifdef EXTRA_SPEC_FUNCTIONS
    1830              :   EXTRA_SPEC_FUNCTIONS
    1831              : #endif
    1832              :   { 0, 0 }
    1833              : };
    1834              : 
    1835              : static int processing_spec_function;
    1836              : 
    1837              : /* Add appropriate libgcc specs to OBSTACK, taking into account
    1838              :    various permutations of -shared-libgcc, -shared, and such.  */
    1839              : 
    1840              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1841              : 
    1842              : #ifndef USE_LD_AS_NEEDED
    1843              : #define USE_LD_AS_NEEDED 0
    1844              : #endif
    1845              : 
    1846              : static void
    1847         1140 : init_gcc_specs (struct obstack *obstack, const char *shared_name,
    1848              :                 const char *static_name, const char *eh_name)
    1849              : {
    1850         1140 :   char *buf;
    1851              : 
    1852              : #if USE_LD_AS_NEEDED
    1853              : #if defined(USE_LD_AS_NEEDED_LDSCRIPT) && !defined(USE_LIBUNWIND_EXCEPTIONS)
    1854         1140 :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1855              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1856              :                 "%{!shared-libgcc:",
    1857              :                 static_name, " ",
    1858              :                 shared_name, "_asneeded}"
    1859              :                 "%{shared-libgcc:",
    1860              :                 shared_name, "%{!shared: ", static_name, "}"
    1861              :                 "}}"
    1862              : #else
    1863              :   buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
    1864              :                 "%{!static:%{!static-libgcc:%{!static-pie:"
    1865              :                 "%{!shared-libgcc:",
    1866              :                 static_name, " " LD_AS_NEEDED_OPTION " ",
    1867              :                 shared_name, " " LD_NO_AS_NEEDED_OPTION
    1868              :                 "}"
    1869              :                 "%{shared-libgcc:",
    1870              :                 shared_name, "%{!shared: ", static_name, "}"
    1871              :                 "}}"
    1872              : #endif
    1873              : #else
    1874              :   buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name, "}"
    1875              :                 "%{!static:%{!static-libgcc:"
    1876              :                 "%{!shared:"
    1877              :                 "%{!shared-libgcc:", static_name, " ", eh_name, "}"
    1878              :                 "%{shared-libgcc:", shared_name, " ", static_name, "}"
    1879              :                 "}"
    1880              : #ifdef LINK_EH_SPEC
    1881              :                 "%{shared:"
    1882              :                 "%{shared-libgcc:", shared_name, "}"
    1883              :                 "%{!shared-libgcc:", static_name, "}"
    1884              :                 "}"
    1885              : #else
    1886              :                 "%{shared:", shared_name, "}"
    1887              : #endif
    1888              : #endif
    1889              :                 "}}", NULL);
    1890              : 
    1891         1140 :   obstack_grow (obstack, buf, strlen (buf));
    1892         1140 :   free (buf);
    1893         1140 : }
    1894              : #endif /* ENABLE_SHARED_LIBGCC */
    1895              : 
    1896              : /* Initialize the specs lookup routines.  */
    1897              : 
    1898              : static void
    1899         1140 : init_spec (void)
    1900              : {
    1901         1140 :   struct spec_list *next = (struct spec_list *) 0;
    1902         1140 :   struct spec_list *sl   = (struct spec_list *) 0;
    1903         1140 :   int i;
    1904              : 
    1905         1140 :   if (specs)
    1906              :     return;                     /* Already initialized.  */
    1907              : 
    1908         1140 :   if (verbose_flag)
    1909           78 :     fnotice (stderr, "Using built-in specs.\n");
    1910              : 
    1911              : #ifdef EXTRA_SPECS
    1912         1140 :   extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1));
    1913              : 
    1914         2280 :   for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
    1915              :     {
    1916         1140 :       sl = &extra_specs[i];
    1917         1140 :       sl->name = extra_specs_1[i].name;
    1918         1140 :       sl->ptr = extra_specs_1[i].ptr;
    1919         1140 :       sl->next = next;
    1920         1140 :       sl->name_len = strlen (sl->name);
    1921         1140 :       sl->ptr_spec = &sl->ptr;
    1922         1140 :       gcc_assert (sl->ptr_spec != NULL);
    1923         1140 :       sl->default_ptr = sl->ptr;
    1924         1140 :       next = sl;
    1925              :     }
    1926              : #endif
    1927              : 
    1928        52440 :   for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    1929              :     {
    1930        51300 :       sl = &static_specs[i];
    1931        51300 :       sl->next = next;
    1932        51300 :       next = sl;
    1933              :     }
    1934              : 
    1935              : #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
    1936              :   /* ??? If neither -shared-libgcc nor --static-libgcc was
    1937              :      seen, then we should be making an educated guess.  Some proposed
    1938              :      heuristics for ELF include:
    1939              : 
    1940              :         (1) If "-Wl,--export-dynamic", then it's a fair bet that the
    1941              :             program will be doing dynamic loading, which will likely
    1942              :             need the shared libgcc.
    1943              : 
    1944              :         (2) If "-ldl", then it's also a fair bet that we're doing
    1945              :             dynamic loading.
    1946              : 
    1947              :         (3) For each ET_DYN we're linking against (either through -lfoo
    1948              :             or /some/path/foo.so), check to see whether it or one of
    1949              :             its dependencies depends on a shared libgcc.
    1950              : 
    1951              :         (4) If "-shared"
    1952              : 
    1953              :             If the runtime is fixed to look for program headers instead
    1954              :             of calling __register_frame_info at all, for each object,
    1955              :             use the shared libgcc if any EH symbol referenced.
    1956              : 
    1957              :             If crtstuff is fixed to not invoke __register_frame_info
    1958              :             automatically, for each object, use the shared libgcc if
    1959              :             any non-empty unwind section found.
    1960              : 
    1961              :      Doing any of this probably requires invoking an external program to
    1962              :      do the actual object file scanning.  */
    1963         1140 :   {
    1964         1140 :     const char *p = libgcc_spec;
    1965         1140 :     int in_sep = 1;
    1966              : 
    1967              :     /* Transform the extant libgcc_spec into one that uses the shared libgcc
    1968              :        when given the proper command line arguments.  */
    1969         2280 :     while (*p)
    1970              :       {
    1971         1140 :         if (in_sep && *p == '-' && startswith (p, "-lgcc"))
    1972              :           {
    1973         1140 :             init_gcc_specs (&obstack,
    1974              :                             "-lgcc_s"
    1975              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1976              :                             " -lunwind"
    1977              : #endif
    1978              :                             ,
    1979              :                             "-lgcc",
    1980              :                             "-lgcc_eh"
    1981              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    1982              : # ifdef HAVE_LD_STATIC_DYNAMIC
    1983              :                             " %{!static:%{!static-pie:" LD_STATIC_OPTION "}} -lunwind"
    1984              :                             " %{!static:%{!static-pie:" LD_DYNAMIC_OPTION "}}"
    1985              : # else
    1986              :                             " -lunwind"
    1987              : # endif
    1988              : #endif
    1989              :                             );
    1990              : 
    1991         1140 :             p += 5;
    1992         1140 :             in_sep = 0;
    1993              :           }
    1994            0 :         else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
    1995              :           {
    1996              :             /* Ug.  We don't know shared library extensions.  Hope that
    1997              :                systems that use this form don't do shared libraries.  */
    1998            0 :             init_gcc_specs (&obstack,
    1999              :                             "-lgcc_s",
    2000              :                             "libgcc.a%s",
    2001              :                             "libgcc_eh.a%s"
    2002              : #ifdef USE_LIBUNWIND_EXCEPTIONS
    2003              :                             " -lunwind"
    2004              : #endif
    2005              :                             );
    2006            0 :             p += 10;
    2007            0 :             in_sep = 0;
    2008              :           }
    2009              :         else
    2010              :           {
    2011            0 :             obstack_1grow (&obstack, *p);
    2012            0 :             in_sep = (*p == ' ');
    2013            0 :             p += 1;
    2014              :           }
    2015              :       }
    2016              : 
    2017         1140 :     obstack_1grow (&obstack, '\0');
    2018         1140 :     libgcc_spec = XOBFINISH (&obstack, const char *);
    2019              :   }
    2020              : #endif
    2021              : #ifdef USE_AS_TRADITIONAL_FORMAT
    2022              :   /* Prepend "--traditional-format" to whatever asm_spec we had before.  */
    2023              :   {
    2024              :     static const char tf[] = "--traditional-format ";
    2025              :     obstack_grow (&obstack, tf, sizeof (tf) - 1);
    2026              :     obstack_grow0 (&obstack, asm_spec, strlen (asm_spec));
    2027              :     asm_spec = XOBFINISH (&obstack, const char *);
    2028              :   }
    2029              : #endif
    2030              : 
    2031              : #if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC || \
    2032              :     defined LINKER_HASH_STYLE
    2033              : # ifdef LINK_BUILDID_SPEC
    2034              :   /* Prepend LINK_BUILDID_SPEC to whatever link_spec we had before.  */
    2035              :   obstack_grow (&obstack, LINK_BUILDID_SPEC, sizeof (LINK_BUILDID_SPEC) - 1);
    2036              : # endif
    2037              : # ifdef LINK_EH_SPEC
    2038              :   /* Prepend LINK_EH_SPEC to whatever link_spec we had before.  */
    2039         1140 :   obstack_grow (&obstack, LINK_EH_SPEC, sizeof (LINK_EH_SPEC) - 1);
    2040              : # endif
    2041              : # ifdef LINKER_HASH_STYLE
    2042              :   /* Prepend --hash-style=LINKER_HASH_STYLE to whatever link_spec we had
    2043              :      before.  */
    2044              :   {
    2045              :     static const char hash_style[] = "--hash-style=";
    2046              :     obstack_grow (&obstack, hash_style, sizeof (hash_style) - 1);
    2047              :     obstack_grow (&obstack, LINKER_HASH_STYLE, sizeof (LINKER_HASH_STYLE) - 1);
    2048              :     obstack_1grow (&obstack, ' ');
    2049              :   }
    2050              : # endif
    2051         1140 :   obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    2052         1140 :   link_spec = XOBFINISH (&obstack, const char *);
    2053              : #endif
    2054              : 
    2055         1140 :   specs = sl;
    2056              : }
    2057              : 
    2058              : /* Update the entry for SPEC in the static_specs table to point to VALUE,
    2059              :    ensuring that we free the previous value if necessary.  Set alloc_p for the
    2060              :    entry to ALLOC_P: this determines whether we take ownership of VALUE (i.e.
    2061              :    whether we need to free it later on).  */
    2062              : static void
    2063       213799 : set_static_spec (const char **spec, const char *value, bool alloc_p)
    2064              : {
    2065       213799 :   struct spec_list *sl = NULL;
    2066              : 
    2067      7379057 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
    2068              :     {
    2069      7379057 :       if (static_specs[i].ptr_spec == spec)
    2070              :         {
    2071       213799 :           sl = static_specs + i;
    2072       213799 :           break;
    2073              :         }
    2074              :     }
    2075              : 
    2076            0 :   gcc_assert (sl);
    2077              : 
    2078       213799 :   if (sl->alloc_p)
    2079              :     {
    2080       213799 :       const char *old = *spec;
    2081       213799 :       free (const_cast <char *> (old));
    2082              :     }
    2083              : 
    2084       213799 :   *spec = value;
    2085       213799 :   sl->alloc_p = alloc_p;
    2086       213799 : }
    2087              : 
    2088              : /* Update a static spec to a new string, taking ownership of that
    2089              :    string's memory.  */
    2090       114129 : static void set_static_spec_owned (const char **spec, const char *val)
    2091              : {
    2092            0 :   return set_static_spec (spec, val, true);
    2093              : }
    2094              : 
    2095              : /* Update a static spec to point to a new value, but don't take
    2096              :    ownership of (i.e. don't free) that string.  */
    2097        99670 : static void set_static_spec_shared (const char **spec, const char *val)
    2098              : {
    2099            0 :   return set_static_spec (spec, val, false);
    2100              : }
    2101              : 
    2102              : 
    2103              : /* Change the value of spec NAME to SPEC.  If SPEC is empty, then the spec is
    2104              :    removed; If the spec starts with a + then SPEC is added to the end of the
    2105              :    current spec.  */
    2106              : 
    2107              : static void
    2108     14014397 : set_spec (const char *name, const char *spec, bool user_p)
    2109              : {
    2110     14014397 :   struct spec_list *sl;
    2111     14014397 :   const char *old_spec;
    2112     14014397 :   int name_len = strlen (name);
    2113     14014397 :   int i;
    2114              : 
    2115              :   /* If this is the first call, initialize the statically allocated specs.  */
    2116     14014397 :   if (!specs)
    2117              :     {
    2118              :       struct spec_list *next = (struct spec_list *) 0;
    2119     13965462 :       for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
    2120              :         {
    2121     13661865 :           sl = &static_specs[i];
    2122     13661865 :           sl->next = next;
    2123     13661865 :           next = sl;
    2124              :         }
    2125       303597 :       specs = sl;
    2126              :     }
    2127              : 
    2128              :   /* See if the spec already exists.  */
    2129    329774928 :   for (sl = specs; sl; sl = sl->next)
    2130    329449838 :     if (name_len == sl->name_len && !strcmp (sl->name, name))
    2131              :       break;
    2132              : 
    2133     14014397 :   if (!sl)
    2134              :     {
    2135              :       /* Not found - make it.  */
    2136       325090 :       sl = XNEW (struct spec_list);
    2137       325090 :       sl->name = xstrdup (name);
    2138       325090 :       sl->name_len = name_len;
    2139       325090 :       sl->ptr_spec = &sl->ptr;
    2140       325090 :       sl->alloc_p = 0;
    2141       325090 :       *(sl->ptr_spec) = "";
    2142       325090 :       sl->next = specs;
    2143       325090 :       sl->default_ptr = NULL;
    2144       325090 :       specs = sl;
    2145              :     }
    2146              : 
    2147     14014397 :   old_spec = *(sl->ptr_spec);
    2148     14014397 :   *(sl->ptr_spec) = ((spec[0] == '+' && ISSPACE ((unsigned char)spec[1]))
    2149            1 :                      ? concat (old_spec, spec + 1, NULL)
    2150     14014396 :                      : xstrdup (spec));
    2151              : 
    2152              : #ifdef DEBUG_SPECS
    2153              :   if (verbose_flag)
    2154              :     fnotice (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
    2155              : #endif
    2156              : 
    2157              :   /* Free the old spec.  */
    2158     14014397 :   if (old_spec && sl->alloc_p)
    2159         6042 :     free (const_cast<char *> (old_spec));
    2160              : 
    2161     14014397 :   sl->user_p = user_p;
    2162     14014397 :   sl->alloc_p = true;
    2163     14014397 : }
    2164              : 
    2165              : /* Accumulate a command (program name and args), and run it.  */
    2166              : 
    2167              : typedef const char *const_char_p; /* For DEF_VEC_P.  */
    2168              : 
    2169              : /* Vector of pointers to arguments in the current line of specifications.  */
    2170              : static vec<const_char_p> argbuf;
    2171              : 
    2172              : /* Likewise, but for the current @file.  */
    2173              : static vec<const_char_p> at_file_argbuf;
    2174              : 
    2175              : /* Whether an @file is currently open.  */
    2176              : static bool in_at_file = false;
    2177              : 
    2178              : /* Were the options -c, -S or -E passed.  */
    2179              : static int have_c = 0;
    2180              : 
    2181              : /* Was the option -o passed.  */
    2182              : static int have_o = 0;
    2183              : 
    2184              : /* Was the option -E passed.  */
    2185              : static int have_E = 0;
    2186              : 
    2187              : /* Pointer to output file name passed in with -o. */
    2188              : static const char *output_file = 0;
    2189              : 
    2190              : /* Pointer to input file name passed in with -truncate.
    2191              :    This file should be truncated after linking. */
    2192              : static const char *totruncate_file = 0;
    2193              : 
    2194              : /* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
    2195              :    temp file.  If the HOST_BIT_BUCKET is used for %j, no entry is made for
    2196              :    it here.  */
    2197              : 
    2198              : static struct temp_name {
    2199              :   const char *suffix;   /* suffix associated with the code.  */
    2200              :   int length;           /* strlen (suffix).  */
    2201              :   int unique;           /* Indicates whether %g or %u/%U was used.  */
    2202              :   const char *filename; /* associated filename.  */
    2203              :   int filename_length;  /* strlen (filename).  */
    2204              :   struct temp_name *next;
    2205              : } *temp_names;
    2206              : 
    2207              : /* Number of commands executed so far.  */
    2208              : 
    2209              : static int execution_count;
    2210              : 
    2211              : /* Number of commands that exited with a signal.  */
    2212              : 
    2213              : static int signal_count;
    2214              : 
    2215              : /* Allocate the argument vector.  */
    2216              : 
    2217              : static void
    2218      2376479 : alloc_args (void)
    2219              : {
    2220      2376479 :   argbuf.create (10);
    2221      2376479 :   at_file_argbuf.create (10);
    2222      2376479 : }
    2223              : 
    2224              : /* Clear out the vector of arguments (after a command is executed).  */
    2225              : 
    2226              : static void
    2227      5640397 : clear_args (void)
    2228              : {
    2229      5640397 :   argbuf.truncate (0);
    2230      5640397 :   at_file_argbuf.truncate (0);
    2231      5640397 : }
    2232              : 
    2233              : /* Add one argument to the vector at the end.
    2234              :    This is done when a space is seen or at the end of the line.
    2235              :    If DELETE_ALWAYS is nonzero, the arg is a filename
    2236              :     and the file should be deleted eventually.
    2237              :    If DELETE_FAILURE is nonzero, the arg is a filename
    2238              :     and the file should be deleted if this compilation fails.  */
    2239              : 
    2240              : static void
    2241     19353401 : store_arg (const char *arg, int delete_always, int delete_failure)
    2242              : {
    2243     19353401 :   if (in_at_file)
    2244        13362 :     at_file_argbuf.safe_push (arg);
    2245              :   else
    2246     19340039 :     argbuf.safe_push (arg);
    2247              : 
    2248     19353401 :   if (delete_always || delete_failure)
    2249              :     {
    2250       518994 :       const char *p;
    2251              :       /* If the temporary file we should delete is specified as
    2252              :          part of a joined argument extract the filename.  */
    2253       518994 :       if (arg[0] == '-'
    2254       518994 :           && (p = strrchr (arg, '=')))
    2255        90533 :         arg = p + 1;
    2256       518994 :       record_temp_file (arg, delete_always, delete_failure);
    2257              :     }
    2258     19353401 : }
    2259              : 
    2260              : /* Open a temporary @file into which subsequent arguments will be stored.  */
    2261              : 
    2262              : static void
    2263        12310 : open_at_file (void)
    2264              : {
    2265        12310 :    if (in_at_file)
    2266            0 :      fatal_error (input_location, "cannot open nested response file");
    2267              :    else
    2268        12310 :      in_at_file = true;
    2269        12310 : }
    2270              : 
    2271              : /* Create a temporary @file name.  */
    2272              : 
    2273        12300 : static char *make_at_file (void)
    2274              : {
    2275        12300 :   static int fileno = 0;
    2276        12300 :   char filename[20];
    2277        12300 :   const char *base, *ext;
    2278              : 
    2279        12300 :   if (!save_temps_flag)
    2280        12262 :     return make_temp_file ("");
    2281              : 
    2282           38 :   base = dumpbase;
    2283           38 :   if (!(base && *base))
    2284           11 :     base = dumpdir;
    2285           38 :   if (!(base && *base))
    2286            0 :     base = "a";
    2287              : 
    2288           38 :   sprintf (filename, ".args.%d", fileno++);
    2289           38 :   ext = filename;
    2290              : 
    2291           38 :   if (base == dumpdir && dumpdir_trailing_dash_added)
    2292           38 :     ext++;
    2293              : 
    2294           38 :   return concat (base, ext, NULL);
    2295              : }
    2296              : 
    2297              : /* Close the temporary @file and add @file to the argument list.  */
    2298              : 
    2299              : static void
    2300        12310 : close_at_file (void)
    2301              : {
    2302        12310 :   if (!in_at_file)
    2303            0 :     fatal_error (input_location, "cannot close nonexistent response file");
    2304              : 
    2305        12310 :   in_at_file = false;
    2306              : 
    2307        12310 :   const unsigned int n_args = at_file_argbuf.length ();
    2308        12310 :   if (n_args == 0)
    2309              :     return;
    2310              : 
    2311        12300 :   char **argv = XALLOCAVEC (char *, n_args + 1);
    2312        12300 :   char *temp_file = make_at_file ();
    2313        12300 :   char *at_argument = concat ("@", temp_file, NULL);
    2314        12300 :   FILE *f = fopen (temp_file, "w");
    2315        12300 :   int status;
    2316        12300 :   unsigned int i;
    2317              : 
    2318              :   /* Copy the strings over.  */
    2319        37962 :   for (i = 0; i < n_args; i++)
    2320        13362 :     argv[i] = const_cast<char *> (at_file_argbuf[i]);
    2321        12300 :   argv[i] = NULL;
    2322              : 
    2323        12300 :   at_file_argbuf.truncate (0);
    2324              : 
    2325        12300 :   if (f == NULL)
    2326            0 :     fatal_error (input_location, "could not open temporary response file %s",
    2327              :                  temp_file);
    2328              : 
    2329        12300 :   status = writeargv (argv, f);
    2330              : 
    2331        12300 :   if (status)
    2332            0 :     fatal_error (input_location,
    2333              :                  "could not write to temporary response file %s",
    2334              :                  temp_file);
    2335              : 
    2336        12300 :   status = fclose (f);
    2337              : 
    2338        12300 :   if (status == EOF)
    2339            0 :     fatal_error (input_location, "could not close temporary response file %s",
    2340              :                  temp_file);
    2341              : 
    2342        12300 :   store_arg (at_argument, 0, 0);
    2343              : 
    2344        12300 :   record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
    2345              : }
    2346              : 
    2347              : /* Load specs from a file name named FILENAME, replacing occurrences of
    2348              :    various different types of line-endings, \r\n, \n\r and just \r, with
    2349              :    a single \n.  */
    2350              : 
    2351              : static char *
    2352       334776 : load_specs (const char *filename)
    2353              : {
    2354       334776 :   int desc;
    2355       334776 :   int readlen;
    2356       334776 :   struct stat statbuf;
    2357       334776 :   char *buffer;
    2358       334776 :   char *buffer_p;
    2359       334776 :   char *specs;
    2360       334776 :   char *specs_p;
    2361              : 
    2362       334776 :   if (verbose_flag)
    2363         1485 :     fnotice (stderr, "Reading specs from %s\n", filename);
    2364              : 
    2365              :   /* Open and stat the file.  */
    2366       334776 :   desc = open (filename, O_RDONLY, 0);
    2367       334776 :   if (desc < 0)
    2368              :     {
    2369            1 :     failed:
    2370              :       /* This leaves DESC open, but the OS will save us.  */
    2371            1 :       fatal_error (input_location, "cannot read spec file %qs: %m", filename);
    2372              :     }
    2373              : 
    2374       334775 :   if (stat (filename, &statbuf) < 0)
    2375            0 :     goto failed;
    2376              : 
    2377              :   /* Read contents of file into BUFFER.  */
    2378       334775 :   buffer = XNEWVEC (char, statbuf.st_size + 1);
    2379       334775 :   readlen = read (desc, buffer, (unsigned) statbuf.st_size);
    2380       334775 :   if (readlen < 0)
    2381            0 :     goto failed;
    2382       334775 :   buffer[readlen] = 0;
    2383       334775 :   close (desc);
    2384              : 
    2385       334775 :   specs = XNEWVEC (char, readlen + 1);
    2386       334775 :   specs_p = specs;
    2387   3052998902 :   for (buffer_p = buffer; buffer_p && *buffer_p; buffer_p++)
    2388              :     {
    2389   3052664127 :       int skip = 0;
    2390   3052664127 :       char c = *buffer_p;
    2391   3052664127 :       if (c == '\r')
    2392              :         {
    2393            0 :           if (buffer_p > buffer && *(buffer_p - 1) == '\n')  /* \n\r */
    2394              :             skip = 1;
    2395            0 :           else if (*(buffer_p + 1) == '\n')                     /* \r\n */
    2396              :             skip = 1;
    2397              :           else                                                  /* \r */
    2398              :             c = '\n';
    2399              :         }
    2400              :       if (! skip)
    2401   3052664127 :         *specs_p++ = c;
    2402              :     }
    2403       334775 :   *specs_p = '\0';
    2404              : 
    2405       334775 :   free (buffer);
    2406       334775 :   return (specs);
    2407              : }
    2408              : 
    2409              : /* Read compilation specs from a file named FILENAME,
    2410              :    replacing the default ones.
    2411              : 
    2412              :    A suffix which starts with `*' is a definition for
    2413              :    one of the machine-specific sub-specs.  The "suffix" should be
    2414              :    *asm, *cc1, *cpp, *link, *startfile, etc.
    2415              :    The corresponding spec is stored in asm_spec, etc.,
    2416              :    rather than in the `compilers' vector.
    2417              : 
    2418              :    Anything invalid in the file is a fatal error.  */
    2419              : 
    2420              : static void
    2421       334776 : read_specs (const char *filename, bool main_p, bool user_p)
    2422              : {
    2423       334776 :   char *buffer;
    2424       334776 :   char *p;
    2425              : 
    2426       334776 :   buffer = load_specs (filename);
    2427              : 
    2428              :   /* Scan BUFFER for specs, putting them in the vector.  */
    2429       334776 :   p = buffer;
    2430     14652769 :   while (1)
    2431              :     {
    2432     14652769 :       char *suffix;
    2433     14652769 :       char *spec;
    2434     14652769 :       char *in, *out, *p1, *p2, *p3;
    2435              : 
    2436              :       /* Advance P in BUFFER to the next nonblank nocomment line.  */
    2437     14652769 :       p = skip_whitespace (p);
    2438     14652769 :       if (*p == 0)
    2439              :         break;
    2440              : 
    2441              :       /* Is this a special command that starts with '%'? */
    2442              :       /* Don't allow this for the main specs file, since it would
    2443              :          encourage people to overwrite it.  */
    2444     14317994 :       if (*p == '%' && !main_p)
    2445              :         {
    2446       428000 :           p1 = p;
    2447       428000 :           while (*p && *p != '\n')
    2448       406600 :             p++;
    2449              : 
    2450              :           /* Skip '\n'.  */
    2451        21400 :           p++;
    2452              : 
    2453        21400 :           if (startswith (p1, "%include")
    2454        21400 :               && (p1[sizeof "%include" - 1] == ' '
    2455            0 :                   || p1[sizeof "%include" - 1] == '\t'))
    2456              :             {
    2457            0 :               char *new_filename;
    2458              : 
    2459            0 :               p1 += sizeof ("%include");
    2460            0 :               while (*p1 == ' ' || *p1 == '\t')
    2461            0 :                 p1++;
    2462              : 
    2463            0 :               if (*p1++ != '<' || p[-2] != '>')
    2464            0 :                 fatal_error (input_location,
    2465              :                              "specs %%include syntax malformed after "
    2466            0 :                              "%td characters", p1 - buffer + 1);
    2467              : 
    2468            0 :               p[-2] = '\0';
    2469            0 :               new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
    2470            0 :               read_specs (new_filename ? new_filename : p1, false, user_p);
    2471            0 :               continue;
    2472            0 :             }
    2473        21400 :           else if (startswith (p1, "%include_noerr")
    2474        21400 :                    && (p1[sizeof "%include_noerr" - 1] == ' '
    2475            0 :                        || p1[sizeof "%include_noerr" - 1] == '\t'))
    2476              :             {
    2477            0 :               char *new_filename;
    2478              : 
    2479            0 :               p1 += sizeof "%include_noerr";
    2480            0 :               while (*p1 == ' ' || *p1 == '\t')
    2481            0 :                 p1++;
    2482              : 
    2483            0 :               if (*p1++ != '<' || p[-2] != '>')
    2484            0 :                 fatal_error (input_location,
    2485              :                              "specs %%include syntax malformed after "
    2486            0 :                              "%td characters", p1 - buffer + 1);
    2487              : 
    2488            0 :               p[-2] = '\0';
    2489            0 :               new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
    2490            0 :               if (new_filename)
    2491            0 :                 read_specs (new_filename, false, user_p);
    2492            0 :               else if (verbose_flag)
    2493            0 :                 fnotice (stderr, "could not find specs file %s\n", p1);
    2494            0 :               continue;
    2495            0 :             }
    2496        21400 :           else if (startswith (p1, "%rename")
    2497        21400 :                    && (p1[sizeof "%rename" - 1] == ' '
    2498            0 :                        || p1[sizeof "%rename" - 1] == '\t'))
    2499              :             {
    2500        21400 :               int name_len;
    2501        21400 :               struct spec_list *sl;
    2502        21400 :               struct spec_list *newsl;
    2503              : 
    2504              :               /* Get original name.  */
    2505        21400 :               p1 += sizeof "%rename";
    2506        21400 :               while (*p1 == ' ' || *p1 == '\t')
    2507            0 :                 p1++;
    2508              : 
    2509        21400 :               if (! ISALPHA ((unsigned char) *p1))
    2510            0 :                 fatal_error (input_location,
    2511              :                              "specs %%rename syntax malformed after "
    2512              :                              "%td characters", p1 - buffer);
    2513              : 
    2514              :               p2 = p1;
    2515        85600 :               while (*p2 && !ISSPACE ((unsigned char) *p2))
    2516        64200 :                 p2++;
    2517              : 
    2518        21400 :               if (*p2 != ' ' && *p2 != '\t')
    2519            0 :                 fatal_error (input_location,
    2520              :                              "specs %%rename syntax malformed after "
    2521              :                              "%td characters", p2 - buffer);
    2522              : 
    2523        21400 :               name_len = p2 - p1;
    2524        21400 :               *p2++ = '\0';
    2525        21400 :               while (*p2 == ' ' || *p2 == '\t')
    2526            0 :                 p2++;
    2527              : 
    2528        21400 :               if (! ISALPHA ((unsigned char) *p2))
    2529            0 :                 fatal_error (input_location,
    2530              :                              "specs %%rename syntax malformed after "
    2531              :                              "%td characters", p2 - buffer);
    2532              : 
    2533              :               /* Get new spec name.  */
    2534              :               p3 = p2;
    2535       171200 :               while (*p3 && !ISSPACE ((unsigned char) *p3))
    2536       149800 :                 p3++;
    2537              : 
    2538        21400 :               if (p3 != p - 1)
    2539            0 :                 fatal_error (input_location,
    2540              :                              "specs %%rename syntax malformed after "
    2541              :                              "%td characters", p3 - buffer);
    2542        21400 :               *p3 = '\0';
    2543              : 
    2544       428000 :               for (sl = specs; sl; sl = sl->next)
    2545       428000 :                 if (name_len == sl->name_len && !strcmp (sl->name, p1))
    2546              :                   break;
    2547              : 
    2548        21400 :               if (!sl)
    2549            0 :                 fatal_error (input_location,
    2550              :                              "specs %s spec was not found to be renamed", p1);
    2551              : 
    2552        21400 :               if (strcmp (p1, p2) == 0)
    2553            0 :                 continue;
    2554              : 
    2555      1005800 :               for (newsl = specs; newsl; newsl = newsl->next)
    2556       984400 :                 if (strcmp (newsl->name, p2) == 0)
    2557            0 :                   fatal_error (input_location,
    2558              :                                "%s: attempt to rename spec %qs to "
    2559              :                                "already defined spec %qs",
    2560              :                     filename, p1, p2);
    2561              : 
    2562        21400 :               if (verbose_flag)
    2563              :                 {
    2564            0 :                   fnotice (stderr, "rename spec %s to %s\n", p1, p2);
    2565              : #ifdef DEBUG_SPECS
    2566              :                   fnotice (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
    2567              : #endif
    2568              :                 }
    2569              : 
    2570        21400 :               set_spec (p2, *(sl->ptr_spec), user_p);
    2571        21400 :               if (sl->alloc_p)
    2572        21400 :                 free (const_cast<char *> (*(sl->ptr_spec)));
    2573              : 
    2574        21400 :               *(sl->ptr_spec) = "";
    2575        21400 :               sl->alloc_p = 0;
    2576        21400 :               continue;
    2577        21400 :             }
    2578              :           else
    2579            0 :             fatal_error (input_location,
    2580              :                          "specs unknown %% command after %td characters",
    2581              :                          p1 - buffer);
    2582              :         }
    2583              : 
    2584              :       /* Find the colon that should end the suffix.  */
    2585              :       p1 = p;
    2586    196298387 :       while (*p1 && *p1 != ':' && *p1 != '\n')
    2587    182001793 :         p1++;
    2588              : 
    2589              :       /* The colon shouldn't be missing.  */
    2590     14296594 :       if (*p1 != ':')
    2591            0 :         fatal_error (input_location,
    2592              :                      "specs file malformed after %td characters",
    2593              :                      p1 - buffer);
    2594              : 
    2595              :       /* Skip back over trailing whitespace.  */
    2596              :       p2 = p1;
    2597     14296594 :       while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t'))
    2598            0 :         p2--;
    2599              : 
    2600              :       /* Copy the suffix to a string.  */
    2601     14296594 :       suffix = save_string (p, p2 - p);
    2602              :       /* Find the next line.  */
    2603     14296594 :       p = skip_whitespace (p1 + 1);
    2604     14296594 :       if (p[1] == 0)
    2605            0 :         fatal_error (input_location,
    2606              :                      "specs file malformed after %td characters",
    2607              :                      p - buffer);
    2608              : 
    2609              :       p1 = p;
    2610              :       /* Find next blank line or end of string.  */
    2611   2823653151 :       while (*p1 && !(*p1 == '\n' && (p1[1] == '\n' || p1[1] == '\0')))
    2612   2809356557 :         p1++;
    2613              : 
    2614              :       /* Specs end at the blank line and do not include the newline.  */
    2615     14296594 :       spec = save_string (p, p1 - p);
    2616     14296594 :       p = p1;
    2617              : 
    2618              :       /* Delete backslash-newline sequences from the spec.  */
    2619     14296594 :       in = spec;
    2620     14296594 :       out = spec;
    2621   2837949743 :       while (*in != 0)
    2622              :         {
    2623   2809356555 :           if (in[0] == '\\' && in[1] == '\n')
    2624            2 :             in += 2;
    2625   2809356553 :           else if (in[0] == '#')
    2626            0 :             while (*in && *in != '\n')
    2627            0 :               in++;
    2628              : 
    2629              :           else
    2630   2809356553 :             *out++ = *in++;
    2631              :         }
    2632     14296594 :       *out = 0;
    2633              : 
    2634     14296594 :       if (suffix[0] == '*')
    2635              :         {
    2636     14296594 :           if (! strcmp (suffix, "*link_command"))
    2637       303597 :             link_command_spec = spec;
    2638              :           else
    2639              :             {
    2640     13992997 :               set_spec (suffix + 1, spec, user_p);
    2641     13992997 :               free (spec);
    2642              :             }
    2643              :         }
    2644              :       else
    2645              :         {
    2646              :           /* Add this pair to the vector.  */
    2647            0 :           compilers
    2648            0 :             = XRESIZEVEC (struct compiler, compilers, n_compilers + 2);
    2649              : 
    2650            0 :           compilers[n_compilers].suffix = suffix;
    2651            0 :           compilers[n_compilers].spec = spec;
    2652            0 :           n_compilers++;
    2653            0 :           memset (&compilers[n_compilers], 0, sizeof compilers[n_compilers]);
    2654              :         }
    2655              : 
    2656     14296594 :       if (*suffix == 0)
    2657            0 :         link_command_spec = spec;
    2658              :     }
    2659              : 
    2660       334775 :   if (link_command_spec == 0)
    2661            0 :     fatal_error (input_location, "spec file has no spec for linking");
    2662              : 
    2663       334775 :   XDELETEVEC (buffer);
    2664       334775 : }
    2665              : 
    2666              : /* Record the names of temporary files we tell compilers to write,
    2667              :    and delete them at the end of the run.  */
    2668              : 
    2669              : /* This is the common prefix we use to make temp file names.
    2670              :    It is chosen once for each run of this program.
    2671              :    It is substituted into a spec by %g or %j.
    2672              :    Thus, all temp file names contain this prefix.
    2673              :    In practice, all temp file names start with this prefix.
    2674              : 
    2675              :    This prefix comes from the envvar TMPDIR if it is defined;
    2676              :    otherwise, from the P_tmpdir macro if that is defined;
    2677              :    otherwise, in /usr/tmp or /tmp;
    2678              :    or finally the current directory if all else fails.  */
    2679              : 
    2680              : static const char *temp_filename;
    2681              : 
    2682              : /* Length of the prefix.  */
    2683              : 
    2684              : static int temp_filename_length;
    2685              : 
    2686              : /* Define the list of temporary files to delete.  */
    2687              : 
    2688              : struct temp_file
    2689              : {
    2690              :   const char *name;
    2691              :   struct temp_file *next;
    2692              : };
    2693              : 
    2694              : /* Queue of files to delete on success or failure of compilation.  */
    2695              : static struct temp_file *always_delete_queue;
    2696              : /* Queue of files to delete on failure of compilation.  */
    2697              : static struct temp_file *failure_delete_queue;
    2698              : 
    2699              : /* Record FILENAME as a file to be deleted automatically.
    2700              :    ALWAYS_DELETE nonzero means delete it if all compilation succeeds;
    2701              :    otherwise delete it in any case.
    2702              :    FAIL_DELETE nonzero means delete it if a compilation step fails;
    2703              :    otherwise delete it in any case.  */
    2704              : 
    2705              : void
    2706       703365 : record_temp_file (const char *filename, int always_delete, int fail_delete)
    2707              : {
    2708       703365 :   char *const name = xstrdup (filename);
    2709              : 
    2710       703365 :   if (always_delete)
    2711              :     {
    2712       528450 :       struct temp_file *temp;
    2713       917708 :       for (temp = always_delete_queue; temp; temp = temp->next)
    2714       553705 :         if (! filename_cmp (name, temp->name))
    2715              :           {
    2716       164447 :             free (name);
    2717       164447 :             goto already1;
    2718              :           }
    2719              : 
    2720       364003 :       temp = XNEW (struct temp_file);
    2721       364003 :       temp->next = always_delete_queue;
    2722       364003 :       temp->name = name;
    2723       364003 :       always_delete_queue = temp;
    2724              : 
    2725       703365 :     already1:;
    2726              :     }
    2727              : 
    2728       703365 :   if (fail_delete)
    2729              :     {
    2730       283914 :       struct temp_file *temp;
    2731       288988 :       for (temp = failure_delete_queue; temp; temp = temp->next)
    2732         5163 :         if (! filename_cmp (name, temp->name))
    2733              :           {
    2734           89 :             free (name);
    2735           89 :             goto already2;
    2736              :           }
    2737              : 
    2738       283825 :       temp = XNEW (struct temp_file);
    2739       283825 :       temp->next = failure_delete_queue;
    2740       283825 :       temp->name = name;
    2741       283825 :       failure_delete_queue = temp;
    2742              : 
    2743       703365 :     already2:;
    2744              :     }
    2745       703365 : }
    2746              : 
    2747              : /* Delete all the temporary files whose names we previously recorded.  */
    2748              : 
    2749              : #ifndef DELETE_IF_ORDINARY
    2750              : #define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG)        \
    2751              : do                                                      \
    2752              :   {                                                     \
    2753              :     if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode))  \
    2754              :       if (unlink (NAME) < 0)                            \
    2755              :         if (VERBOSE_FLAG)                               \
    2756              :           error ("%s: %m", (NAME));                   \
    2757              :   } while (0)
    2758              : #endif
    2759              : 
    2760              : static void
    2761       387645 : delete_if_ordinary (const char *name)
    2762              : {
    2763       387645 :   struct stat st;
    2764              : #ifdef DEBUG
    2765              :   int i, c;
    2766              : 
    2767              :   printf ("Delete %s? (y or n) ", name);
    2768              :   fflush (stdout);
    2769              :   i = getchar ();
    2770              :   if (i != '\n')
    2771              :     while ((c = getchar ()) != '\n' && c != EOF)
    2772              :       ;
    2773              : 
    2774              :   if (i == 'y' || i == 'Y')
    2775              : #endif /* DEBUG */
    2776       387645 :   DELETE_IF_ORDINARY (name, st, verbose_flag);
    2777       387645 : }
    2778              : 
    2779              : static void
    2780       588205 : delete_temp_files (void)
    2781              : {
    2782       588205 :   struct temp_file *temp;
    2783              : 
    2784       952208 :   for (temp = always_delete_queue; temp; temp = temp->next)
    2785       364003 :     delete_if_ordinary (temp->name);
    2786       588205 :   always_delete_queue = 0;
    2787       588205 : }
    2788              : 
    2789              : /* Delete all the files to be deleted on error.  */
    2790              : 
    2791              : static void
    2792        58696 : delete_failure_queue (void)
    2793              : {
    2794        58696 :   struct temp_file *temp;
    2795              : 
    2796        82338 :   for (temp = failure_delete_queue; temp; temp = temp->next)
    2797        23642 :     delete_if_ordinary (temp->name);
    2798        58696 : }
    2799              : 
    2800              : static void
    2801       545949 : clear_failure_queue (void)
    2802              : {
    2803       545949 :   failure_delete_queue = 0;
    2804       545949 : }
    2805              : 
    2806              : /* Call CALLBACK for each path in PATHS, breaking out early if CALLBACK
    2807              :    returns non-NULL.
    2808              :    If DO_MULTI is true iterate over the paths twice, first with multilib
    2809              :    suffix then without, otherwise iterate over the paths once without
    2810              :    adding a multilib suffix.  When DO_MULTI is true, some attempt is made
    2811              :    to avoid visiting the same path twice, but we could do better.  For
    2812              :    instance, /usr/lib/../lib is considered different from /usr/lib.
    2813              :    At least EXTRA_SPACE chars past the end of the path passed to
    2814              :    CALLBACK are available for use by the callback.
    2815              :    CALLBACK_INFO allows extra parameters to be passed to CALLBACK.
    2816              : 
    2817              :    Returns the value returned by CALLBACK.  */
    2818              : 
    2819              : template<typename fun>
    2820              : auto *
    2821      2846284 : for_each_path (const struct path_prefix *paths,
    2822              :                bool do_multi,
    2823              :                size_t extra_space,
    2824              :                fun && callback)
    2825              : {
    2826              :   struct prefix_list *pl;
    2827      2846284 :   const char *multi_dir = NULL;
    2828      2846284 :   const char *multi_os_dir = NULL;
    2829      2846284 :   const char *multiarch_suffix = NULL;
    2830              :   const char *multi_suffix;
    2831              :   const char *just_multi_suffix;
    2832      2846284 :   char *path = NULL;
    2833      2846284 :   decltype (callback (nullptr)) ret = nullptr;
    2834      2846284 :   bool skip_multi_dir = false;
    2835      2846284 :   bool skip_multi_os_dir = false;
    2836              : 
    2837      2846284 :   multi_suffix = machine_suffix;
    2838      2846284 :   just_multi_suffix = just_machine_suffix;
    2839      2846284 :   if (do_multi && multilib_dir && strcmp (multilib_dir, ".") != 0)
    2840              :     {
    2841        15893 :       multi_dir = concat (multilib_dir, dir_separator_str, NULL);
    2842        15893 :       multi_suffix = concat (multi_suffix, multi_dir, NULL);
    2843        15893 :       just_multi_suffix = concat (just_multi_suffix, multi_dir, NULL);
    2844              :     }
    2845      1239372 :   if (do_multi && multilib_os_dir && strcmp (multilib_os_dir, ".") != 0)
    2846       934634 :     multi_os_dir = concat (multilib_os_dir, dir_separator_str, NULL);
    2847      2846284 :   if (multiarch_dir)
    2848            0 :     multiarch_suffix = concat (multiarch_dir, dir_separator_str, NULL);
    2849              : 
    2850              :   while (1)
    2851              :     {
    2852      3269732 :       size_t multi_dir_len = 0;
    2853      3269732 :       size_t multi_os_dir_len = 0;
    2854      3269732 :       size_t multiarch_len = 0;
    2855              :       size_t suffix_len;
    2856              :       size_t just_suffix_len;
    2857              :       size_t len;
    2858              : 
    2859      3269732 :       if (multi_dir)
    2860        15893 :         multi_dir_len = strlen (multi_dir);
    2861      3269732 :       if (multi_os_dir)
    2862       934634 :         multi_os_dir_len = strlen (multi_os_dir);
    2863      3269732 :       if (multiarch_suffix)
    2864            0 :         multiarch_len = strlen (multiarch_suffix);
    2865      3269732 :       suffix_len = strlen (multi_suffix);
    2866      3269732 :       just_suffix_len = strlen (just_multi_suffix);
    2867              : 
    2868      3269732 :       if (path == NULL)
    2869              :         {
    2870      2846284 :           len = paths->max_len + extra_space + 1;
    2871      2846284 :           len += MAX (MAX (suffix_len, multi_os_dir_len), multiarch_len);
    2872      2846284 :           path = XNEWVEC (char, len);
    2873              :         }
    2874              : 
    2875     12745345 :       for (pl = paths->plist; pl != 0; pl = pl->next)
    2876              :         {
    2877     11162021 :           len = strlen (pl->prefix);
    2878     11162021 :           memcpy (path, pl->prefix, len);
    2879              : 
    2880              :           /* Look first in MACHINE/VERSION subdirectory.  */
    2881     11162021 :           if (!skip_multi_dir)
    2882              :             {
    2883      8172669 :               memcpy (path + len, multi_suffix, suffix_len + 1);
    2884      8172669 :               ret = callback (path);
    2885      5278623 :               if (ret)
    2886              :                 break;
    2887              :             }
    2888              : 
    2889              :           /* Some paths are tried with just the machine (ie. target)
    2890              :              subdir.  This is used for finding as, ld, etc.  */
    2891              :           if (!skip_multi_dir
    2892      8172669 :               && pl->require_machine_suffix == 2)
    2893              :             {
    2894            0 :               memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
    2895            0 :               ret = callback (path);
    2896            0 :               if (ret)
    2897              :                 break;
    2898              :             }
    2899              : 
    2900              :           /* Now try the multiarch path.  */
    2901              :           if (!skip_multi_dir
    2902      8172669 :               && !pl->require_machine_suffix && multiarch_dir)
    2903              :             {
    2904            0 :               memcpy (path + len, multiarch_suffix, multiarch_len + 1);
    2905            0 :               ret = callback (path);
    2906            0 :               if (ret)
    2907              :                 break;
    2908              :             }
    2909              : 
    2910              :           /* Now try the base path.  */
    2911     11162021 :           if (!pl->require_machine_suffix
    2912     17769367 :               && !(pl->os_multilib ? skip_multi_os_dir : skip_multi_dir))
    2913              :             {
    2914              :               const char *this_multi;
    2915              :               size_t this_multi_len;
    2916              : 
    2917      9977360 :               if (pl->os_multilib)
    2918              :                 {
    2919              :                   this_multi = multi_os_dir;
    2920              :                   this_multi_len = multi_os_dir_len;
    2921              :                 }
    2922              :               else
    2923              :                 {
    2924      5422685 :                   this_multi = multi_dir;
    2925      5422685 :                   this_multi_len = multi_dir_len;
    2926              :                 }
    2927              : 
    2928      9977360 :               if (this_multi_len)
    2929      2770396 :                 memcpy (path + len, this_multi, this_multi_len + 1);
    2930              :               else
    2931      7206964 :                 path[len] = '\0';
    2932              : 
    2933      9977360 :               ret = callback (path);
    2934      5941117 :               if (ret)
    2935              :                 break;
    2936              :             }
    2937              :         }
    2938      2509427 :       if (pl)
    2939              :         break;
    2940              : 
    2941      1583324 :       if (multi_dir == NULL && multi_os_dir == NULL)
    2942              :         break;
    2943              : 
    2944              :       /* Run through the paths again, this time without multilibs.
    2945              :          Don't repeat any we have already seen.  */
    2946       423448 :       if (multi_dir)
    2947              :         {
    2948        10166 :           free (const_cast<char *> (multi_dir));
    2949        10166 :           multi_dir = NULL;
    2950        10166 :           free (const_cast<char *> (multi_suffix));
    2951        10166 :           multi_suffix = machine_suffix;
    2952        10166 :           free (const_cast<char *> (just_multi_suffix));
    2953        10166 :           just_multi_suffix = just_machine_suffix;
    2954              :         }
    2955              :       else
    2956              :         skip_multi_dir = true;
    2957       423448 :       if (multi_os_dir)
    2958              :         {
    2959       423448 :           free (const_cast<char *> (multi_os_dir));
    2960       423448 :           multi_os_dir = NULL;
    2961              :         }
    2962              :       else
    2963              :         skip_multi_os_dir = true;
    2964              :     }
    2965              : 
    2966      2846284 :   if (multi_dir)
    2967              :     {
    2968         5727 :       free (const_cast<char *> (multi_dir));
    2969         5727 :       free (const_cast<char *> (multi_suffix));
    2970         5727 :       free (const_cast<char *> (just_multi_suffix));
    2971              :     }
    2972      2846284 :   if (multi_os_dir)
    2973       511186 :     free (const_cast<char *> (multi_os_dir));
    2974      2339414 :   if (ret != path)
    2975      1159876 :     free (path);
    2976      2846284 :   return ret;
    2977              : }
    2978              : 
    2979              : /* Add or change the value of an environment variable, outputting the
    2980              :    change to standard error if in verbose mode.  */
    2981              : static void
    2982      1776374 : xputenv (const char *string)
    2983              : {
    2984            0 :   env.xput (string);
    2985       143505 : }
    2986              : 
    2987              : /* Build a list of search directories from PATHS.
    2988              :    PREFIX is a string to prepend to the list.
    2989              :    If CHECK_DIR_P is true we ensure the directory exists.
    2990              :    If DO_MULTI is true, multilib paths are output first, then
    2991              :    non-multilib paths.
    2992              :    This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
    2993              :    It is also used by the --print-search-dirs flag.  */
    2994              : 
    2995              : static char *
    2996       506870 : build_search_list (const struct path_prefix *paths, const char *prefix,
    2997              :                    bool check_dir, bool do_multi)
    2998              : {
    2999       506870 :   struct obstack *const ob = &collect_obstack;
    3000       506870 :   bool first_time = true;
    3001              : 
    3002       506870 :   obstack_grow (&collect_obstack, prefix, strlen (prefix));
    3003       506870 :   obstack_1grow (&collect_obstack, '=');
    3004              : 
    3005              :   /* Callback adds path to obstack being built.  */
    3006       506870 :   for_each_path (paths, do_multi, 0, [&](char *path) -> void*
    3007              :     {
    3008      6930289 :       if (check_dir && !is_directory (path))
    3009              :         return NULL;
    3010              : 
    3011      2543735 :       if (!first_time)
    3012      2037999 :         obstack_1grow (ob, PATH_SEPARATOR);
    3013              : 
    3014      2543735 :       obstack_grow (ob, path, strlen (path));
    3015              : 
    3016      2543735 :       first_time = false;
    3017      2543735 :       return NULL;
    3018              :     });
    3019              : 
    3020       506870 :   obstack_1grow (&collect_obstack, '\0');
    3021       506870 :   return XOBFINISH (&collect_obstack, char *);
    3022              : }
    3023              : 
    3024              : /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    3025              :    for collect.  */
    3026              : 
    3027              : static void
    3028       506814 : putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
    3029              :                       bool do_multi)
    3030              : {
    3031       506814 :   xputenv (build_search_list (paths, env_var, true, do_multi));
    3032       506814 : }
    3033              : 
    3034              : /* Check whether NAME can be accessed in MODE.  This is like access,
    3035              :    except that it never considers directories to be executable.  */
    3036              : 
    3037              : static int
    3038      7884696 : access_check (const char *name, int mode)
    3039              : {
    3040      7884696 :   if (mode == X_OK)
    3041              :     {
    3042      1522450 :       struct stat st;
    3043              : 
    3044      1522450 :       if (stat (name, &st) < 0
    3045      1522450 :           || S_ISDIR (st.st_mode))
    3046       774069 :         return -1;
    3047              :     }
    3048              : 
    3049      7110627 :   return access (name, mode);
    3050              : }
    3051              : 
    3052              : 
    3053              : /* Search for NAME using the prefix list PREFIXES.  MODE is passed to
    3054              :    access to check permissions.  If DO_MULTI is true, search multilib
    3055              :    paths then non-multilib paths, otherwise do not search multilib paths.
    3056              :    Return 0 if not found, otherwise return its name, allocated with malloc.  */
    3057              : 
    3058              : static char *
    3059      1787744 : find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
    3060              :              bool do_multi)
    3061              : {
    3062              :   /* Find the filename in question (special case for absolute paths).  */
    3063              : 
    3064      1787744 :   if (IS_ABSOLUTE_PATH (name))
    3065              :     {
    3066            1 :       if (access (name, mode) == 0)
    3067            1 :         return xstrdup (name);
    3068              : 
    3069              :       return NULL;
    3070              :     }
    3071              : 
    3072      1787743 :   const char *suffix = (mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "";
    3073      1787743 :   const int name_len = strlen (name);
    3074      1787743 :   const int suffix_len = strlen (suffix);
    3075              : 
    3076              : 
    3077              :   /* Callback appends the file name to the directory path.  If the
    3078              :      resulting file exists in the right mode, return the full pathname
    3079              :      to the file.  */
    3080      1787743 :   return for_each_path (pprefix, do_multi,
    3081              :                         name_len + suffix_len,
    3082      1787743 :                         [=](char *path) -> char*
    3083              :     {
    3084      7884696 :       size_t len = strlen (path);
    3085              : 
    3086      7884696 :       memcpy (path + len, name, name_len);
    3087      7884696 :       len += name_len;
    3088              : 
    3089              :       /* Some systems have a suffix for executable files.
    3090              :          So try appending that first.  */
    3091      7884696 :       if (suffix_len)
    3092              :         {
    3093            0 :           memcpy (path + len, suffix, suffix_len + 1);
    3094            0 :           if (access_check (path, mode) == 0)
    3095              :             return path;
    3096              :         }
    3097              : 
    3098      7884696 :       path[len] = '\0';
    3099      7884696 :       if (access_check (path, mode) == 0)
    3100              :         return path;
    3101              : 
    3102              :       return NULL;
    3103              :     });
    3104              : }
    3105              : 
    3106              : /* Specialization of find_a_file for programs that also takes into account
    3107              :    configure-specified default programs. */
    3108              : 
    3109              : static char*
    3110       754488 : find_a_program (const char *name)
    3111              : {
    3112              :   /* Do not search if default matches query. */
    3113              : 
    3114              : #ifdef DEFAULT_ASSEMBLER
    3115              :   if (! strcmp (name, "as") && access (DEFAULT_ASSEMBLER, X_OK) == 0)
    3116              :     return xstrdup (DEFAULT_ASSEMBLER);
    3117              : #endif
    3118              : 
    3119              : #ifdef DEFAULT_LINKER
    3120              :   if (! strcmp (name, "ld") && access (DEFAULT_LINKER, X_OK) == 0)
    3121              :     return xstrdup (DEFAULT_LINKER);
    3122              : #endif
    3123              : 
    3124              : #ifdef DEFAULT_DSYMUTIL
    3125              :   if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, X_OK) == 0)
    3126              :     return xstrdup (DEFAULT_DSYMUTIL);
    3127              : #endif
    3128              : 
    3129              : #ifdef DEFAULT_WINDRES
    3130              :   if (! strcmp (name, "windres") && access (DEFAULT_WINDRES, X_OK) == 0)
    3131              :     return xstrdup (DEFAULT_WINDRES);
    3132              : #endif
    3133              : 
    3134            0 :   return find_a_file (&exec_prefixes, name, X_OK, false);
    3135              : }
    3136              : 
    3137              : /* Ranking of prefixes in the sort list. -B prefixes are put before
    3138              :    all others.  */
    3139              : 
    3140              : enum path_prefix_priority
    3141              : {
    3142              :   PREFIX_PRIORITY_B_OPT,
    3143              :   PREFIX_PRIORITY_LAST
    3144              : };
    3145              : 
    3146              : /* Add an entry for PREFIX in PLIST.  The PLIST is kept in ascending
    3147              :    order according to PRIORITY.  Within each PRIORITY, new entries are
    3148              :    appended.
    3149              : 
    3150              :    If WARN is nonzero, we will warn if no file is found
    3151              :    through this prefix.  WARN should point to an int
    3152              :    which will be set to 1 if this entry is used.
    3153              : 
    3154              :    COMPONENT is the value to be passed to update_path.
    3155              : 
    3156              :    REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without
    3157              :    the complete value of machine_suffix.
    3158              :    2 means try both machine_suffix and just_machine_suffix.  */
    3159              : 
    3160              : static void
    3161      3942746 : add_prefix (struct path_prefix *pprefix, const char *prefix,
    3162              :             const char *component, /* enum prefix_priority */ int priority,
    3163              :             int require_machine_suffix, int os_multilib)
    3164              : {
    3165      3942746 :   struct prefix_list *pl, **prev;
    3166      3942746 :   int len;
    3167              : 
    3168      3942746 :   for (prev = &pprefix->plist;
    3169     12384550 :        (*prev) != NULL && (*prev)->priority <= priority;
    3170      8441804 :        prev = &(*prev)->next)
    3171              :     ;
    3172              : 
    3173              :   /* Keep track of the longest prefix.  */
    3174              : 
    3175      3942746 :   prefix = update_path (prefix, component);
    3176      3942746 :   len = strlen (prefix);
    3177      3942746 :   if (len > pprefix->max_len)
    3178      2146747 :     pprefix->max_len = len;
    3179              : 
    3180      3942746 :   pl = XNEW (struct prefix_list);
    3181      3942746 :   pl->prefix = prefix;
    3182      3942746 :   pl->require_machine_suffix = require_machine_suffix;
    3183      3942746 :   pl->priority = priority;
    3184      3942746 :   pl->os_multilib = os_multilib;
    3185              : 
    3186              :   /* Insert after PREV.  */
    3187      3942746 :   pl->next = (*prev);
    3188      3942746 :   (*prev) = pl;
    3189      3942746 : }
    3190              : 
    3191              : /* Same as add_prefix, but prepending target_system_root to prefix.  */
    3192              : /* The target_system_root prefix has been relocated by gcc_exec_prefix.  */
    3193              : static void
    3194       609472 : add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
    3195              :                       const char *component,
    3196              :                       /* enum prefix_priority */ int priority,
    3197              :                       int require_machine_suffix, int os_multilib)
    3198              : {
    3199       609472 :   if (!IS_ABSOLUTE_PATH (prefix))
    3200            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3201              : 
    3202       609472 :   if (target_system_root)
    3203              :     {
    3204            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3205            0 :       size_t sysroot_len = strlen (target_system_root);
    3206              : 
    3207            0 :       if (sysroot_len > 0
    3208            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3209            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3210              : 
    3211            0 :       if (target_sysroot_suffix)
    3212            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3213              :                          target_sysroot_suffix, prefix, NULL);
    3214              :       else
    3215            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3216              : 
    3217            0 :       free (sysroot_no_trailing_dir_separator);
    3218              : 
    3219              :       /* We have to override this because GCC's notion of sysroot
    3220              :          moves along with GCC.  */
    3221            0 :       component = "GCC";
    3222              :     }
    3223              : 
    3224       609472 :   add_prefix (pprefix, prefix, component, priority,
    3225              :               require_machine_suffix, os_multilib);
    3226       609472 : }
    3227              : 
    3228              : /* Same as add_prefix, but prepending target_sysroot_hdrs_suffix to prefix.  */
    3229              : 
    3230              : static void
    3231        31358 : add_sysrooted_hdrs_prefix (struct path_prefix *pprefix, const char *prefix,
    3232              :                            const char *component,
    3233              :                            /* enum prefix_priority */ int priority,
    3234              :                            int require_machine_suffix, int os_multilib)
    3235              : {
    3236        31358 :   if (!IS_ABSOLUTE_PATH (prefix))
    3237            0 :     fatal_error (input_location, "system path %qs is not absolute", prefix);
    3238              : 
    3239        31358 :   if (target_system_root)
    3240              :     {
    3241            0 :       char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
    3242            0 :       size_t sysroot_len = strlen (target_system_root);
    3243              : 
    3244            0 :       if (sysroot_len > 0
    3245            0 :           && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
    3246            0 :         sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
    3247              : 
    3248            0 :       if (target_sysroot_hdrs_suffix)
    3249            0 :         prefix = concat (sysroot_no_trailing_dir_separator,
    3250              :                          target_sysroot_hdrs_suffix, prefix, NULL);
    3251              :       else
    3252            0 :         prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
    3253              : 
    3254            0 :       free (sysroot_no_trailing_dir_separator);
    3255              : 
    3256              :       /* We have to override this because GCC's notion of sysroot
    3257              :          moves along with GCC.  */
    3258            0 :       component = "GCC";
    3259              :     }
    3260              : 
    3261        31358 :   add_prefix (pprefix, prefix, component, priority,
    3262              :               require_machine_suffix, os_multilib);
    3263        31358 : }
    3264              : 
    3265              : 
    3266              : /* Execute the command specified by the arguments on the current line of spec.
    3267              :    When using pipes, this includes several piped-together commands
    3268              :    with `|' between them.
    3269              : 
    3270              :    Return 0 if successful, -1 if failed.  */
    3271              : 
    3272              : static int
    3273       542842 : execute (void)
    3274              : {
    3275       542842 :   int i;
    3276       542842 :   int n_commands;               /* # of command.  */
    3277       542842 :   char *string;
    3278       542842 :   struct pex_obj *pex;
    3279       542842 :   struct command
    3280              :   {
    3281              :     const char *prog;           /* program name.  */
    3282              :     const char **argv;          /* vector of args.  */
    3283              :   };
    3284       542842 :   const char *arg;
    3285              : 
    3286       542842 :   struct command *commands;     /* each command buffer with above info.  */
    3287              : 
    3288       542842 :   gcc_assert (!processing_spec_function);
    3289              : 
    3290       542842 :   if (wrapper_string)
    3291              :     {
    3292            0 :       string = find_a_program (argbuf[0]);
    3293            0 :       if (string)
    3294            0 :         argbuf[0] = string;
    3295            0 :       insert_wrapper (wrapper_string);
    3296              :     }
    3297              : 
    3298              :   /* Count # of piped commands.  */
    3299     16744089 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3300     16201247 :     if (strcmp (arg, "|") == 0)
    3301            0 :       n_commands++;
    3302              : 
    3303              :   /* Get storage for each command.  */
    3304       542842 :   commands = XALLOCAVEC (struct command, n_commands);
    3305              : 
    3306              :   /* Split argbuf into its separate piped processes,
    3307              :      and record info about each one.
    3308              :      Also search for the programs that are to be run.  */
    3309              : 
    3310       542842 :   argbuf.safe_push (0);
    3311              : 
    3312       542842 :   commands[0].prog = argbuf[0]; /* first command.  */
    3313       542842 :   commands[0].argv = argbuf.address ();
    3314              : 
    3315       542842 :   if (!wrapper_string)
    3316              :     {
    3317       542842 :       string = find_a_program(commands[0].prog);
    3318       542842 :       if (string)
    3319       540207 :         commands[0].argv[0] = string;
    3320              :     }
    3321              : 
    3322     17286931 :   for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); i++)
    3323     16744089 :     if (arg && strcmp (arg, "|") == 0)
    3324              :       {                         /* each command.  */
    3325              : #if defined (__MSDOS__) || defined (OS2) || defined (VMS)
    3326              :         fatal_error (input_location, "%<-pipe%> not supported");
    3327              : #endif
    3328            0 :         argbuf[i] = 0; /* Termination of command args.  */
    3329            0 :         commands[n_commands].prog = argbuf[i + 1];
    3330            0 :         commands[n_commands].argv
    3331            0 :           = &(argbuf.address ())[i + 1];
    3332            0 :         string = find_a_program(commands[n_commands].prog);
    3333            0 :         if (string)
    3334            0 :           commands[n_commands].argv[0] = string;
    3335            0 :         n_commands++;
    3336              :       }
    3337              : 
    3338              :   /* If -v, print what we are about to do, and maybe query.  */
    3339              : 
    3340       542842 :   if (verbose_flag)
    3341              :     {
    3342              :       /* For help listings, put a blank line between sub-processes.  */
    3343         1402 :       if (print_help_list)
    3344            9 :         fputc ('\n', stderr);
    3345              : 
    3346              :       /* Print each piped command as a separate line.  */
    3347         2804 :       for (i = 0; i < n_commands; i++)
    3348              :         {
    3349         1402 :           const char *const *j;
    3350              : 
    3351         1402 :           if (verbose_only_flag)
    3352              :             {
    3353        17991 :               for (j = commands[i].argv; *j; j++)
    3354              :                 {
    3355              :                   const char *p;
    3356       429464 :                   for (p = *j; *p; ++p)
    3357       414996 :                     if (!ISALNUM ((unsigned char) *p)
    3358        98223 :                         && *p != '_' && *p != '/' && *p != '-' && *p != '.')
    3359              :                       break;
    3360        16968 :                   if (*p || !*j)
    3361              :                     {
    3362         2500 :                       fprintf (stderr, " \"");
    3363       130111 :                       for (p = *j; *p; ++p)
    3364              :                         {
    3365       127611 :                           if (*p == '"' || *p == '\\' || *p == '$')
    3366            0 :                             fputc ('\\', stderr);
    3367       127611 :                           fputc (*p, stderr);
    3368              :                         }
    3369         2500 :                       fputc ('"', stderr);
    3370              :                     }
    3371              :                   /* If it's empty, print "".  */
    3372        14468 :                   else if (!**j)
    3373            0 :                     fprintf (stderr, " \"\"");
    3374              :                   else
    3375        14468 :                     fprintf (stderr, " %s", *j);
    3376              :                 }
    3377              :             }
    3378              :           else
    3379        10225 :             for (j = commands[i].argv; *j; j++)
    3380              :               /* If it's empty, print "".  */
    3381         9846 :               if (!**j)
    3382            0 :                 fprintf (stderr, " \"\"");
    3383              :               else
    3384         9846 :                 fprintf (stderr, " %s", *j);
    3385              : 
    3386              :           /* Print a pipe symbol after all but the last command.  */
    3387         1402 :           if (i + 1 != n_commands)
    3388            0 :             fprintf (stderr, " |");
    3389         1402 :           fprintf (stderr, "\n");
    3390              :         }
    3391         1402 :       fflush (stderr);
    3392         1402 :       if (verbose_only_flag != 0)
    3393              :         {
    3394              :           /* verbose_only_flag should act as if the spec was
    3395              :              executed, so increment execution_count before
    3396              :              returning.  This prevents spurious warnings about
    3397              :              unused linker input files, etc.  */
    3398         1023 :           execution_count++;
    3399         1023 :           return 0;
    3400              :         }
    3401              : #ifdef DEBUG
    3402              :       fnotice (stderr, "\nGo ahead? (y or n) ");
    3403              :       fflush (stderr);
    3404              :       i = getchar ();
    3405              :       if (i != '\n')
    3406              :         while (getchar () != '\n')
    3407              :           ;
    3408              : 
    3409              :       if (i != 'y' && i != 'Y')
    3410              :         return 0;
    3411              : #endif /* DEBUG */
    3412              :     }
    3413              : 
    3414              : #ifdef ENABLE_VALGRIND_CHECKING
    3415              :   /* Run the each command through valgrind.  To simplify prepending the
    3416              :      path to valgrind and the option "-q" (for quiet operation unless
    3417              :      something triggers), we allocate a separate argv array.  */
    3418              : 
    3419              :   for (i = 0; i < n_commands; i++)
    3420              :     {
    3421              :       const char **argv;
    3422              :       int argc;
    3423              :       int j;
    3424              : 
    3425              :       for (argc = 0; commands[i].argv[argc] != NULL; argc++)
    3426              :         ;
    3427              : 
    3428              :       argv = XALLOCAVEC (const char *, argc + 3);
    3429              : 
    3430              :       argv[0] = VALGRIND_PATH;
    3431              :       argv[1] = "-q";
    3432              :       for (j = 2; j < argc + 2; j++)
    3433              :         argv[j] = commands[i].argv[j - 2];
    3434              :       argv[j] = NULL;
    3435              : 
    3436              :       commands[i].argv = argv;
    3437              :       commands[i].prog = argv[0];
    3438              :     }
    3439              : #endif
    3440              : 
    3441              :   /* Run each piped subprocess.  */
    3442              : 
    3443       541819 :   pex = pex_init (PEX_USE_PIPES | ((report_times || report_times_to_file)
    3444              :                                    ? PEX_RECORD_TIMES : 0),
    3445              :                   progname, temp_filename);
    3446       541819 :   if (pex == NULL)
    3447              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    3448              : 
    3449      1083638 :   for (i = 0; i < n_commands; i++)
    3450              :     {
    3451       541819 :       const char *errmsg;
    3452       541819 :       int err;
    3453       541819 :       const char *string = commands[i].argv[0];
    3454              : 
    3455       541819 :       errmsg = pex_run (pex,
    3456       541819 :                         ((i + 1 == n_commands ? PEX_LAST : 0)
    3457       541819 :                          | (string == commands[i].prog ? PEX_SEARCH : 0)),
    3458              :                         string, const_cast<char **> (commands[i].argv),
    3459              :                         NULL, NULL, &err);
    3460       541819 :       if (errmsg != NULL)
    3461              :         {
    3462            0 :           errno = err;
    3463            0 :           fatal_error (input_location,
    3464              :                        err ? G_("cannot execute %qs: %s: %m")
    3465              :                        : G_("cannot execute %qs: %s"),
    3466              :                        string, errmsg);
    3467              :         }
    3468              : 
    3469       541819 :       if (i && string != commands[i].prog)
    3470            0 :         free (const_cast<char *> (string));
    3471              :     }
    3472              : 
    3473       541819 :   execution_count++;
    3474              : 
    3475              :   /* Wait for all the subprocesses to finish.  */
    3476              : 
    3477       541819 :   {
    3478       541819 :     int *statuses;
    3479       541819 :     struct pex_time *times = NULL;
    3480       541819 :     int ret_code = 0;
    3481              : 
    3482       541819 :     statuses = XALLOCAVEC (int, n_commands);
    3483       541819 :     if (!pex_get_status (pex, n_commands, statuses))
    3484            0 :       fatal_error (input_location, "failed to get exit status: %m");
    3485              : 
    3486       541819 :     if (report_times || report_times_to_file)
    3487              :       {
    3488            0 :         times = XALLOCAVEC (struct pex_time, n_commands);
    3489            0 :         if (!pex_get_times (pex, n_commands, times))
    3490            0 :           fatal_error (input_location, "failed to get process times: %m");
    3491              :       }
    3492              : 
    3493       541819 :     pex_free (pex);
    3494              : 
    3495      1083638 :     for (i = 0; i < n_commands; ++i)
    3496              :       {
    3497       541819 :         int status = statuses[i];
    3498              : 
    3499       541819 :         if (WIFSIGNALED (status))
    3500            0 :           switch (WTERMSIG (status))
    3501              :             {
    3502            0 :             case SIGINT:
    3503            0 :             case SIGTERM:
    3504              :               /* SIGQUIT and SIGKILL are not available on MinGW.  */
    3505              : #ifdef SIGQUIT
    3506            0 :             case SIGQUIT:
    3507              : #endif
    3508              : #ifdef SIGKILL
    3509            0 :             case SIGKILL:
    3510              : #endif
    3511              :               /* The user (or environment) did something to the
    3512              :                  inferior.  Making this an ICE confuses the user into
    3513              :                  thinking there's a compiler bug.  Much more likely is
    3514              :                  the user or OOM killer nuked it.  */
    3515            0 :               fatal_error (input_location,
    3516              :                            "%s signal terminated program %s",
    3517              :                            strsignal (WTERMSIG (status)),
    3518            0 :                            commands[i].prog);
    3519            0 :               break;
    3520              : 
    3521              : #ifdef SIGPIPE
    3522            0 :             case SIGPIPE:
    3523              :               /* SIGPIPE is a special case.  It happens in -pipe mode
    3524              :                  when the compiler dies before the preprocessor is
    3525              :                  done, or the assembler dies before the compiler is
    3526              :                  done.  There's generally been an error already, and
    3527              :                  this is just fallout.  So don't generate another
    3528              :                  error unless we would otherwise have succeeded.  */
    3529            0 :               if (signal_count || greatest_status >= MIN_FATAL_STATUS)
    3530              :                 {
    3531            0 :                   signal_count++;
    3532            0 :                   ret_code = -1;
    3533            0 :                   break;
    3534              :                 }
    3535              : #endif
    3536              :               /* FALLTHROUGH */
    3537              : 
    3538            0 :             default:
    3539              :               /* The inferior failed to catch the signal.  */
    3540            0 :               internal_error_no_backtrace ("%s signal terminated program %s",
    3541              :                                            strsignal (WTERMSIG (status)),
    3542            0 :                                            commands[i].prog);
    3543              :             }
    3544       541819 :         else if (WIFEXITED (status)
    3545       541819 :                  && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
    3546              :           {
    3547              :             /* For ICEs in cc1, cc1obj, cc1plus see if it is
    3548              :                reproducible or not.  */
    3549        29399 :             const char *p;
    3550        29399 :             if (flag_report_bug
    3551            0 :                 && WEXITSTATUS (status) == ICE_EXIT_CODE
    3552            0 :                 && i == 0
    3553            0 :                 && (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
    3554        29399 :                 && startswith (p + 1, "cc1"))
    3555            0 :               try_generate_repro (commands[0].argv);
    3556        29399 :             if (WEXITSTATUS (status) > greatest_status)
    3557           22 :               greatest_status = WEXITSTATUS (status);
    3558              :             ret_code = -1;
    3559              :           }
    3560              : 
    3561       541819 :         if (report_times || report_times_to_file)
    3562              :           {
    3563            0 :             struct pex_time *pt = &times[i];
    3564            0 :             double ut, st;
    3565              : 
    3566            0 :             ut = ((double) pt->user_seconds
    3567            0 :                   + (double) pt->user_microseconds / 1.0e6);
    3568            0 :             st = ((double) pt->system_seconds
    3569            0 :                   + (double) pt->system_microseconds / 1.0e6);
    3570              : 
    3571            0 :             if (ut + st != 0)
    3572              :               {
    3573            0 :                 if (report_times)
    3574            0 :                   fnotice (stderr, "# %s %.2f %.2f\n",
    3575            0 :                            commands[i].prog, ut, st);
    3576              : 
    3577            0 :                 if (report_times_to_file)
    3578              :                   {
    3579            0 :                     int c = 0;
    3580            0 :                     const char *const *j;
    3581              : 
    3582            0 :                     fprintf (report_times_to_file, "%g %g", ut, st);
    3583              : 
    3584            0 :                     for (j = &commands[i].prog; *j; j = &commands[i].argv[++c])
    3585              :                       {
    3586              :                         const char *p;
    3587            0 :                         for (p = *j; *p; ++p)
    3588            0 :                           if (*p == '"' || *p == '\\' || *p == '$'
    3589            0 :                               || ISSPACE (*p))
    3590              :                             break;
    3591              : 
    3592            0 :                         if (*p)
    3593              :                           {
    3594            0 :                             fprintf (report_times_to_file, " \"");
    3595            0 :                             for (p = *j; *p; ++p)
    3596              :                               {
    3597            0 :                                 if (*p == '"' || *p == '\\' || *p == '$')
    3598            0 :                                   fputc ('\\', report_times_to_file);
    3599            0 :                                 fputc (*p, report_times_to_file);
    3600              :                               }
    3601            0 :                             fputc ('"', report_times_to_file);
    3602              :                           }
    3603              :                         else
    3604            0 :                           fprintf (report_times_to_file, " %s", *j);
    3605              :                       }
    3606              : 
    3607            0 :                     fputc ('\n', report_times_to_file);
    3608              :                   }
    3609              :               }
    3610              :           }
    3611              :       }
    3612              : 
    3613       541819 :    if (commands[0].argv[0] != commands[0].prog)
    3614       539184 :      free (const_cast<char *> (commands[0].argv[0]));
    3615              : 
    3616              :     return ret_code;
    3617              :   }
    3618              : }
    3619              : 
    3620              : static struct switchstr *switches;
    3621              : 
    3622              : static int n_switches;
    3623              : 
    3624              : static int n_switches_alloc;
    3625              : 
    3626              : /* Set to zero if -fcompare-debug is disabled, positive if it's
    3627              :    enabled and we're running the first compilation, negative if it's
    3628              :    enabled and we're running the second compilation.  For most of the
    3629              :    time, it's in the range -1..1, but it can be temporarily set to 2
    3630              :    or 3 to indicate that the -fcompare-debug flags didn't come from
    3631              :    the command-line, but rather from the GCC_COMPARE_DEBUG environment
    3632              :    variable, until a synthesized -fcompare-debug flag is added to the
    3633              :    command line.  */
    3634              : int compare_debug;
    3635              : 
    3636              : /* Set to nonzero if we've seen the -fcompare-debug-second flag.  */
    3637              : int compare_debug_second;
    3638              : 
    3639              : /* Set to the flags that should be passed to the second compilation in
    3640              :    a -fcompare-debug compilation.  */
    3641              : const char *compare_debug_opt;
    3642              : 
    3643              : static struct switchstr *switches_debug_check[2];
    3644              : 
    3645              : static int n_switches_debug_check[2];
    3646              : 
    3647              : static int n_switches_alloc_debug_check[2];
    3648              : 
    3649              : static char *debug_check_temp_file[2];
    3650              : 
    3651              : /* Language is one of three things:
    3652              : 
    3653              :    1) The name of a real programming language.
    3654              :    2) NULL, indicating that no one has figured out
    3655              :    what it is yet.
    3656              :    3) '*', indicating that the file should be passed
    3657              :    to the linker.  */
    3658              : struct infile
    3659              : {
    3660              :   const char *name;
    3661              :   const char *language;
    3662              :   struct compiler *incompiler;
    3663              :   bool compiled;
    3664              :   bool preprocessed;
    3665              :   bool artificial;
    3666              : };
    3667              : 
    3668              : /* Also a vector of input files specified.  */
    3669              : 
    3670              : static struct infile *infiles;
    3671              : 
    3672              : int n_infiles;
    3673              : 
    3674              : static int n_infiles_alloc;
    3675              : 
    3676              : /* True if undefined environment variables encountered during spec processing
    3677              :    are ok to ignore, typically when we're running for --help or --version.  */
    3678              : 
    3679              : static bool spec_undefvar_allowed;
    3680              : 
    3681              : /* True if multiple input files are being compiled to a single
    3682              :    assembly file.  */
    3683              : 
    3684              : static bool combine_inputs;
    3685              : 
    3686              : /* This counts the number of libraries added by lang_specific_driver, so that
    3687              :    we can tell if there were any user supplied any files or libraries.  */
    3688              : 
    3689              : static int added_libraries;
    3690              : 
    3691              : /* And a vector of corresponding output files is made up later.  */
    3692              : 
    3693              : const char **outfiles;
    3694              : 
    3695              : #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3696              : 
    3697              : /* Convert NAME to a new name if it is the standard suffix.  DO_EXE
    3698              :    is true if we should look for an executable suffix.  DO_OBJ
    3699              :    is true if we should look for an object suffix.  */
    3700              : 
    3701              : static const char *
    3702              : convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
    3703              :                   int do_obj ATTRIBUTE_UNUSED)
    3704              : {
    3705              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3706              :   int i;
    3707              : #endif
    3708              :   int len;
    3709              : 
    3710              :   if (name == NULL)
    3711              :     return NULL;
    3712              : 
    3713              :   len = strlen (name);
    3714              : 
    3715              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    3716              :   /* Convert x.o to x.obj if TARGET_OBJECT_SUFFIX is ".obj".  */
    3717              :   if (do_obj && len > 2
    3718              :       && name[len - 2] == '.'
    3719              :       && name[len - 1] == 'o')
    3720              :     {
    3721              :       obstack_grow (&obstack, name, len - 2);
    3722              :       obstack_grow0 (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    3723              :       name = XOBFINISH (&obstack, const char *);
    3724              :     }
    3725              : #endif
    3726              : 
    3727              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    3728              :   /* If there is no filetype, make it the executable suffix (which includes
    3729              :      the ".").  But don't get confused if we have just "-o".  */
    3730              :   if (! do_exe || TARGET_EXECUTABLE_SUFFIX[0] == 0 || not_actual_file_p (name))
    3731              :     return name;
    3732              : 
    3733              :   for (i = len - 1; i >= 0; i--)
    3734              :     if (IS_DIR_SEPARATOR (name[i]))
    3735              :       break;
    3736              : 
    3737              :   for (i++; i < len; i++)
    3738              :     if (name[i] == '.')
    3739              :       return name;
    3740              : 
    3741              :   obstack_grow (&obstack, name, len);
    3742              :   obstack_grow0 (&obstack, TARGET_EXECUTABLE_SUFFIX,
    3743              :                  strlen (TARGET_EXECUTABLE_SUFFIX));
    3744              :   name = XOBFINISH (&obstack, const char *);
    3745              : #endif
    3746              : 
    3747              :   return name;
    3748              : }
    3749              : #endif
    3750              : 
    3751              : /* Display the command line switches accepted by gcc.  */
    3752              : static void
    3753            4 : display_help (void)
    3754              : {
    3755            4 :   printf (_("Usage: %s [options] file...\n"), progname);
    3756            4 :   fputs (_("Options:\n"), stdout);
    3757              : 
    3758            4 :   fputs (_("  -pass-exit-codes         Exit with highest error code from a phase.\n"), stdout);
    3759            4 :   fputs (_("  --help                   Display this information.\n"), stdout);
    3760            4 :   fputs (_("  --target-help            Display target specific command line options "
    3761              :            "(including assembler and linker options).\n"), stdout);
    3762            4 :   fputs (_("  --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].\n"), stdout);
    3763            4 :   fputs (_("                           Display specific types of command line options.\n"), stdout);
    3764            4 :   if (! verbose_flag)
    3765            1 :     fputs (_("  (Use '-v --help' to display command line options of sub-processes).\n"), stdout);
    3766            4 :   fputs (_("  --version                Display compiler version information.\n"), stdout);
    3767            4 :   fputs (_("  -dumpspecs               Display all of the built in spec strings.\n"), stdout);
    3768            4 :   fputs (_("  -dumpversion             Display the version of the compiler.\n"), stdout);
    3769            4 :   fputs (_("  -dumpmachine             Display the compiler's target processor.\n"), stdout);
    3770            4 :   fputs (_("  -foffload=<targets>      Specify offloading targets.\n"), stdout);
    3771            4 :   fputs (_("  -print-search-dirs       Display the directories in the compiler's search path.\n"), stdout);
    3772            4 :   fputs (_("  -print-libgcc-file-name  Display the name of the compiler's companion library.\n"), stdout);
    3773            4 :   fputs (_("  -print-file-name=<lib>   Display the full path to library <lib>.\n"), stdout);
    3774            4 :   fputs (_("  -print-prog-name=<prog>  Display the full path to compiler component <prog>.\n"), stdout);
    3775            4 :   fputs (_("\
    3776              :   -print-multiarch         Display the target's normalized GNU triplet, used as\n\
    3777              :                            a component in the library path.\n"), stdout);
    3778            4 :   fputs (_("  -print-multi-directory   Display the root directory for versions of libgcc.\n"), stdout);
    3779            4 :   fputs (_("\
    3780              :   -print-multi-lib         Display the mapping between command line options and\n\
    3781              :                            multiple library search directories.\n"), stdout);
    3782            4 :   fputs (_("  -print-multi-os-directory Display the relative path to OS libraries.\n"), stdout);
    3783            4 :   fputs (_("  -print-sysroot           Display the target libraries directory.\n"), stdout);
    3784            4 :   fputs (_("  -print-sysroot-headers-suffix Display the sysroot suffix used to find headers.\n"), stdout);
    3785            4 :   fputs (_("  -Wa,<options>            Pass comma-separated <options> on to the assembler.\n"), stdout);
    3786            4 :   fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor.\n"), stdout);
    3787            4 :   fputs (_("  -Wl,<options>            Pass comma-separated <options> on to the linker.\n"), stdout);
    3788            4 :   fputs (_("  -Xassembler <arg>        Pass <arg> on to the assembler.\n"), stdout);
    3789            4 :   fputs (_("  -Xpreprocessor <arg>     Pass <arg> on to the preprocessor.\n"), stdout);
    3790            4 :   fputs (_("  -Xlinker <arg>           Pass <arg> on to the linker.\n"), stdout);
    3791            4 :   fputs (_("  -save-temps              Do not delete intermediate files.\n"), stdout);
    3792            4 :   fputs (_("  -save-temps=<arg>        Do not delete intermediate files.\n"), stdout);
    3793            4 :   fputs (_("\
    3794              :   -no-canonical-prefixes   Do not canonicalize paths when building relative\n\
    3795              :                            prefixes to other gcc components.\n"), stdout);
    3796            4 :   fputs (_("  -pipe                    Use pipes rather than intermediate files.\n"), stdout);
    3797            4 :   fputs (_("  -time                    Time the execution of each subprocess.\n"), stdout);
    3798            4 :   fputs (_("  -specs=<file>            Override built-in specs with the contents of <file>.\n"), stdout);
    3799            4 :   fputs (_("  -std=<standard>          Assume that the input sources are for <standard>.\n"), stdout);
    3800            4 :   fputs (_("\
    3801              :   --sysroot=<directory>    Use <directory> as the root directory for headers\n\
    3802              :                            and libraries.\n"), stdout);
    3803            4 :   fputs (_("  -B <directory>           Add <directory> to the compiler's search paths.\n"), stdout);
    3804            4 :   fputs (_("  -v                       Display the programs invoked by the compiler.\n"), stdout);
    3805            4 :   fputs (_("  -###                     Like -v but options quoted and commands not executed.\n"), stdout);
    3806            4 :   fputs (_("  -E                       Preprocess only; do not compile, assemble or link.\n"), stdout);
    3807            4 :   fputs (_("  -S                       Compile only; do not assemble or link.\n"), stdout);
    3808            4 :   fputs (_("  -c                       Compile and assemble, but do not link.\n"), stdout);
    3809            4 :   fputs (_("  -o <file>                Place the output into <file>.\n"), stdout);
    3810            4 :   fputs (_("  -pie                     Create a dynamically linked position independent\n\
    3811              :                            executable.\n"), stdout);
    3812            4 :   fputs (_("  -shared                  Create a shared library.\n"), stdout);
    3813            4 :   fputs (_("\
    3814              :   -x <language>            Specify the language of the following input files.\n\
    3815              :                            Permissible languages include: c c++ assembler none\n\
    3816              :                            'none' means revert to the default behavior of\n\
    3817              :                            guessing the language based on the file's extension.\n\
    3818              : "), stdout);
    3819              : 
    3820            4 :   printf (_("\
    3821              : \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
    3822              :  passed on to the various sub-processes invoked by %s.  In order to pass\n\
    3823              :  other options on to these processes the -W<letter> options must be used.\n\
    3824              : "), progname);
    3825              : 
    3826              :   /* The rest of the options are displayed by invocations of the various
    3827              :      sub-processes.  */
    3828            4 : }
    3829              : 
    3830              : static void
    3831            0 : add_preprocessor_option (const char *option, int len)
    3832              : {
    3833            0 :   preprocessor_options.safe_push (save_string (option, len));
    3834            0 : }
    3835              : 
    3836              : static void
    3837          195 : add_assembler_option (const char *option, int len)
    3838              : {
    3839          195 :   assembler_options.safe_push (save_string (option, len));
    3840          195 : }
    3841              : 
    3842              : static void
    3843           82 : add_linker_option (const char *option, int len)
    3844              : {
    3845           82 :   linker_options.safe_push (save_string (option, len));
    3846           82 : }
    3847              : 
    3848              : /* Allocate space for an input file in infiles.  */
    3849              : 
    3850              : static void
    3851       911396 : alloc_infile (void)
    3852              : {
    3853       911396 :   if (n_infiles_alloc == 0)
    3854              :     {
    3855       304737 :       n_infiles_alloc = 16;
    3856       304737 :       infiles = XNEWVEC (struct infile, n_infiles_alloc);
    3857              :     }
    3858       606659 :   else if (n_infiles_alloc == n_infiles)
    3859              :     {
    3860          247 :       n_infiles_alloc *= 2;
    3861          247 :       infiles = XRESIZEVEC (struct infile, infiles, n_infiles_alloc);
    3862              :     }
    3863       911396 : }
    3864              : 
    3865              : /* Store an input file with the given NAME and LANGUAGE in
    3866              :    infiles.  */
    3867              : 
    3868              : static void
    3869       606660 : add_infile (const char *name, const char *language, bool art = false)
    3870              : {
    3871       606660 :   alloc_infile ();
    3872       606660 :   infiles[n_infiles].name = name;
    3873       606660 :   infiles[n_infiles].artificial = art;
    3874       606660 :   infiles[n_infiles++].language = language;
    3875       606660 : }
    3876              : 
    3877              : /* Allocate space for a switch in switches.  */
    3878              : 
    3879              : static void
    3880      7716446 : alloc_switch (void)
    3881              : {
    3882      7716446 :   if (n_switches_alloc == 0)
    3883              :     {
    3884       305051 :       n_switches_alloc = 16;
    3885       305051 :       switches = XNEWVEC (struct switchstr, n_switches_alloc);
    3886              :     }
    3887      7411395 :   else if (n_switches_alloc == n_switches)
    3888              :     {
    3889       272951 :       n_switches_alloc *= 2;
    3890       272951 :       switches = XRESIZEVEC (struct switchstr, switches, n_switches_alloc);
    3891              :     }
    3892      7716446 : }
    3893              : 
    3894              : /* Save an option OPT with N_ARGS arguments in array ARGS, marking it
    3895              :    as validated if VALIDATED and KNOWN if it is an internal switch.  */
    3896              : 
    3897              : static void
    3898      6831525 : save_switch (const char *opt, size_t n_args, const char *const *args,
    3899              :              bool validated, bool known)
    3900              : {
    3901      6831525 :   alloc_switch ();
    3902      6831525 :   switches[n_switches].part1 = opt + 1;
    3903      6831525 :   if (n_args == 0)
    3904      5291684 :     switches[n_switches].args = 0;
    3905              :   else
    3906              :     {
    3907      1539841 :       switches[n_switches].args = XNEWVEC (const char *, n_args + 1);
    3908      1539841 :       memcpy (switches[n_switches].args, args, n_args * sizeof (const char *));
    3909      1539841 :       switches[n_switches].args[n_args] = NULL;
    3910              :     }
    3911              : 
    3912      6831525 :   switches[n_switches].live_cond = 0;
    3913      6831525 :   switches[n_switches].validated = validated;
    3914      6831525 :   switches[n_switches].known = known;
    3915      6831525 :   switches[n_switches].ordering = 0;
    3916      6831525 :   n_switches++;
    3917      6831525 : }
    3918              : 
    3919              : /* Set the SOURCE_DATE_EPOCH environment variable to the current time if it is
    3920              :    not set already.  */
    3921              : 
    3922              : static void
    3923          619 : set_source_date_epoch_envvar ()
    3924              : {
    3925              :   /* Array size is 21 = ceil(log_10(2^64)) + 1 to hold string representations
    3926              :      of 64 bit integers.  */
    3927          619 :   char source_date_epoch[21];
    3928          619 :   time_t tt;
    3929              : 
    3930          619 :   errno = 0;
    3931          619 :   tt = time (NULL);
    3932          619 :   if (tt < (time_t) 0 || errno != 0)
    3933            0 :     tt = (time_t) 0;
    3934              : 
    3935          619 :   snprintf (source_date_epoch, 21, "%llu", (unsigned long long) tt);
    3936              :   /* Using setenv instead of xputenv because we want the variable to remain
    3937              :      after finalizing so that it's still set in the second run when using
    3938              :      -fcompare-debug.  */
    3939          619 :   setenv ("SOURCE_DATE_EPOCH", source_date_epoch, 0);
    3940          619 : }
    3941              : 
    3942              : /* Handle an option DECODED that is unknown to the option-processing
    3943              :    machinery.  */
    3944              : 
    3945              : static bool
    3946          692 : driver_unknown_option_callback (const struct cl_decoded_option *decoded)
    3947              : {
    3948          692 :   const char *opt = decoded->arg;
    3949          692 :   if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
    3950           93 :       && !(decoded->errors & CL_ERR_NEGATIVE))
    3951              :     {
    3952              :       /* Leave unknown -Wno-* options for the compiler proper, to be
    3953              :          diagnosed only if there are warnings.  */
    3954           91 :       save_switch (decoded->canonical_option[0],
    3955           91 :                    decoded->canonical_option_num_elements - 1,
    3956              :                    &decoded->canonical_option[1], false, true);
    3957           91 :       return false;
    3958              :     }
    3959          601 :   if (decoded->opt_index == OPT_SPECIAL_unknown)
    3960              :     {
    3961              :       /* Give it a chance to define it a spec file.  */
    3962          601 :       save_switch (decoded->canonical_option[0],
    3963          601 :                    decoded->canonical_option_num_elements - 1,
    3964              :                    &decoded->canonical_option[1], false, false);
    3965          601 :       return false;
    3966              :     }
    3967              :   else
    3968              :     return true;
    3969              : }
    3970              : 
    3971              : /* Handle an option DECODED that is not marked as CL_DRIVER.
    3972              :    LANG_MASK will always be CL_DRIVER.  */
    3973              : 
    3974              : static void
    3975      4421510 : driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
    3976              :                             unsigned int lang_mask ATTRIBUTE_UNUSED)
    3977              : {
    3978              :   /* At this point, non-driver options are accepted (and expected to
    3979              :      be passed down by specs) unless marked to be rejected by the
    3980              :      driver.  Options to be rejected by the driver but accepted by the
    3981              :      compilers proper are treated just like completely unknown
    3982              :      options.  */
    3983      4421510 :   const struct cl_option *option = &cl_options[decoded->opt_index];
    3984              : 
    3985      4421510 :   if (option->cl_reject_driver)
    3986            0 :     error ("unrecognized command-line option %qs",
    3987            0 :            decoded->orig_option_with_args_text);
    3988              :   else
    3989      4421510 :     save_switch (decoded->canonical_option[0],
    3990      4421510 :                  decoded->canonical_option_num_elements - 1,
    3991              :                  &decoded->canonical_option[1], false, true);
    3992      4421510 : }
    3993              : 
    3994              : static const char *spec_lang = 0;
    3995              : static int last_language_n_infiles;
    3996              : 
    3997              : 
    3998              : /* Check that GCC is configured to support the offload target.  */
    3999              : 
    4000              : static bool
    4001          125 : check_offload_target_name (const char *target, ptrdiff_t len)
    4002              : {
    4003          125 :   const char *n, *c = OFFLOAD_TARGETS;
    4004          250 :   while (c)
    4005              :     {
    4006          125 :       n = strchr (c, ',');
    4007          125 :       if (n == NULL)
    4008          125 :         n = strchr (c, '\0');
    4009          125 :       if (len == n - c && strncmp (target, c, n - c) == 0)
    4010              :         break;
    4011          125 :       c = *n ? n + 1 : NULL;
    4012              :     }
    4013          125 :   if (!c)
    4014              :     {
    4015          125 :       auto_vec<const char*> candidates;
    4016          125 :       size_t olen = strlen (OFFLOAD_TARGETS) + 1;
    4017          125 :       char *cand = XALLOCAVEC (char, olen);
    4018          125 :       memcpy (cand, OFFLOAD_TARGETS, olen);
    4019          125 :       for (c = strtok (cand, ","); c; c = strtok (NULL, ","))
    4020            0 :         candidates.safe_push (c);
    4021          125 :       candidates.safe_push ("default");
    4022          125 :       candidates.safe_push ("disable");
    4023              : 
    4024          125 :       char *target2 = XALLOCAVEC (char, len + 1);
    4025          125 :       memcpy (target2, target, len);
    4026          125 :       target2[len] = '\0';
    4027              : 
    4028          125 :       error ("GCC is not configured to support %qs as %<-foffload=%> argument",
    4029              :              target2);
    4030              : 
    4031          125 :       char *s;
    4032          125 :       const char *hint = candidates_list_and_hint (target2, s, candidates);
    4033          125 :       if (hint)
    4034            0 :         inform (UNKNOWN_LOCATION,
    4035              :                 "valid %<-foffload=%> arguments are: %s; "
    4036              :                 "did you mean %qs?", s, hint);
    4037              :       else
    4038          125 :         inform (UNKNOWN_LOCATION, "valid %<-foffload=%> arguments are: %s", s);
    4039          125 :       XDELETEVEC (s);
    4040          125 :       return false;
    4041          125 :     }
    4042              :   return true;
    4043              : }
    4044              : 
    4045              : /* Sanity check for -foffload-options.  */
    4046              : 
    4047              : static void
    4048           27 : check_foffload_target_names (const char *arg)
    4049              : {
    4050           27 :   const char *cur, *next, *end;
    4051              :   /* If option argument starts with '-' then no target is specified and we
    4052              :      do not need to parse it.  */
    4053           27 :   if (arg[0] == '-')
    4054              :     return;
    4055            0 :   end = strchr (arg, '=');
    4056            0 :   if (end == NULL)
    4057              :     {
    4058            0 :       error ("%<=%>options missing after %<-foffload-options=%>target");
    4059            0 :       return;
    4060              :     }
    4061              : 
    4062              :   cur = arg;
    4063            0 :   while (cur < end)
    4064              :     {
    4065            0 :       next = strchr (cur, ',');
    4066            0 :       if (next == NULL)
    4067            0 :         next = end;
    4068            0 :       next = (next > end) ? end : next;
    4069              : 
    4070              :       /* Retain non-supported targets after printing an error as those will not
    4071              :          be processed; each enabled target only processes its triplet.  */
    4072            0 :       check_offload_target_name (cur, next - cur);
    4073            0 :       cur = next + 1;
    4074              :    }
    4075              : }
    4076              : 
    4077              : /* Parse -foffload option argument.  */
    4078              : 
    4079              : static void
    4080         2858 : handle_foffload_option (const char *arg)
    4081              : {
    4082         2858 :   const char *c, *cur, *n, *next, *end;
    4083         2858 :   char *target;
    4084              : 
    4085              :   /* If option argument starts with '-' then no target is specified and we
    4086              :      do not need to parse it.  */
    4087         2858 :   if (arg[0] == '-')
    4088              :     return;
    4089              : 
    4090         2019 :   end = strchr (arg, '=');
    4091         2019 :   if (end == NULL)
    4092         2019 :     end = strchr (arg, '\0');
    4093         2019 :   cur = arg;
    4094              : 
    4095         2019 :   while (cur < end)
    4096              :     {
    4097         2019 :       next = strchr (cur, ',');
    4098         2019 :       if (next == NULL)
    4099         2019 :         next = end;
    4100         2019 :       next = (next > end) ? end : next;
    4101              : 
    4102         2019 :       target = XNEWVEC (char, next - cur + 1);
    4103         2019 :       memcpy (target, cur, next - cur);
    4104         2019 :       target[next - cur] = '\0';
    4105              : 
    4106              :       /* Reset offloading list and continue.  */
    4107         2019 :       if (strcmp (target, "default") == 0)
    4108              :         {
    4109            0 :           free (offload_targets);
    4110            0 :           offload_targets = NULL;
    4111            0 :           goto next_item;
    4112              :         }
    4113              : 
    4114              :       /* If 'disable' is passed to the option, clean the list of
    4115              :          offload targets and return, even if more targets follow.
    4116              :          Likewise if GCC is not configured to support that offload target.  */
    4117         2019 :       if (strcmp (target, "disable") == 0
    4118         2019 :           || !check_offload_target_name (target, next - cur))
    4119              :         {
    4120         2019 :           free (offload_targets);
    4121         2019 :           offload_targets = xstrdup ("");
    4122         2019 :           return;
    4123              :         }
    4124              : 
    4125            0 :       if (!offload_targets)
    4126              :         {
    4127            0 :           offload_targets = target;
    4128            0 :           target = NULL;
    4129              :         }
    4130              :       else
    4131              :         {
    4132              :           /* Check that the target hasn't already presented in the list.  */
    4133              :           c = offload_targets;
    4134            0 :           do
    4135              :             {
    4136            0 :               n = strchr (c, ':');
    4137            0 :               if (n == NULL)
    4138            0 :                 n = strchr (c, '\0');
    4139              : 
    4140            0 :               if (next - cur == n - c && strncmp (c, target, n - c) == 0)
    4141              :                 break;
    4142              : 
    4143            0 :               c = n + 1;
    4144              :             }
    4145            0 :           while (*n);
    4146              : 
    4147              :           /* If duplicate is not found, append the target to the list.  */
    4148            0 :           if (c > n)
    4149              :             {
    4150            0 :               size_t offload_targets_len = strlen (offload_targets);
    4151            0 :               offload_targets
    4152            0 :                 = XRESIZEVEC (char, offload_targets,
    4153              :                               offload_targets_len + 1 + next - cur + 1);
    4154            0 :               offload_targets[offload_targets_len++] = ':';
    4155            0 :               memcpy (offload_targets + offload_targets_len, target, next - cur + 1);
    4156              :             }
    4157              :         }
    4158            0 : next_item:
    4159            0 :       cur = next + 1;
    4160            0 :       XDELETEVEC (target);
    4161              :     }
    4162              : }
    4163              : 
    4164              : /* Forward certain options to offloading compilation.  */
    4165              : 
    4166              : static void
    4167            0 : forward_offload_option (size_t opt_index, const char *arg, bool validated)
    4168              : {
    4169            0 :   switch (opt_index)
    4170              :     {
    4171            0 :     case OPT_l:
    4172              :       /* Use a '_GCC_' prefix and standard name ('-l_GCC_m' irrespective of the
    4173              :          host's 'MATH_LIBRARY', for example), so that the 'mkoffload's can tell
    4174              :          this has been synthesized here, and translate/drop as necessary.  */
    4175              :       /* Note that certain libraries ('-lc', '-lgcc', '-lgomp', for example)
    4176              :          are injected by default in offloading compilation, and therefore not
    4177              :          forwarded here.  */
    4178              :       /* GCC libraries.  */
    4179            0 :       if (/* '-lgfortran' */ strcmp (arg, "gfortran") == 0
    4180            0 :           || /* '-lstdc++' */ strcmp (arg, "stdc++") == 0)
    4181            0 :         save_switch (concat ("-foffload-options=-l_GCC_", arg, NULL),
    4182              :                      0, NULL, validated, true);
    4183              :       /* Other libraries.  */
    4184              :       else
    4185              :         {
    4186              :           /* The case will need special consideration where on the host
    4187              :              '!need_math', but for offloading compilation still need
    4188              :              '-foffload-options=-l_GCC_m'.  The problem is that we don't get
    4189              :              here anything like '-lm', because it's not synthesized in
    4190              :              'gcc/fortran/gfortranspec.cc:lang_specific_driver', for example.
    4191              :              Generally synthesizing '-foffload-options=-l_GCC_m' etc. in the
    4192              :              language specific drivers is non-trivial, needs very careful
    4193              :              review of their options handling.  However, this issue is not
    4194              :              actually relevant for the current set of supported host/offloading
    4195              :              configurations.  */
    4196            0 :           int need_math = (MATH_LIBRARY[0] != '\0');
    4197            0 :           if (/* '-lm' */ (need_math && strcmp (arg, MATH_LIBRARY) == 0))
    4198            0 :             save_switch ("-foffload-options=-l_GCC_m",
    4199              :                          0, NULL, validated, true);
    4200              :         }
    4201            0 :       break;
    4202            0 :     default:
    4203            0 :       gcc_unreachable ();
    4204              :     }
    4205            0 : }
    4206              : 
    4207              : /* Handle a driver option; arguments and return value as for
    4208              :    handle_option.  */
    4209              : 
    4210              : static bool
    4211      2772549 : driver_handle_option (struct gcc_options *opts,
    4212              :                       struct gcc_options *opts_set,
    4213              :                       const struct cl_decoded_option *decoded,
    4214              :                       unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
    4215              :                       location_t loc,
    4216              :                       const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
    4217              :                       diagnostics::context *dc,
    4218              :                       void (*) (void))
    4219              : {
    4220      2772549 :   size_t opt_index = decoded->opt_index;
    4221      2772549 :   const char *arg = decoded->arg;
    4222      2772549 :   const char *compare_debug_replacement_opt;
    4223      2772549 :   int value = decoded->value;
    4224      2772549 :   bool validated = false;
    4225      2772549 :   bool do_save = true;
    4226              : 
    4227      2772549 :   gcc_assert (opts == &global_options);
    4228      2772549 :   gcc_assert (opts_set == &global_options_set);
    4229      2772549 :   gcc_assert (static_cast<diagnostics::kind> (kind)
    4230              :               == diagnostics::kind::unspecified);
    4231      2772549 :   gcc_assert (loc == UNKNOWN_LOCATION);
    4232      2772549 :   gcc_assert (dc == global_dc);
    4233              : 
    4234      2772549 :   switch (opt_index)
    4235              :     {
    4236            1 :     case OPT_dumpspecs:
    4237            1 :       {
    4238            1 :         struct spec_list *sl;
    4239            1 :         init_spec ();
    4240           47 :         for (sl = specs; sl; sl = sl->next)
    4241           46 :           printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
    4242            1 :         if (link_command_spec)
    4243            1 :           printf ("*link_command:\n%s\n\n", link_command_spec);
    4244            1 :         exit (0);
    4245              :       }
    4246              : 
    4247          280 :     case OPT_dumpversion:
    4248          280 :       printf ("%s\n", spec_version);
    4249          280 :       exit (0);
    4250              : 
    4251            0 :     case OPT_dumpmachine:
    4252            0 :       printf ("%s\n", spec_machine);
    4253            0 :       exit (0);
    4254              : 
    4255            0 :     case OPT_dumpfullversion:
    4256            0 :       printf ("%s\n", BASEVER);
    4257            0 :       exit (0);
    4258              : 
    4259           78 :     case OPT__version:
    4260           78 :       print_version = 1;
    4261              : 
    4262              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4263           78 :       if (is_cpp_driver)
    4264            0 :         add_preprocessor_option ("--version", strlen ("--version"));
    4265           78 :       add_assembler_option ("--version", strlen ("--version"));
    4266           78 :       add_linker_option ("--version", strlen ("--version"));
    4267           78 :       break;
    4268              : 
    4269            5 :     case OPT__completion_:
    4270            5 :       validated = true;
    4271            5 :       completion = decoded->arg;
    4272            5 :       break;
    4273              : 
    4274            4 :     case OPT__help:
    4275            4 :       print_help_list = 1;
    4276              : 
    4277              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4278            4 :       if (is_cpp_driver)
    4279            0 :         add_preprocessor_option ("--help", 6);
    4280            4 :       add_assembler_option ("--help", 6);
    4281            4 :       add_linker_option ("--help", 6);
    4282            4 :       break;
    4283              : 
    4284           66 :     case OPT__help_:
    4285           66 :       print_subprocess_help = 2;
    4286           66 :       break;
    4287              : 
    4288            0 :     case OPT__target_help:
    4289            0 :       print_subprocess_help = 1;
    4290              : 
    4291              :       /* CPP driver cannot obtain switch from cc1_options.  */
    4292            0 :       if (is_cpp_driver)
    4293            0 :         add_preprocessor_option ("--target-help", 13);
    4294            0 :       add_assembler_option ("--target-help", 13);
    4295            0 :       add_linker_option ("--target-help", 13);
    4296            0 :       break;
    4297              : 
    4298              :     case OPT__no_sysroot_suffix:
    4299              :     case OPT_pass_exit_codes:
    4300              :     case OPT_print_search_dirs:
    4301              :     case OPT_print_autofdo_gcov_version:
    4302              :     case OPT_print_file_name_:
    4303              :     case OPT_print_prog_name_:
    4304              :     case OPT_print_multi_lib:
    4305              :     case OPT_print_multi_directory:
    4306              :     case OPT_print_sysroot:
    4307              :     case OPT_print_multi_os_directory:
    4308              :     case OPT_print_multiarch:
    4309              :     case OPT_print_sysroot_headers_suffix:
    4310              :     case OPT_time:
    4311              :     case OPT_wrapper:
    4312              :       /* These options set the variables specified in common.opt
    4313              :          automatically, and do not need to be saved for spec
    4314              :          processing.  */
    4315              :       do_save = false;
    4316              :       break;
    4317              : 
    4318          392 :     case OPT_print_libgcc_file_name:
    4319          392 :       print_file_name = "libgcc.a";
    4320          392 :       do_save = false;
    4321          392 :       break;
    4322              : 
    4323            0 :     case OPT_fuse_ld_bfd:
    4324            0 :        use_ld = ".bfd";
    4325            0 :        break;
    4326              : 
    4327            0 :     case OPT_fuse_ld_gold:
    4328            0 :        use_ld = ".gold";
    4329            0 :        break;
    4330              : 
    4331            0 :     case OPT_fuse_ld_mold:
    4332            0 :        use_ld = ".mold";
    4333            0 :        break;
    4334              : 
    4335            0 :     case OPT_fuse_ld_wild:
    4336            0 :        use_ld = ".wild";
    4337            0 :        break;
    4338              : 
    4339            0 :     case OPT_fcompare_debug_second:
    4340            0 :       compare_debug_second = 1;
    4341            0 :       break;
    4342              : 
    4343          613 :     case OPT_fcompare_debug:
    4344          613 :       switch (value)
    4345              :         {
    4346            0 :         case 0:
    4347            0 :           compare_debug_replacement_opt = "-fcompare-debug=";
    4348            0 :           arg = "";
    4349            0 :           goto compare_debug_with_arg;
    4350              : 
    4351          613 :         case 1:
    4352          613 :           compare_debug_replacement_opt = "-fcompare-debug=-gtoggle";
    4353          613 :           arg = "-gtoggle";
    4354          613 :           goto compare_debug_with_arg;
    4355              : 
    4356            0 :         default:
    4357            0 :           gcc_unreachable ();
    4358              :         }
    4359            6 :       break;
    4360              : 
    4361            6 :     case OPT_fcompare_debug_:
    4362            6 :       compare_debug_replacement_opt = decoded->canonical_option[0];
    4363          619 :     compare_debug_with_arg:
    4364          619 :       gcc_assert (decoded->canonical_option_num_elements == 1);
    4365          619 :       gcc_assert (arg != NULL);
    4366          619 :       if (*arg)
    4367          619 :         compare_debug = 1;
    4368              :       else
    4369            0 :         compare_debug = -1;
    4370          619 :       if (compare_debug < 0)
    4371            0 :         compare_debug_opt = NULL;
    4372              :       else
    4373          619 :         compare_debug_opt = arg;
    4374          619 :       save_switch (compare_debug_replacement_opt, 0, NULL, validated, true);
    4375          619 :       set_source_date_epoch_envvar ();
    4376          619 :       return true;
    4377              : 
    4378       273039 :     case OPT_fdiagnostics_color_:
    4379       273039 :       diagnostic_color_init (dc, value);
    4380       273039 :       break;
    4381              : 
    4382       263757 :     case OPT_fdiagnostics_urls_:
    4383       263757 :       diagnostic_urls_init (dc, value);
    4384       263757 :       break;
    4385              : 
    4386            0 :     case OPT_fdiagnostics_show_highlight_colors:
    4387            0 :       dc->set_show_highlight_colors (value);
    4388            0 :       break;
    4389              : 
    4390            0 :     case OPT_fdiagnostics_format_:
    4391            0 :         {
    4392            0 :           const char *basename = get_diagnostic_file_output_basename (*opts);
    4393            0 :           gcc_assert (dc);
    4394            0 :           diagnostics::output_format_init (*dc,
    4395              :                                            opts->x_main_input_filename, basename,
    4396              :                                            (enum diagnostics_output_format)value,
    4397            0 :                                            opts->x_flag_diagnostics_json_formatting);
    4398            0 :           break;
    4399              :         }
    4400              : 
    4401            0 :     case OPT_fdiagnostics_add_output_:
    4402            0 :       handle_OPT_fdiagnostics_add_output_ (*opts, *dc, arg, loc);
    4403            0 :       break;
    4404              : 
    4405            0 :     case OPT_fdiagnostics_set_output_:
    4406            0 :       handle_OPT_fdiagnostics_set_output_ (*opts, *dc, arg, loc);
    4407            0 :       break;
    4408              : 
    4409       292774 :     case OPT_fdiagnostics_text_art_charset_:
    4410       292774 :       dc->set_text_art_charset ((enum diagnostic_text_art_charset)value);
    4411       292774 :       break;
    4412              : 
    4413              :     case OPT_Wa_:
    4414              :       {
    4415              :         int prev, j;
    4416              :         /* Pass the rest of this option to the assembler.  */
    4417              : 
    4418              :         /* Split the argument at commas.  */
    4419              :         prev = 0;
    4420          634 :         for (j = 0; arg[j]; j++)
    4421          586 :           if (arg[j] == ',')
    4422              :             {
    4423            0 :               add_assembler_option (arg + prev, j - prev);
    4424            0 :               prev = j + 1;
    4425              :             }
    4426              : 
    4427              :         /* Record the part after the last comma.  */
    4428           48 :         add_assembler_option (arg + prev, j - prev);
    4429              :       }
    4430           48 :       do_save = false;
    4431           48 :       break;
    4432              : 
    4433              :     case OPT_Wp_:
    4434              :       {
    4435              :         int prev, j;
    4436              :         /* Pass the rest of this option to the preprocessor.  */
    4437              : 
    4438              :         /* Split the argument at commas.  */
    4439              :         prev = 0;
    4440            0 :         for (j = 0; arg[j]; j++)
    4441            0 :           if (arg[j] == ',')
    4442              :             {
    4443            0 :               add_preprocessor_option (arg + prev, j - prev);
    4444            0 :               prev = j + 1;
    4445              :             }
    4446              : 
    4447              :         /* Record the part after the last comma.  */
    4448            0 :         add_preprocessor_option (arg + prev, j - prev);
    4449              :       }
    4450            0 :       do_save = false;
    4451            0 :       break;
    4452              : 
    4453              :     case OPT_Wl_:
    4454              :       {
    4455              :         int prev, j;
    4456              :         /* Split the argument at commas.  */
    4457              :         prev = 0;
    4458       124749 :         for (j = 0; arg[j]; j++)
    4459       117288 :           if (arg[j] == ',')
    4460              :             {
    4461           54 :               add_infile (save_string (arg + prev, j - prev), "*");
    4462           54 :               prev = j + 1;
    4463              :             }
    4464              :         /* Record the part after the last comma.  */
    4465         7461 :         add_infile (arg + prev, "*");
    4466         7461 :         if (strcmp (arg, "-z,lazy") == 0 || strcmp (arg, "-z,norelro") == 0)
    4467           12 :           avoid_linker_hardening_p = true;
    4468              :       }
    4469              :       do_save = false;
    4470              :       break;
    4471              : 
    4472           12 :     case OPT_z:
    4473           12 :       if (strcmp (arg, "lazy") == 0 || strcmp (arg, "norelro") == 0)
    4474           12 :         avoid_linker_hardening_p = true;
    4475              :       break;
    4476              : 
    4477            0 :     case OPT_Xlinker:
    4478            0 :       add_infile (arg, "*");
    4479            0 :       do_save = false;
    4480            0 :       break;
    4481              : 
    4482            0 :     case OPT_Xpreprocessor:
    4483            0 :       add_preprocessor_option (arg, strlen (arg));
    4484            0 :       do_save = false;
    4485            0 :       break;
    4486              : 
    4487           65 :     case OPT_Xassembler:
    4488           65 :       add_assembler_option (arg, strlen (arg));
    4489           65 :       do_save = false;
    4490           65 :       break;
    4491              : 
    4492       275858 :     case OPT_l:
    4493              :       /* POSIX allows separation of -l and the lib arg; canonicalize
    4494              :          by concatenating -l with its arg */
    4495       275858 :       add_infile (concat ("-l", arg, NULL), "*");
    4496              : 
    4497              :       /* Forward to offloading compilation '-l[...]' flags for standard,
    4498              :          well-known libraries.  */
    4499              :       /* Doing this processing here means that we don't get to see libraries
    4500              :          injected via specs, such as '-lquadmath' injected via
    4501              :          '[build]/[target]/libgfortran/libgfortran.spec'.  However, this issue
    4502              :          is not actually relevant for the current set of host/offloading
    4503              :          configurations.  */
    4504       275858 :       if (ENABLE_OFFLOADING)
    4505              :         forward_offload_option (opt_index, arg, validated);
    4506              : 
    4507       275858 :       do_save = false;
    4508       275858 :       break;
    4509              : 
    4510       272478 :     case OPT_L:
    4511              :       /* Similarly, canonicalize -L for linkers that may not accept
    4512              :          separate arguments.  */
    4513       272478 :       save_switch (concat ("-L", arg, NULL), 0, NULL, validated, true);
    4514       272478 :       return true;
    4515              : 
    4516            0 :     case OPT_F:
    4517              :       /* Likewise -F.  */
    4518            0 :       save_switch (concat ("-F", arg, NULL), 0, NULL, validated, true);
    4519            0 :       return true;
    4520              : 
    4521          408 :     case OPT_save_temps:
    4522          408 :       if (!save_temps_flag)
    4523          402 :         save_temps_flag = SAVE_TEMPS_DUMP;
    4524              :       validated = true;
    4525              :       break;
    4526              : 
    4527           58 :     case OPT_save_temps_:
    4528           58 :       if (strcmp (arg, "cwd") == 0)
    4529           29 :         save_temps_flag = SAVE_TEMPS_CWD;
    4530           29 :       else if (strcmp (arg, "obj") == 0
    4531            0 :                || strcmp (arg, "object") == 0)
    4532           29 :         save_temps_flag = SAVE_TEMPS_OBJ;
    4533              :       else
    4534            0 :         fatal_error (input_location, "%qs is an unknown %<-save-temps%> option",
    4535            0 :                      decoded->orig_option_with_args_text);
    4536           58 :       save_temps_overrides_dumpdir = true;
    4537           58 :       break;
    4538              : 
    4539        20565 :     case OPT_dumpdir:
    4540        20565 :       free (dumpdir);
    4541        20565 :       dumpdir = xstrdup (arg);
    4542        20565 :       save_temps_overrides_dumpdir = false;
    4543        20565 :       break;
    4544              : 
    4545        22001 :     case OPT_dumpbase:
    4546        22001 :       free (dumpbase);
    4547        22001 :       dumpbase = xstrdup (arg);
    4548        22001 :       break;
    4549              : 
    4550          252 :     case OPT_dumpbase_ext:
    4551          252 :       free (dumpbase_ext);
    4552          252 :       dumpbase_ext = xstrdup (arg);
    4553          252 :       break;
    4554              : 
    4555              :     case OPT_no_canonical_prefixes:
    4556              :       /* Already handled as a special case, so ignored here.  */
    4557              :       do_save = false;
    4558              :       break;
    4559              : 
    4560              :     case OPT_pipe:
    4561              :       validated = true;
    4562              :       /* These options set the variables specified in common.opt
    4563              :          automatically, but do need to be saved for spec
    4564              :          processing.  */
    4565              :       break;
    4566              : 
    4567            3 :     case OPT_specs_:
    4568            3 :       {
    4569            3 :         struct user_specs *user = XNEW (struct user_specs);
    4570              : 
    4571            3 :         user->next = (struct user_specs *) 0;
    4572            3 :         user->filename = arg;
    4573            3 :         if (user_specs_tail)
    4574            0 :           user_specs_tail->next = user;
    4575              :         else
    4576            3 :           user_specs_head = user;
    4577            3 :         user_specs_tail = user;
    4578              :       }
    4579            3 :       validated = true;
    4580            3 :       break;
    4581              : 
    4582            0 :     case OPT__sysroot_:
    4583            0 :       target_system_root = arg;
    4584            0 :       target_system_root_changed = 1;
    4585              :       /* Saving this option is useful to let self-specs decide to
    4586              :          provide a default one.  */
    4587            0 :       do_save = true;
    4588            0 :       validated = true;
    4589            0 :       break;
    4590              : 
    4591            0 :     case OPT_time_:
    4592            0 :       if (report_times_to_file)
    4593            0 :         fclose (report_times_to_file);
    4594            0 :       report_times_to_file = fopen (arg, "a");
    4595            0 :       do_save = false;
    4596            0 :       break;
    4597              : 
    4598         8111 :     case OPT_truncate:
    4599         8111 :       totruncate_file = arg;
    4600         8111 :       do_save = false;
    4601         8111 :       break;
    4602              : 
    4603          641 :     case OPT____:
    4604              :       /* "-###"
    4605              :          This is similar to -v except that there is no execution
    4606              :          of the commands and the echoed arguments are quoted.  It
    4607              :          is intended for use in shell scripts to capture the
    4608              :          driver-generated command line.  */
    4609          641 :       verbose_only_flag++;
    4610          641 :       verbose_flag = 1;
    4611          641 :       do_save = false;
    4612          641 :       break;
    4613              : 
    4614       496568 :     case OPT_B:
    4615       496568 :       {
    4616       496568 :         size_t len = strlen (arg);
    4617              : 
    4618              :         /* Catch the case where the user has forgotten to append a
    4619              :            directory separator to the path.  Note, they may be using
    4620              :            -B to add an executable name prefix, eg "i386-elf-", in
    4621              :            order to distinguish between multiple installations of
    4622              :            GCC in the same directory.  Hence we must check to see
    4623              :            if appending a directory separator actually makes a
    4624              :            valid directory name.  */
    4625       496568 :         if (!IS_DIR_SEPARATOR (arg[len - 1])
    4626       496568 :             && is_directory (arg))
    4627              :           {
    4628       101457 :             char *tmp = XNEWVEC (char, len + 2);
    4629       101457 :             strcpy (tmp, arg);
    4630       101457 :             tmp[len] = DIR_SEPARATOR;
    4631       101457 :             tmp[++len] = 0;
    4632       101457 :             arg = tmp;
    4633              :           }
    4634              : 
    4635       496568 :         add_prefix (&exec_prefixes, arg, NULL,
    4636              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4637       496568 :         add_prefix (&startfile_prefixes, arg, NULL,
    4638              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4639       496568 :         add_prefix (&include_prefixes, arg, NULL,
    4640              :                     PREFIX_PRIORITY_B_OPT, 0, 0);
    4641              :       }
    4642       496568 :       validated = true;
    4643       496568 :       break;
    4644              : 
    4645         2450 :     case OPT_E:
    4646         2450 :       have_E = true;
    4647         2450 :       break;
    4648              : 
    4649        49979 :     case OPT_x:
    4650        49979 :       spec_lang = arg;
    4651        49979 :       if (!strcmp (spec_lang, "none"))
    4652              :         /* Suppress the warning if -xnone comes after the last input
    4653              :            file, because alternate command interfaces like g++ might
    4654              :            find it useful to place -xnone after each input file.  */
    4655        13958 :         spec_lang = 0;
    4656              :       else
    4657        36021 :         last_language_n_infiles = n_infiles;
    4658              :       do_save = false;
    4659              :       break;
    4660              : 
    4661       272139 :     case OPT_o:
    4662       272139 :       have_o = 1;
    4663              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
    4664              :       arg = convert_filename (arg, ! have_c, 0);
    4665              : #endif
    4666       272139 :       output_file = arg;
    4667              :       /* On some systems, ld cannot handle "-o" without a space.  So
    4668              :          split the option from its argument.  */
    4669       272139 :       save_switch ("-o", 1, &arg, validated, true);
    4670       272139 :       return true;
    4671              : 
    4672         2130 :     case OPT_pie:
    4673              : #ifdef ENABLE_DEFAULT_PIE
    4674              :       /* -pie is turned on by default.  */
    4675              :       validated = true;
    4676              : #endif
    4677              :       /* FALLTHROUGH */
    4678         2130 :     case OPT_r:
    4679         2130 :     case OPT_shared:
    4680         2130 :     case OPT_no_pie:
    4681         2130 :       avoid_linker_hardening_p = true;
    4682         2130 :       break;
    4683              : 
    4684          100 :     case OPT_static:
    4685          100 :       static_p = true;
    4686          100 :       break;
    4687              : 
    4688              :     case OPT_static_libgcc:
    4689              :     case OPT_shared_libgcc:
    4690              :     case OPT_static_libgfortran:
    4691              :     case OPT_static_libquadmath:
    4692              :     case OPT_static_libphobos:
    4693              :     case OPT_static_libga68:
    4694              :     case OPT_static_libgm2:
    4695              :     case OPT_static_libstdc__:
    4696              :       /* These are always valid; gcc.cc itself understands the first two
    4697              :          gfortranspec.cc understands -static-libgfortran,
    4698              :          libgfortran.spec handles -static-libquadmath,
    4699              :          a68spec.cc understands -static-libga68,
    4700              :          d-spec.cc understands -static-libphobos,
    4701              :          gm2spec.cc understands -static-libgm2,
    4702              :          and g++spec.cc understands -static-libstdc++.  */
    4703              :       validated = true;
    4704              :       break;
    4705              : 
    4706           78 :     case OPT_fwpa:
    4707           78 :       flag_wpa = "";
    4708           78 :       break;
    4709              : 
    4710           27 :     case OPT_foffload_options_:
    4711           27 :       check_foffload_target_names (arg);
    4712           27 :       break;
    4713              : 
    4714         2858 :     case OPT_foffload_:
    4715         2858 :       handle_foffload_option (arg);
    4716         2858 :       if (arg[0] == '-' || NULL != strchr (arg, '='))
    4717          839 :         save_switch (concat ("-foffload-options=", arg, NULL),
    4718              :                      0, NULL, validated, true);
    4719              :       do_save = false;
    4720              :       break;
    4721              : 
    4722            0 :     case OPT_gcodeview:
    4723            0 :       add_infile ("--pdb=", "*");
    4724            0 :       break;
    4725              : 
    4726              :     default:
    4727              :       /* Various driver options need no special processing at this
    4728              :          point, having been handled in a prescan above or being
    4729              :          handled by specs.  */
    4730              :       break;
    4731              :     }
    4732              : 
    4733      1659082 :   if (do_save)
    4734      1861943 :     save_switch (decoded->canonical_option[0],
    4735      1861943 :                  decoded->canonical_option_num_elements - 1,
    4736              :                  &decoded->canonical_option[1], validated, true);
    4737              :   return true;
    4738              : }
    4739              : 
    4740              : /* Return true if F2 is F1 followed by a single suffix, i.e., by a
    4741              :    period and additional characters other than a period.  */
    4742              : 
    4743              : static inline bool
    4744        86505 : adds_single_suffix_p (const char *f2, const char *f1)
    4745              : {
    4746        86505 :   size_t len = strlen (f1);
    4747              : 
    4748        86505 :   return (strncmp (f1, f2, len) == 0
    4749        76488 :           && f2[len] == '.'
    4750       162522 :           && strchr (f2 + len + 1, '.') == NULL);
    4751              : }
    4752              : 
    4753              : /* Put the driver's standard set of option handlers in *HANDLERS.  */
    4754              : 
    4755              : static void
    4756       885203 : set_option_handlers (struct cl_option_handlers *handlers)
    4757              : {
    4758       885203 :   handlers->unknown_option_callback = driver_unknown_option_callback;
    4759       885203 :   handlers->wrong_lang_callback = driver_wrong_lang_callback;
    4760       885203 :   handlers->num_handlers = 3;
    4761       885203 :   handlers->handlers[0].handler = driver_handle_option;
    4762       885203 :   handlers->handlers[0].mask = CL_DRIVER;
    4763       885203 :   handlers->handlers[1].handler = common_handle_option;
    4764       885203 :   handlers->handlers[1].mask = CL_COMMON;
    4765       885203 :   handlers->handlers[2].handler = target_handle_option;
    4766       885203 :   handlers->handlers[2].mask = CL_TARGET;
    4767            0 : }
    4768              : 
    4769              : 
    4770              : /* Return the index into infiles for the single non-library
    4771              :    non-lto-wpa input file, -1 if there isn't any, or -2 if there is
    4772              :    more than one.  */
    4773              : static inline int
    4774       155649 : single_input_file_index ()
    4775              : {
    4776       155649 :   int ret = -1;
    4777              : 
    4778       513936 :   for (int i = 0; i < n_infiles; i++)
    4779              :     {
    4780       370447 :       if (infiles[i].language
    4781       263663 :           && (infiles[i].language[0] == '*'
    4782        46019 :               || (flag_wpa
    4783        17092 :                   && strcmp (infiles[i].language, "lto") == 0)))
    4784       234736 :         continue;
    4785              : 
    4786       135711 :       if (ret != -1)
    4787              :         return -2;
    4788              : 
    4789              :       ret = i;
    4790              :     }
    4791              : 
    4792              :   return ret;
    4793              : }
    4794              : 
    4795              : /* Create the vector `switches' and its contents.
    4796              :    Store its length in `n_switches'.  */
    4797              : 
    4798              : static void
    4799       305022 : process_command (unsigned int decoded_options_count,
    4800              :                  struct cl_decoded_option *decoded_options)
    4801              : {
    4802       305022 :   const char *temp;
    4803       305022 :   char *temp1;
    4804       305022 :   char *tooldir_prefix, *tooldir_prefix2;
    4805       305022 :   char *(*get_relative_prefix) (const char *, const char *,
    4806              :                                 const char *) = NULL;
    4807       305022 :   struct cl_option_handlers handlers;
    4808       305022 :   unsigned int j;
    4809              : 
    4810       305022 :   gcc_exec_prefix = env.get ("GCC_EXEC_PREFIX");
    4811              : 
    4812       305022 :   n_switches = 0;
    4813       305022 :   n_infiles = 0;
    4814       305022 :   added_libraries = 0;
    4815              : 
    4816              :   /* Figure compiler version from version string.  */
    4817              : 
    4818       305022 :   compiler_version = temp1 = xstrdup (version_string);
    4819              : 
    4820      2135154 :   for (; *temp1; ++temp1)
    4821              :     {
    4822      2135154 :       if (*temp1 == ' ')
    4823              :         {
    4824       305022 :           *temp1 = '\0';
    4825       305022 :           break;
    4826              :         }
    4827              :     }
    4828              : 
    4829              :   /* Handle any -no-canonical-prefixes flag early, to assign the function
    4830              :      that builds relative prefixes.  This function creates default search
    4831              :      paths that are needed later in normal option handling.  */
    4832              : 
    4833      6820129 :   for (j = 1; j < decoded_options_count; j++)
    4834              :     {
    4835      6515107 :       if (decoded_options[j].opt_index == OPT_no_canonical_prefixes)
    4836              :         {
    4837              :           get_relative_prefix = make_relative_prefix_ignore_links;
    4838              :           break;
    4839              :         }
    4840              :     }
    4841       305022 :   if (! get_relative_prefix)
    4842       305022 :     get_relative_prefix = make_relative_prefix;
    4843              : 
    4844              :   /* Set up the default search paths.  If there is no GCC_EXEC_PREFIX,
    4845              :      see if we can create it from the pathname specified in
    4846              :      decoded_options[0].arg.  */
    4847              : 
    4848       305022 :   gcc_libexec_prefix = standard_libexec_prefix;
    4849              : #ifndef VMS
    4850              :   /* FIXME: make_relative_prefix doesn't yet work for VMS.  */
    4851       305022 :   if (!gcc_exec_prefix)
    4852              :     {
    4853        29376 :       gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg,
    4854              :                                              standard_bindir_prefix,
    4855              :                                              standard_exec_prefix);
    4856        29376 :       gcc_libexec_prefix = get_relative_prefix (decoded_options[0].arg,
    4857              :                                              standard_bindir_prefix,
    4858              :                                              standard_libexec_prefix);
    4859        29376 :       if (gcc_exec_prefix)
    4860        29376 :         xputenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
    4861              :     }
    4862              :   else
    4863              :     {
    4864              :       /* make_relative_prefix requires a program name, but
    4865              :          GCC_EXEC_PREFIX is typically a directory name with a trailing
    4866              :          / (which is ignored by make_relative_prefix), so append a
    4867              :          program name.  */
    4868       275646 :       char *tmp_prefix = concat (gcc_exec_prefix, "gcc", NULL);
    4869       275646 :       gcc_libexec_prefix = get_relative_prefix (tmp_prefix,
    4870              :                                                 standard_exec_prefix,
    4871              :                                                 standard_libexec_prefix);
    4872              : 
    4873              :       /* The path is unrelocated, so fallback to the original setting.  */
    4874       275646 :       if (!gcc_libexec_prefix)
    4875       275301 :         gcc_libexec_prefix = standard_libexec_prefix;
    4876              : 
    4877       275646 :       free (tmp_prefix);
    4878              :     }
    4879              : #else
    4880              : #endif
    4881              :   /* From this point onward, gcc_exec_prefix is non-null if the toolchain
    4882              :      is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX
    4883              :      or an automatically created GCC_EXEC_PREFIX from
    4884              :      decoded_options[0].arg.  */
    4885              : 
    4886              :   /* Do language-specific adjustment/addition of flags.  */
    4887       305022 :   lang_specific_driver (&decoded_options, &decoded_options_count,
    4888              :                         &added_libraries);
    4889              : 
    4890       305018 :   if (gcc_exec_prefix)
    4891              :     {
    4892       305018 :       int len = strlen (gcc_exec_prefix);
    4893              : 
    4894       305018 :       if (len > (int) sizeof ("/lib/gcc/") - 1
    4895       305018 :           && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
    4896              :         {
    4897       305018 :           temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
    4898       305018 :           if (IS_DIR_SEPARATOR (*temp)
    4899       305018 :               && filename_ncmp (temp + 1, "lib", 3) == 0
    4900       305018 :               && IS_DIR_SEPARATOR (temp[4])
    4901       610036 :               && filename_ncmp (temp + 5, "gcc", 3) == 0)
    4902       305018 :             len -= sizeof ("/lib/gcc/") - 1;
    4903              :         }
    4904              : 
    4905       305018 :       set_std_prefix (gcc_exec_prefix, len);
    4906       305018 :       add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
    4907              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4908       305018 :       add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
    4909              :                   PREFIX_PRIORITY_LAST, 0, 0);
    4910              :     }
    4911              : 
    4912              :   /* COMPILER_PATH and LIBRARY_PATH have values
    4913              :      that are lists of directory names with colons.  */
    4914              : 
    4915       305018 :   temp = env.get ("COMPILER_PATH");
    4916       305018 :   if (temp)
    4917              :     {
    4918        20401 :       const char *startp, *endp;
    4919        20401 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4920              : 
    4921        20401 :       startp = endp = temp;
    4922      1942463 :       while (1)
    4923              :         {
    4924      1942463 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4925              :             {
    4926        34061 :               strncpy (nstore, startp, endp - startp);
    4927        34061 :               if (endp == startp)
    4928            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4929        34061 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4930              :                 {
    4931            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4932            0 :                   nstore[endp - startp + 1] = 0;
    4933              :                 }
    4934              :               else
    4935        34061 :                 nstore[endp - startp] = 0;
    4936        34061 :               add_prefix (&exec_prefixes, nstore, 0,
    4937              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4938        34061 :               add_prefix (&include_prefixes, nstore, 0,
    4939              :                           PREFIX_PRIORITY_LAST, 0, 0);
    4940        34061 :               if (*endp == 0)
    4941              :                 break;
    4942        13660 :               endp = startp = endp + 1;
    4943              :             }
    4944              :           else
    4945      1908402 :             endp++;
    4946              :         }
    4947              :     }
    4948              : 
    4949       305018 :   temp = env.get (LIBRARY_PATH_ENV);
    4950       305018 :   if (temp && *cross_compile == '0')
    4951              :     {
    4952        21754 :       const char *startp, *endp;
    4953        21754 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4954              : 
    4955        21754 :       startp = endp = temp;
    4956      3843708 :       while (1)
    4957              :         {
    4958      3843708 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4959              :             {
    4960       157130 :               strncpy (nstore, startp, endp - startp);
    4961       157130 :               if (endp == startp)
    4962            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4963       157130 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4964              :                 {
    4965         1353 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4966         1353 :                   nstore[endp - startp + 1] = 0;
    4967              :                 }
    4968              :               else
    4969       155777 :                 nstore[endp - startp] = 0;
    4970       157130 :               add_prefix (&startfile_prefixes, nstore, NULL,
    4971              :                           PREFIX_PRIORITY_LAST, 0, 1);
    4972       157130 :               if (*endp == 0)
    4973              :                 break;
    4974       135376 :               endp = startp = endp + 1;
    4975              :             }
    4976              :           else
    4977      3686578 :             endp++;
    4978              :         }
    4979              :     }
    4980              : 
    4981              :   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
    4982       305018 :   temp = env.get ("LPATH");
    4983       305018 :   if (temp && *cross_compile == '0')
    4984              :     {
    4985            0 :       const char *startp, *endp;
    4986            0 :       char *nstore = (char *) alloca (strlen (temp) + 3);
    4987              : 
    4988            0 :       startp = endp = temp;
    4989            0 :       while (1)
    4990              :         {
    4991            0 :           if (*endp == PATH_SEPARATOR || *endp == 0)
    4992              :             {
    4993            0 :               strncpy (nstore, startp, endp - startp);
    4994            0 :               if (endp == startp)
    4995            0 :                 strcpy (nstore, concat (".", dir_separator_str, NULL));
    4996            0 :               else if (!IS_DIR_SEPARATOR (endp[-1]))
    4997              :                 {
    4998            0 :                   nstore[endp - startp] = DIR_SEPARATOR;
    4999            0 :                   nstore[endp - startp + 1] = 0;
    5000              :                 }
    5001              :               else
    5002            0 :                 nstore[endp - startp] = 0;
    5003            0 :               add_prefix (&startfile_prefixes, nstore, NULL,
    5004              :                           PREFIX_PRIORITY_LAST, 0, 1);
    5005            0 :               if (*endp == 0)
    5006              :                 break;
    5007            0 :               endp = startp = endp + 1;
    5008              :             }
    5009              :           else
    5010            0 :             endp++;
    5011              :         }
    5012              :     }
    5013              : 
    5014              :   /* Process the options and store input files and switches in their
    5015              :      vectors.  */
    5016              : 
    5017       305018 :   last_language_n_infiles = -1;
    5018              : 
    5019       305018 :   set_option_handlers (&handlers);
    5020              : 
    5021      5912821 :   for (j = 1; j < decoded_options_count; j++)
    5022              :     {
    5023      5796141 :       switch (decoded_options[j].opt_index)
    5024              :         {
    5025       188338 :         case OPT_S:
    5026       188338 :         case OPT_c:
    5027       188338 :         case OPT_E:
    5028       188338 :           have_c = 1;
    5029       188338 :           break;
    5030              :         }
    5031      5796141 :       if (have_c)
    5032              :         break;
    5033              :     }
    5034              : 
    5035      7241054 :   for (j = 1; j < decoded_options_count; j++)
    5036              :     {
    5037      6936317 :       if (decoded_options[j].opt_index == OPT_SPECIAL_input_file)
    5038              :         {
    5039       322941 :           const char *arg = decoded_options[j].arg;
    5040              : 
    5041              : #ifdef HAVE_TARGET_OBJECT_SUFFIX
    5042              :           arg = convert_filename (arg, 0, access (arg, F_OK));
    5043              : #endif
    5044       322941 :           add_infile (arg, spec_lang,
    5045       322941 :                       decoded_options[j].mask == CL_DRIVER);
    5046              : 
    5047       322941 :           continue;
    5048       322941 :         }
    5049              : 
    5050      6613376 :       read_cmdline_option (&global_options, &global_options_set,
    5051              :                            decoded_options + j, UNKNOWN_LOCATION,
    5052              :                            CL_DRIVER, &handlers, global_dc);
    5053              :     }
    5054              : 
    5055              :   /* If the user didn't specify any, default to all configured offload
    5056              :      targets.  */
    5057       304737 :   if (ENABLE_OFFLOADING && offload_targets == NULL)
    5058              :     {
    5059              :       handle_foffload_option (OFFLOAD_TARGETS);
    5060              : #if OFFLOAD_DEFAULTED
    5061              :       offload_targets_default = true;
    5062              : #endif
    5063              :     }
    5064              : 
    5065              :   /* TODO: check if -static -pie works and maybe use it.  */
    5066       304737 :   if (flag_hardened)
    5067              :     {
    5068           91 :       if (!avoid_linker_hardening_p && !static_p)
    5069              :         {
    5070              : #if defined HAVE_LD_PIE && defined LD_PIE_SPEC
    5071           67 :           save_switch (LD_PIE_SPEC, 0, NULL, /*validated=*/true, /*known=*/false);
    5072              : #endif
    5073              :           /* These are passed straight down to collect2 so we have to break
    5074              :              it up like this.  */
    5075           67 :           if (HAVE_LD_NOW_SUPPORT)
    5076              :             {
    5077           67 :               add_infile ("-z", "*");
    5078           67 :               add_infile ("now", "*");
    5079              :             }
    5080           67 :           if (HAVE_LD_RELRO_SUPPORT)
    5081              :             {
    5082           67 :               add_infile ("-z", "*");
    5083           67 :               add_infile ("relro", "*");
    5084              :             }
    5085              :         }
    5086              :       /* We can't use OPT_Whardened yet.  Sigh.  */
    5087              :       else
    5088           24 :         warning_at (UNKNOWN_LOCATION, 0,
    5089              :                     "linker hardening options not enabled by %<-fhardened%> "
    5090              :                     "because other link options were specified on the command "
    5091              :                     "line");
    5092              :     }
    5093              : 
    5094              :   /* Handle -gtoggle as it would later in toplev.cc:process_options to
    5095              :      make the debug-level-gt spec function work as expected.  */
    5096       304737 :   if (flag_gtoggle)
    5097              :     {
    5098            4 :       if (debug_info_level == DINFO_LEVEL_NONE)
    5099            0 :         debug_info_level = DINFO_LEVEL_NORMAL;
    5100              :       else
    5101            4 :         debug_info_level = DINFO_LEVEL_NONE;
    5102              :     }
    5103              : 
    5104       304737 :   if (output_file
    5105       272138 :       && strcmp (output_file, "-") != 0
    5106       271975 :       && strcmp (output_file, HOST_BIT_BUCKET) != 0)
    5107              :     {
    5108              :       int i;
    5109       810225 :       for (i = 0; i < n_infiles; i++)
    5110       263403 :         if ((!infiles[i].language || infiles[i].language[0] != '*')
    5111       567271 :             && canonical_filename_eq (infiles[i].name, output_file))
    5112            1 :           fatal_error (input_location,
    5113              :                        "input file %qs is the same as output file",
    5114              :                        output_file);
    5115              :     }
    5116              : 
    5117       304736 :   if (output_file != NULL && output_file[0] == '\0')
    5118            0 :     fatal_error (input_location, "output filename may not be empty");
    5119              : 
    5120              :   /* -dumpdir and -save-temps=* both specify the location of aux/dump
    5121              :      outputs; the one that appears last prevails.  When compiling
    5122              :      multiple sources, an explicit dumpbase (minus -ext) may be
    5123              :      combined with an explicit or implicit dumpdir, whereas when
    5124              :      linking, a specified or implied link output name (minus
    5125              :      extension) may be combined with a prevailing -save-temps=* or an
    5126              :      otherwise implied dumpdir, but not override a prevailing
    5127              :      -dumpdir.  Primary outputs (e.g., linker output when linking
    5128              :      without -o, or .i, .s or .o outputs when processing multiple
    5129              :      inputs with -E, -S or -c, respectively) are NOT affected by these
    5130              :      -save-temps=/-dump* options, always landing in the current
    5131              :      directory and with the same basename as the input when an output
    5132              :      name is not given, but when they're intermediate outputs, they
    5133              :      are named like other aux outputs, so the options affect their
    5134              :      location and name.
    5135              : 
    5136              :      Here are some examples.  There are several more in the
    5137              :      documentation of -o and -dump*, and some quite exhaustive tests
    5138              :      in gcc.misc-tests/outputs.exp.
    5139              : 
    5140              :      When compiling any number of sources, no -dump* nor
    5141              :      -save-temps=*, all outputs in cwd without prefix:
    5142              : 
    5143              :      # gcc -c b.c -gsplit-dwarf
    5144              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5145              : 
    5146              :      # gcc -c b.c d.c -gsplit-dwarf
    5147              :      -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
    5148              :      && cc1 [-dumpdir ./] -dumpbase d.c -dumpbase-ext .c # d.o d.dwo
    5149              : 
    5150              :      When compiling and linking, no -dump* nor -save-temps=*, .o
    5151              :      outputs are temporary, aux outputs land in the dir of the output,
    5152              :      prefixed with the basename of the linker output:
    5153              : 
    5154              :      # gcc b.c d.c -o ab -gsplit-dwarf
    5155              :      -> cc1 -dumpdir ab- -dumpbase b.c -dumpbase-ext .c # ab-b.dwo
    5156              :      && cc1 -dumpdir ab- -dumpbase d.c -dumpbase-ext .c # ab-d.dwo
    5157              :      && link ... -o ab
    5158              : 
    5159              :      # gcc b.c d.c [-o a.out] -gsplit-dwarf
    5160              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.dwo
    5161              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.dwo
    5162              :      && link ... [-o a.out]
    5163              : 
    5164              :      When compiling and linking, a prevailing -dumpdir fully overrides
    5165              :      the prefix of aux outputs given by the output name:
    5166              : 
    5167              :      # gcc -dumpdir f b.c d.c -gsplit-dwarf [-o [dir/]whatever]
    5168              :      -> cc1 -dumpdir f -dumpbase b.c -dumpbase-ext .c # fb.dwo
    5169              :      && cc1 -dumpdir f -dumpbase d.c -dumpbase-ext .c # fd.dwo
    5170              :      && link ... [-o whatever]
    5171              : 
    5172              :      When compiling multiple inputs, an explicit -dumpbase is combined
    5173              :      with -dumpdir, affecting aux outputs, but not the .o outputs:
    5174              : 
    5175              :      # gcc -dumpdir f -dumpbase g- b.c d.c -gsplit-dwarf -c
    5176              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # b.o fg-b.dwo
    5177              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # d.o fg-d.dwo
    5178              : 
    5179              :      When compiling and linking with -save-temps, the .o outputs that
    5180              :      would have been temporary become aux outputs, so they get
    5181              :      affected by -dump* flags:
    5182              : 
    5183              :      # gcc -dumpdir f -dumpbase g- -save-temps b.c d.c
    5184              :      -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # fg-b.o
    5185              :      && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # fg-d.o
    5186              :      && link
    5187              : 
    5188              :      If -save-temps=* prevails over -dumpdir, however, the explicit
    5189              :      -dumpdir is discarded, as if it wasn't there.  The basename of
    5190              :      the implicit linker output, a.out or a.exe, becomes a- as the aux
    5191              :      output prefix for all compilations:
    5192              : 
    5193              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c
    5194              :      -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.o
    5195              :      && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.o
    5196              :      && link
    5197              : 
    5198              :      A single -dumpbase, applying to multiple inputs, overrides the
    5199              :      linker output name, implied or explicit, as the aux output prefix:
    5200              : 
    5201              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c
    5202              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5203              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5204              :      && link
    5205              : 
    5206              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c -o dir/h.out
    5207              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5208              :      && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
    5209              :      && link -o dir/h.out
    5210              : 
    5211              :      Now, if the linker output is NOT overridden as a prefix, but
    5212              :      -save-temps=* overrides implicit or explicit -dumpdir, the
    5213              :      effective dump dir combines the dir selected by the -save-temps=*
    5214              :      option with the basename of the specified or implied link output:
    5215              : 
    5216              :      # gcc [-dumpdir f] -save-temps=cwd b.c d.c -o dir/h.out
    5217              :      -> cc1 -dumpdir h- -dumpbase b.c -dumpbase-ext .c # h-b.o
    5218              :      && cc1 -dumpdir h- -dumpbase d.c -dumpbase-ext .c # h-d.o
    5219              :      && link -o dir/h.out
    5220              : 
    5221              :      # gcc [-dumpdir f] -save-temps=obj b.c d.c -o dir/h.out
    5222              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5223              :      && cc1 -dumpdir dir/h- -dumpbase d.c -dumpbase-ext .c # dir/h-d.o
    5224              :      && link -o dir/h.out
    5225              : 
    5226              :      But then again, a single -dumpbase applying to multiple inputs
    5227              :      gets used instead of the linker output basename in the combined
    5228              :      dumpdir:
    5229              : 
    5230              :      # gcc [-dumpdir f] -dumpbase g- -save-temps=obj b.c d.c -o dir/h.out
    5231              :      -> cc1 -dumpdir dir/g- -dumpbase b.c -dumpbase-ext .c # dir/g-b.o
    5232              :      && cc1 -dumpdir dir/g- -dumpbase d.c -dumpbase-ext .c # dir/g-d.o
    5233              :      && link -o dir/h.out
    5234              : 
    5235              :      With a single input being compiled, the output basename does NOT
    5236              :      affect the dumpdir prefix.
    5237              : 
    5238              :      # gcc -save-temps=obj b.c -gsplit-dwarf -c -o dir/b.o
    5239              :      -> cc1 -dumpdir dir/ -dumpbase b.c -dumpbase-ext .c # dir/b.o dir/b.dwo
    5240              : 
    5241              :      but when compiling and linking even a single file, it does:
    5242              : 
    5243              :      # gcc -save-temps=obj b.c -o dir/h.out
    5244              :      -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
    5245              : 
    5246              :      unless an explicit -dumpdir prevails:
    5247              : 
    5248              :      # gcc -save-temps[=obj] -dumpdir g- b.c -o dir/h.out
    5249              :      -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
    5250              : 
    5251              :   */
    5252              : 
    5253       304736 :   bool explicit_dumpdir = dumpdir;
    5254              : 
    5255       304684 :   if ((!save_temps_overrides_dumpdir && explicit_dumpdir)
    5256       588863 :       || (output_file && not_actual_file_p (output_file)))
    5257              :     {
    5258              :       /* Do nothing.  */
    5259              :     }
    5260              : 
    5261              :   /* If -save-temps=obj and -o name, create the prefix to use for %b.
    5262              :      Otherwise just make -save-temps=obj the same as -save-temps=cwd.  */
    5263       282672 :   else if (save_temps_flag != SAVE_TEMPS_CWD && output_file != NULL)
    5264              :     {
    5265       257660 :       free (dumpdir);
    5266       257660 :       dumpdir = NULL;
    5267       257660 :       temp = lbasename (output_file);
    5268       257660 :       if (temp != output_file)
    5269       103816 :         dumpdir = xstrndup (output_file,
    5270       103816 :                             strlen (output_file) - strlen (temp));
    5271              :     }
    5272        25012 :   else if (dumpdir)
    5273              :     {
    5274            5 :       free (dumpdir);
    5275            5 :       dumpdir = NULL;
    5276              :     }
    5277              : 
    5278       304736 :   if (save_temps_flag)
    5279          460 :     save_temps_flag = SAVE_TEMPS_DUMP;
    5280              : 
    5281              :   /* If there is any pathname component in an explicit -dumpbase, it
    5282              :      overrides dumpdir entirely, so discard it right away.  Although
    5283              :      the presence of an explicit -dumpdir matters for the driver, it
    5284              :      shouldn't matter for other processes, that get all that's needed
    5285              :      from the -dumpdir and -dumpbase always passed to them.  */
    5286       304736 :   if (dumpdir && dumpbase && lbasename (dumpbase) != dumpbase)
    5287              :     {
    5288        20470 :       free (dumpdir);
    5289        20470 :       dumpdir = NULL;
    5290              :     }
    5291              : 
    5292              :   /* Check that dumpbase_ext matches the end of dumpbase, drop it
    5293              :      otherwise.  */
    5294       304736 :   if (dumpbase_ext && dumpbase && *dumpbase)
    5295              :     {
    5296           20 :       int lendb = strlen (dumpbase);
    5297           20 :       int lendbx = strlen (dumpbase_ext);
    5298              : 
    5299              :       /* -dumpbase-ext must be a suffix proper; discard it if it
    5300              :           matches all of -dumpbase, as that would make for an empty
    5301              :           basename.  */
    5302           20 :       if (lendbx >= lendb
    5303           19 :           || strcmp (dumpbase + lendb - lendbx, dumpbase_ext) != 0)
    5304              :         {
    5305            1 :           free (dumpbase_ext);
    5306            1 :           dumpbase_ext = NULL;
    5307              :         }
    5308              :     }
    5309              : 
    5310              :   /* -dumpbase with multiple sources goes into dumpdir.  With a single
    5311              :      source, it does only if linking and if dumpdir was not explicitly
    5312              :      specified.  */
    5313        22001 :   if (dumpbase && *dumpbase
    5314       325284 :       && (single_input_file_index () == -2
    5315        20264 :           || (!have_c && !explicit_dumpdir)))
    5316              :     {
    5317          296 :       char *prefix;
    5318              : 
    5319          296 :       if (dumpbase_ext)
    5320              :         /* We checked that they match above.  */
    5321            6 :         dumpbase[strlen (dumpbase) - strlen (dumpbase_ext)] = '\0';
    5322              : 
    5323          296 :       if (dumpdir)
    5324           13 :         prefix = concat (dumpdir, dumpbase, "-", NULL);
    5325              :       else
    5326          283 :         prefix = concat (dumpbase, "-", NULL);
    5327              : 
    5328          296 :       free (dumpdir);
    5329          296 :       free (dumpbase);
    5330          296 :       free (dumpbase_ext);
    5331          296 :       dumpbase = dumpbase_ext = NULL;
    5332          296 :       dumpdir = prefix;
    5333          296 :       dumpdir_trailing_dash_added = true;
    5334              :     }
    5335              : 
    5336              :   /* If dumpbase was not brought into dumpdir but we're linking, bring
    5337              :      output_file into dumpdir unless dumpdir was explicitly specified.
    5338              :      The test for !explicit_dumpdir is further below, because we want
    5339              :      to use the obase computation for a ghost outbase, passed to
    5340              :      GCC_COLLECT_OPTIONS.  */
    5341       304440 :   else if (!have_c && (!explicit_dumpdir || (dumpbase && !*dumpbase)))
    5342              :     {
    5343              :       /* If we get here, we know dumpbase was not specified, or it was
    5344              :          specified as an empty string.  If it was anything else, it
    5345              :          would have combined with dumpdir above, because the condition
    5346              :          for dumpbase to be used when present is broader than the
    5347              :          condition that gets us here.  */
    5348       116297 :       gcc_assert (!dumpbase || !*dumpbase);
    5349              : 
    5350       116297 :       const char *obase;
    5351       116297 :       char *tofree = NULL;
    5352       116297 :       if (!output_file || not_actual_file_p (output_file))
    5353              :         obase = "a";
    5354              :       else
    5355              :         {
    5356        94690 :           obase = lbasename (output_file);
    5357        94690 :           size_t blen = strlen (obase), xlen;
    5358              :           /* Drop the suffix if it's dumpbase_ext, if given,
    5359              :              otherwise .exe or the target executable suffix, or if the
    5360              :              output was explicitly named a.out, but not otherwise.  */
    5361        94690 :           if (dumpbase_ext
    5362        94690 :               ? (blen > (xlen = strlen (dumpbase_ext))
    5363          223 :                  && strcmp ((temp = (obase + blen - xlen)),
    5364              :                             dumpbase_ext) == 0)
    5365        94467 :               : ((temp = strrchr (obase + 1, '.'))
    5366        92604 :                  && (xlen = strlen (temp))
    5367       187071 :                  && (strcmp (temp, ".exe") == 0
    5368              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    5369              :                      || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
    5370              : #endif
    5371         9003 :                      || strcmp (obase, "a.out") == 0)))
    5372              :             {
    5373        83850 :               tofree = xstrndup (obase, blen - xlen);
    5374        83850 :               obase = tofree;
    5375              :             }
    5376              :         }
    5377              : 
    5378              :       /* We wish to save this basename to the -dumpdir passed through
    5379              :          GCC_COLLECT_OPTIONS within maybe_run_linker, for e.g. LTO,
    5380              :          but we do NOT wish to add it to e.g. %b, so we keep
    5381              :          outbase_length as zero.  */
    5382       116297 :       gcc_assert (!outbase);
    5383       116297 :       outbase_length = 0;
    5384              : 
    5385              :       /* If we're building [dir1/]foo[.exe] out of a single input
    5386              :          [dir2/]foo.c that shares the same basename, dump to
    5387              :          [dir2/]foo.c.* rather than duplicating the basename into
    5388              :          [dir2/]foo-foo.c.*.  */
    5389       116297 :       int idxin;
    5390       116297 :       if (dumpbase
    5391       116297 :           || ((idxin = single_input_file_index ()) >= 0
    5392        86505 :               && adds_single_suffix_p (lbasename (infiles[idxin].name),
    5393              :                                        obase)))
    5394              :         {
    5395        77465 :           if (obase == tofree)
    5396        75695 :             outbase = tofree;
    5397              :           else
    5398              :             {
    5399         1770 :               outbase = xstrdup (obase);
    5400         1770 :               free (tofree);
    5401              :             }
    5402       116297 :           obase = tofree = NULL;
    5403              :         }
    5404              :       else
    5405              :         {
    5406        38832 :           if (dumpdir)
    5407              :             {
    5408        14861 :               char *p = concat (dumpdir, obase, "-", NULL);
    5409        14861 :               free (dumpdir);
    5410        14861 :               dumpdir = p;
    5411              :             }
    5412              :           else
    5413        23971 :             dumpdir = concat (obase, "-", NULL);
    5414              : 
    5415        38832 :           dumpdir_trailing_dash_added = true;
    5416              : 
    5417        38832 :           free (tofree);
    5418        38832 :           obase = tofree = NULL;
    5419              :         }
    5420              : 
    5421       116297 :       if (!explicit_dumpdir || dumpbase)
    5422              :         {
    5423              :           /* Absent -dumpbase and present -dumpbase-ext have been applied
    5424              :              to the linker output name, so compute fresh defaults for each
    5425              :              compilation.  */
    5426       116297 :           free (dumpbase_ext);
    5427       116297 :           dumpbase_ext = NULL;
    5428              :         }
    5429              :     }
    5430              : 
    5431              :   /* Now, if we're compiling, or if we haven't used the dumpbase
    5432              :      above, then outbase (%B) is derived from dumpbase, if given, or
    5433              :      from the output name, given or implied.  We can't precompute
    5434              :      implied output names, but that's ok, since they're derived from
    5435              :      input names.  Just make sure we skip this if dumpbase is the
    5436              :      empty string: we want to use input names then, so don't set
    5437              :      outbase.  */
    5438       304736 :   if ((dumpbase || have_c)
    5439       189808 :       && !(dumpbase && !*dumpbase))
    5440              :     {
    5441       188355 :       gcc_assert (!outbase);
    5442              : 
    5443       188355 :       if (dumpbase)
    5444              :         {
    5445        20252 :           gcc_assert (single_input_file_index () != -2);
    5446              :           /* We do not want lbasename here; dumpbase with dirnames
    5447              :              overrides dumpdir entirely, even if dumpdir is
    5448              :              specified.  */
    5449        20252 :           if (dumpbase_ext)
    5450              :             /* We've already checked above that the suffix matches.  */
    5451           13 :             outbase = xstrndup (dumpbase,
    5452           13 :                                 strlen (dumpbase) - strlen (dumpbase_ext));
    5453              :           else
    5454        20239 :             outbase = xstrdup (dumpbase);
    5455              :         }
    5456       168103 :       else if (output_file && !not_actual_file_p (output_file))
    5457              :         {
    5458       163207 :           outbase = xstrdup (lbasename (output_file));
    5459       163207 :           char *p = strrchr (outbase + 1, '.');
    5460       163207 :           if (p)
    5461       163207 :             *p = '\0';
    5462              :         }
    5463              : 
    5464       188355 :       if (outbase)
    5465       183459 :         outbase_length = strlen (outbase);
    5466              :     }
    5467              : 
    5468              :   /* If there is any pathname component in an explicit -dumpbase, do
    5469              :      not use dumpdir, but retain it to pass it on to the compiler.  */
    5470       304736 :   if (dumpdir)
    5471       128157 :     dumpdir_length = strlen (dumpdir);
    5472              :   else
    5473       176579 :     dumpdir_length = 0;
    5474              : 
    5475              :   /* Check that dumpbase_ext, if still present, still matches the end
    5476              :      of dumpbase, if present, and drop it otherwise.  We only retained
    5477              :      it above when dumpbase was absent to maybe use it to drop the
    5478              :      extension from output_name before combining it with dumpdir.  We
    5479              :      won't deal with -dumpbase-ext when -dumpbase is not explicitly
    5480              :      given, even if just to activate backward-compatible dumpbase:
    5481              :      dropping it on the floor is correct, expected and documented
    5482              :      behavior.  Attempting to deal with a -dumpbase-ext that might
    5483              :      match the end of some input filename, or of the combination of
    5484              :      the output basename with the suffix of the input filename,
    5485              :      possible with an intermediate .gk extension for -fcompare-debug,
    5486              :      is just calling for trouble.  */
    5487       304736 :   if (dumpbase_ext)
    5488              :     {
    5489           22 :       if (!dumpbase || !*dumpbase)
    5490              :         {
    5491            9 :           free (dumpbase_ext);
    5492            9 :           dumpbase_ext = NULL;
    5493              :         }
    5494              :       else
    5495           13 :         gcc_assert (strcmp (dumpbase + strlen (dumpbase)
    5496              :                             - strlen (dumpbase_ext), dumpbase_ext) == 0);
    5497              :     }
    5498              : 
    5499       304736 :   if (save_temps_flag && use_pipes)
    5500              :     {
    5501              :       /* -save-temps overrides -pipe, so that temp files are produced */
    5502            0 :       if (save_temps_flag)
    5503            0 :         warning (0, "%<-pipe%> ignored because %<-save-temps%> specified");
    5504            0 :       use_pipes = 0;
    5505              :     }
    5506              : 
    5507       304736 :   if (!compare_debug)
    5508              :     {
    5509       304117 :       const char *gcd = env.get ("GCC_COMPARE_DEBUG");
    5510              : 
    5511       304117 :       if (gcd && gcd[0] == '-')
    5512              :         {
    5513            0 :           compare_debug = 2;
    5514            0 :           compare_debug_opt = gcd;
    5515              :         }
    5516            0 :       else if (gcd && *gcd && strcmp (gcd, "0"))
    5517              :         {
    5518            0 :           compare_debug = 3;
    5519            0 :           compare_debug_opt = "-gtoggle";
    5520              :         }
    5521              :     }
    5522          619 :   else if (compare_debug < 0)
    5523              :     {
    5524            0 :       compare_debug = 0;
    5525            0 :       gcc_assert (!compare_debug_opt);
    5526              :     }
    5527              : 
    5528              :   /* Set up the search paths.  We add directories that we expect to
    5529              :      contain GNU Toolchain components before directories specified by
    5530              :      the machine description so that we will find GNU components (like
    5531              :      the GNU assembler) before those of the host system.  */
    5532              : 
    5533              :   /* If we don't know where the toolchain has been installed, use the
    5534              :      configured-in locations.  */
    5535       304736 :   if (!gcc_exec_prefix)
    5536              :     {
    5537              : #ifndef OS2
    5538            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
    5539              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5540            0 :       add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
    5541              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5542            0 :       add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
    5543              :                   PREFIX_PRIORITY_LAST, 2, 0);
    5544              : #endif
    5545            0 :       add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
    5546              :                   PREFIX_PRIORITY_LAST, 1, 0);
    5547              :     }
    5548              : 
    5549       304736 :   gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
    5550       304736 :   tooldir_prefix2 = concat (tooldir_base_prefix, spec_machine,
    5551              :                             dir_separator_str, NULL);
    5552              : 
    5553              :   /* Look for tools relative to the location from which the driver is
    5554              :      running, or, if that is not available, the configured prefix.  */
    5555       304736 :   tooldir_prefix
    5556       609472 :     = concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    5557              :               spec_host_machine, dir_separator_str, spec_version,
    5558              :               accel_dir_suffix, dir_separator_str, tooldir_prefix2, NULL);
    5559       304736 :   free (tooldir_prefix2);
    5560              : 
    5561       304736 :   add_prefix (&exec_prefixes,
    5562       304736 :               concat (tooldir_prefix, "bin", dir_separator_str, NULL),
    5563              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 0);
    5564       304736 :   add_prefix (&startfile_prefixes,
    5565       304736 :               concat (tooldir_prefix, "lib", dir_separator_str, NULL),
    5566              :               "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
    5567       304736 :   free (tooldir_prefix);
    5568              : 
    5569              : #if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
    5570              :   /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
    5571              :      then consider it to relocate with the rest of the GCC installation
    5572              :      if GCC_EXEC_PREFIX is set.
    5573              :      ``make_relative_prefix'' is not compiled for VMS, so don't call it.  */
    5574              :   if (target_system_root && !target_system_root_changed && gcc_exec_prefix)
    5575              :     {
    5576              :       char *tmp_prefix = get_relative_prefix (decoded_options[0].arg,
    5577              :                                               standard_bindir_prefix,
    5578              :                                               target_system_root);
    5579              :       if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
    5580              :         {
    5581              :           target_system_root = tmp_prefix;
    5582              :           target_system_root_changed = 1;
    5583              :         }
    5584              :     }
    5585              : #endif
    5586              : 
    5587              :   /* More prefixes are enabled in main, after we read the specs file
    5588              :      and determine whether this is cross-compilation or not.  */
    5589              : 
    5590       304736 :   if (n_infiles != 0 && n_infiles == last_language_n_infiles && spec_lang != 0)
    5591            0 :     warning (0, "%<-x %s%> after last input file has no effect", spec_lang);
    5592              : 
    5593              :   /* Synthesize -fcompare-debug flag from the GCC_COMPARE_DEBUG
    5594              :      environment variable.  */
    5595       304736 :   if (compare_debug == 2 || compare_debug == 3)
    5596              :     {
    5597            0 :       const char *opt = concat ("-fcompare-debug=", compare_debug_opt, NULL);
    5598            0 :       save_switch (opt, 0, NULL, false, true);
    5599            0 :       compare_debug = 1;
    5600              :     }
    5601              : 
    5602              :   /* Ensure we only invoke each subprocess once.  */
    5603       304736 :   if (n_infiles == 0
    5604        11903 :       && (print_subprocess_help || print_help_list || print_version))
    5605              :     {
    5606              :       /* Create a dummy input file, so that we can pass
    5607              :          the help option on to the various sub-processes.  */
    5608           78 :       add_infile ("help-dummy", "c");
    5609              :     }
    5610              : 
    5611              :   /* Decide if undefined variable references are allowed in specs.  */
    5612              : 
    5613              :   /* -v alone is safe. --version and --help alone or together are safe.  Note
    5614              :      that -v would make them unsafe, as they'd then be run for subprocesses as
    5615              :      well, the location of which might depend on variables possibly coming
    5616              :      from self-specs.  Note also that the command name is counted in
    5617              :      decoded_options_count.  */
    5618              : 
    5619       304736 :   unsigned help_version_count = 0;
    5620              : 
    5621       304736 :   if (print_version)
    5622           78 :     help_version_count++;
    5623              : 
    5624       304736 :   if (print_help_list)
    5625            4 :     help_version_count++;
    5626              : 
    5627       609472 :   spec_undefvar_allowed =
    5628         1561 :     ((verbose_flag && decoded_options_count == 2)
    5629       306263 :      || help_version_count == decoded_options_count - 1);
    5630              : 
    5631       304736 :   alloc_switch ();
    5632       304736 :   switches[n_switches].part1 = 0;
    5633       304736 :   alloc_infile ();
    5634       304736 :   infiles[n_infiles].name = 0;
    5635       304736 : }
    5636              : 
    5637              : /* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
    5638              :    and place that in the environment.  */
    5639              : 
    5640              : static void
    5641       821217 : set_collect_gcc_options (void)
    5642              : {
    5643       821217 :   int i;
    5644       821217 :   int first_time;
    5645              : 
    5646              :   /* Build COLLECT_GCC_OPTIONS to have all of the options specified to
    5647              :      the compiler.  */
    5648       821217 :   obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=",
    5649              :                 sizeof ("COLLECT_GCC_OPTIONS=") - 1);
    5650              : 
    5651       821217 :   first_time = true;
    5652     19926793 :   for (i = 0; (int) i < n_switches; i++)
    5653              :     {
    5654     19105576 :       const char *const *args;
    5655     19105576 :       const char *p, *q;
    5656     19105576 :       if (!first_time)
    5657     18284359 :         obstack_grow (&collect_obstack, " ", 1);
    5658              : 
    5659     19105576 :       first_time = false;
    5660              : 
    5661              :       /* Ignore elided switches.  */
    5662     19226092 :       if ((switches[i].live_cond
    5663     19105576 :            & (SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC))
    5664              :           == SWITCH_IGNORE)
    5665       120516 :         continue;
    5666              : 
    5667     18985060 :       obstack_grow (&collect_obstack, "'-", 2);
    5668     18985060 :       q = switches[i].part1;
    5669     18985060 :       while ((p = strchr (q, '\'')))
    5670              :         {
    5671            0 :           obstack_grow (&collect_obstack, q, p - q);
    5672            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5673            0 :           q = ++p;
    5674              :         }
    5675     18985060 :       obstack_grow (&collect_obstack, q, strlen (q));
    5676     18985060 :       obstack_grow (&collect_obstack, "'", 1);
    5677              : 
    5678     23148589 :       for (args = switches[i].args; args && *args; args++)
    5679              :         {
    5680      4163529 :           obstack_grow (&collect_obstack, " '", 2);
    5681      4163529 :           q = *args;
    5682      4163529 :           while ((p = strchr (q, '\'')))
    5683              :             {
    5684            0 :               obstack_grow (&collect_obstack, q, p - q);
    5685            0 :               obstack_grow (&collect_obstack, "'\\''", 4);
    5686            0 :               q = ++p;
    5687              :             }
    5688      4163529 :           obstack_grow (&collect_obstack, q, strlen (q));
    5689      4163529 :           obstack_grow (&collect_obstack, "'", 1);
    5690              :         }
    5691              :     }
    5692              : 
    5693       821217 :   if (dumpdir)
    5694              :     {
    5695       582893 :       if (!first_time)
    5696       582893 :         obstack_grow (&collect_obstack, " ", 1);
    5697       582893 :       first_time = false;
    5698              : 
    5699       582893 :       obstack_grow (&collect_obstack, "'-dumpdir' '", 12);
    5700       582893 :       const char *p, *q;
    5701              : 
    5702       582893 :       q = dumpdir;
    5703       582893 :       while ((p = strchr (q, '\'')))
    5704              :         {
    5705            0 :           obstack_grow (&collect_obstack, q, p - q);
    5706            0 :           obstack_grow (&collect_obstack, "'\\''", 4);
    5707            0 :           q = ++p;
    5708              :         }
    5709       582893 :       obstack_grow (&collect_obstack, q, strlen (q));
    5710              : 
    5711       582893 :       obstack_grow (&collect_obstack, "'", 1);
    5712              :     }
    5713              : 
    5714       821217 :   obstack_grow (&collect_obstack, "\0", 1);
    5715       821217 :   xputenv (XOBFINISH (&collect_obstack, char *));
    5716       821217 : }
    5717              : 
    5718              : /* Process a spec string, accumulating and running commands.  */
    5719              : 
    5720              : /* These variables describe the input file name.
    5721              :    input_file_number is the index on outfiles of this file,
    5722              :    so that the output file name can be stored for later use by %o.
    5723              :    input_basename is the start of the part of the input file
    5724              :    sans all directory names, and basename_length is the number
    5725              :    of characters starting there excluding the suffix .c or whatever.  */
    5726              : 
    5727              : static const char *gcc_input_filename;
    5728              : static int input_file_number;
    5729              : size_t input_filename_length;
    5730              : static int basename_length;
    5731              : static int suffixed_basename_length;
    5732              : static const char *input_basename;
    5733              : static const char *input_suffix;
    5734              : #ifndef HOST_LACKS_INODE_NUMBERS
    5735              : static struct stat input_stat;
    5736              : #endif
    5737              : static int input_stat_set;
    5738              : 
    5739              : /* The compiler used to process the current input file.  */
    5740              : static struct compiler *input_file_compiler;
    5741              : 
    5742              : /* These are variables used within do_spec and do_spec_1.  */
    5743              : 
    5744              : /* Nonzero if an arg has been started and not yet terminated
    5745              :    (with space, tab or newline).  */
    5746              : static int arg_going;
    5747              : 
    5748              : /* Nonzero means %d or %g has been seen; the next arg to be terminated
    5749              :    is a temporary file name.  */
    5750              : static int delete_this_arg;
    5751              : 
    5752              : /* Nonzero means %w has been seen; the next arg to be terminated
    5753              :    is the output file name of this compilation.  */
    5754              : static int this_is_output_file;
    5755              : 
    5756              : /* Nonzero means %s has been seen; the next arg to be terminated
    5757              :    is the name of a library file and we should try the standard
    5758              :    search dirs for it.  */
    5759              : static int this_is_library_file;
    5760              : 
    5761              : /* Nonzero means %T has been seen; the next arg to be terminated
    5762              :    is the name of a linker script and we should try all of the
    5763              :    standard search dirs for it.  If it is found insert a --script
    5764              :    command line switch and then substitute the full path in place,
    5765              :    otherwise generate an error message.  */
    5766              : static int this_is_linker_script;
    5767              : 
    5768              : /* Nonzero means that the input of this command is coming from a pipe.  */
    5769              : static int input_from_pipe;
    5770              : 
    5771              : /* Nonnull means substitute this for any suffix when outputting a switches
    5772              :    arguments.  */
    5773              : static const char *suffix_subst;
    5774              : 
    5775              : /* If there is an argument being accumulated, terminate it and store it.  */
    5776              : 
    5777              : static void
    5778     80369556 : end_going_arg (void)
    5779              : {
    5780     80369556 :   if (arg_going)
    5781              :     {
    5782     18973733 :       const char *string;
    5783              : 
    5784     18973733 :       obstack_1grow (&obstack, 0);
    5785     18973733 :       string = XOBFINISH (&obstack, const char *);
    5786     18973733 :       if (this_is_library_file)
    5787       538155 :         string = find_file (string);
    5788     18973733 :       if (this_is_linker_script)
    5789              :         {
    5790            0 :           char * full_script_path = find_a_file (&startfile_prefixes, string, R_OK, true);
    5791              : 
    5792            0 :           if (full_script_path == NULL)
    5793              :             {
    5794            0 :               error ("unable to locate default linker script %qs in the library search paths", string);
    5795              :               /* Script was not found on search path.  */
    5796            0 :               return;
    5797              :             }
    5798            0 :           store_arg ("--script", false, false);
    5799            0 :           string = full_script_path;
    5800              :         }
    5801     18973733 :       store_arg (string, delete_this_arg, this_is_output_file);
    5802     18973733 :       if (this_is_output_file)
    5803        99581 :         outfiles[input_file_number] = string;
    5804     18973733 :       arg_going = 0;
    5805              :     }
    5806              : }
    5807              : 
    5808              : 
    5809              : /* Parse the WRAPPER string which is a comma separated list of the command line
    5810              :    and insert them into the beginning of argbuf.  */
    5811              : 
    5812              : static void
    5813            0 : insert_wrapper (const char *wrapper)
    5814              : {
    5815            0 :   int n = 0;
    5816            0 :   int i;
    5817            0 :   char *buf = xstrdup (wrapper);
    5818            0 :   char *p = buf;
    5819            0 :   unsigned int old_length = argbuf.length ();
    5820              : 
    5821            0 :   do
    5822              :     {
    5823            0 :       n++;
    5824            0 :       while (*p == ',')
    5825            0 :         p++;
    5826              :     }
    5827            0 :   while ((p = strchr (p, ',')) != NULL);
    5828              : 
    5829            0 :   argbuf.safe_grow (old_length + n, true);
    5830            0 :   memmove (argbuf.address () + n,
    5831            0 :            argbuf.address (),
    5832            0 :            old_length * sizeof (const_char_p));
    5833              : 
    5834            0 :   i = 0;
    5835            0 :   p = buf;
    5836              :   do
    5837              :     {
    5838            0 :       while (*p == ',')
    5839              :         {
    5840            0 :           *p = 0;
    5841            0 :           p++;
    5842              :         }
    5843            0 :       argbuf[i] = p;
    5844            0 :       i++;
    5845              :     }
    5846            0 :   while ((p = strchr (p, ',')) != NULL);
    5847            0 :   gcc_assert (i == n);
    5848            0 : }
    5849              : 
    5850              : /* Process the spec SPEC and run the commands specified therein.
    5851              :    Returns 0 if the spec is successfully processed; -1 if failed.  */
    5852              : 
    5853              : int
    5854       564193 : do_spec (const char *spec)
    5855              : {
    5856       564193 :   int value;
    5857              : 
    5858       564193 :   value = do_spec_2 (spec, NULL);
    5859              : 
    5860              :   /* Force out any unfinished command.
    5861              :      If -pipe, this forces out the last command if it ended in `|'.  */
    5862       564193 :   if (value == 0)
    5863              :     {
    5864       558761 :       if (argbuf.length () > 0
    5865       839147 :           && !strcmp (argbuf.last (), "|"))
    5866            0 :         argbuf.pop ();
    5867              : 
    5868       558761 :       set_collect_gcc_options ();
    5869              : 
    5870       558761 :       if (argbuf.length () > 0)
    5871       280386 :         value = execute ();
    5872              :     }
    5873              : 
    5874       564193 :   return value;
    5875              : }
    5876              : 
    5877              : /* Process the spec SPEC, with SOFT_MATCHED_PART designating the current value
    5878              :    of a matched * pattern which may be re-injected by way of %*.  */
    5879              : 
    5880              : static int
    5881      5382239 : do_spec_2 (const char *spec, const char *soft_matched_part)
    5882              : {
    5883      5382239 :   int result;
    5884              : 
    5885      5382239 :   clear_args ();
    5886      5382239 :   arg_going = 0;
    5887      5382239 :   delete_this_arg = 0;
    5888      5382239 :   this_is_output_file = 0;
    5889      5382239 :   this_is_library_file = 0;
    5890      5382239 :   this_is_linker_script = 0;
    5891      5382239 :   input_from_pipe = 0;
    5892      5382239 :   suffix_subst = NULL;
    5893              : 
    5894      5382239 :   result = do_spec_1 (spec, 0, soft_matched_part);
    5895              : 
    5896      5382239 :   end_going_arg ();
    5897              : 
    5898      5382239 :   return result;
    5899              : }
    5900              : 
    5901              : /* Process the given spec string and add any new options to the end
    5902              :    of the switches/n_switches array.  */
    5903              : 
    5904              : static void
    5905      3048670 : do_option_spec (const char *name, const char *spec)
    5906              : {
    5907      3048670 :   unsigned int i, value_count, value_len;
    5908      3048670 :   const char *p, *q, *value;
    5909      3048670 :   char *tmp_spec, *tmp_spec_p;
    5910              : 
    5911      3048670 :   if (configure_default_options[0].name == NULL)
    5912              :     return;
    5913              : 
    5914      8231409 :   for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
    5915      5792473 :     if (strcmp (configure_default_options[i].name, name) == 0)
    5916              :       break;
    5917      3048670 :   if (i == ARRAY_SIZE (configure_default_options))
    5918              :     return;
    5919              : 
    5920       609734 :   value = configure_default_options[i].value;
    5921       609734 :   value_len = strlen (value);
    5922              : 
    5923              :   /* Compute the size of the final spec.  */
    5924       609734 :   value_count = 0;
    5925       609734 :   p = spec;
    5926      1219468 :   while ((p = strstr (p, "%(VALUE)")) != NULL)
    5927              :     {
    5928       609734 :       p ++;
    5929       609734 :       value_count ++;
    5930              :     }
    5931              : 
    5932              :   /* Replace each %(VALUE) by the specified value.  */
    5933       609734 :   tmp_spec = (char *) alloca (strlen (spec) + 1
    5934              :                      + value_count * (value_len - strlen ("%(VALUE)")));
    5935       609734 :   tmp_spec_p = tmp_spec;
    5936       609734 :   q = spec;
    5937      1219468 :   while ((p = strstr (q, "%(VALUE)")) != NULL)
    5938              :     {
    5939       609734 :       memcpy (tmp_spec_p, q, p - q);
    5940       609734 :       tmp_spec_p = tmp_spec_p + (p - q);
    5941       609734 :       memcpy (tmp_spec_p, value, value_len);
    5942       609734 :       tmp_spec_p += value_len;
    5943       609734 :       q = p + strlen ("%(VALUE)");
    5944              :     }
    5945       609734 :   strcpy (tmp_spec_p, q);
    5946              : 
    5947       609734 :   do_self_spec (tmp_spec);
    5948              : }
    5949              : 
    5950              : /* Process the given spec string and add any new options to the end
    5951              :    of the switches/n_switches array.  */
    5952              : 
    5953              : static void
    5954      2744123 : do_self_spec (const char *spec)
    5955              : {
    5956      2744123 :   int i;
    5957              : 
    5958      2744123 :   do_spec_2 (spec, NULL);
    5959      2744123 :   do_spec_1 (" ", 0, NULL);
    5960              : 
    5961              :   /* Mark %<S switches processed by do_self_spec to be ignored permanently.
    5962              :      do_self_specs adds the replacements to switches array, so it shouldn't
    5963              :      be processed afterwards.  */
    5964     66018285 :   for (i = 0; i < n_switches; i++)
    5965     60530039 :     if ((switches[i].live_cond & SWITCH_IGNORE))
    5966          667 :       switches[i].live_cond |= SWITCH_IGNORE_PERMANENTLY;
    5967              : 
    5968      2744123 :   if (argbuf.length () > 0)
    5969              :     {
    5970       580185 :       const char **argbuf_copy;
    5971       580185 :       struct cl_decoded_option *decoded_options;
    5972       580185 :       struct cl_option_handlers handlers;
    5973       580185 :       unsigned int decoded_options_count;
    5974       580185 :       unsigned int j;
    5975              : 
    5976              :       /* Create a copy of argbuf with a dummy argv[0] entry for
    5977              :          decode_cmdline_options_to_array.  */
    5978       580185 :       argbuf_copy = XNEWVEC (const char *,
    5979              :                              argbuf.length () + 1);
    5980       580185 :       argbuf_copy[0] = "";
    5981       580185 :       memcpy (argbuf_copy + 1, argbuf.address (),
    5982       580185 :               argbuf.length () * sizeof (const char *));
    5983              : 
    5984      1160370 :       decode_cmdline_options_to_array (argbuf.length () + 1,
    5985              :                                        argbuf_copy,
    5986              :                                        CL_DRIVER, &decoded_options,
    5987              :                                        &decoded_options_count);
    5988       580185 :       free (argbuf_copy);
    5989              : 
    5990       580185 :       set_option_handlers (&handlers);
    5991              : 
    5992      1162846 :       for (j = 1; j < decoded_options_count; j++)
    5993              :         {
    5994       582661 :           switch (decoded_options[j].opt_index)
    5995              :             {
    5996            0 :             case OPT_SPECIAL_input_file:
    5997              :               /* Specs should only generate options, not input
    5998              :                  files.  */
    5999            0 :               if (strcmp (decoded_options[j].arg, "-") != 0)
    6000            0 :                 fatal_error (input_location,
    6001              :                              "switch %qs does not start with %<-%>",
    6002              :                              decoded_options[j].arg);
    6003              :               else
    6004            0 :                 fatal_error (input_location,
    6005              :                              "spec-generated switch is just %<-%>");
    6006         1238 :               break;
    6007              : 
    6008         1238 :             case OPT_fcompare_debug_second:
    6009         1238 :             case OPT_fcompare_debug:
    6010         1238 :             case OPT_fcompare_debug_:
    6011         1238 :             case OPT_o:
    6012              :               /* Avoid duplicate processing of some options from
    6013              :                  compare-debug specs; just save them here.  */
    6014         1238 :               save_switch (decoded_options[j].canonical_option[0],
    6015         1238 :                            (decoded_options[j].canonical_option_num_elements
    6016              :                             - 1),
    6017         1238 :                            &decoded_options[j].canonical_option[1], false, true);
    6018         1238 :               break;
    6019              : 
    6020       581423 :             default:
    6021       581423 :               read_cmdline_option (&global_options, &global_options_set,
    6022              :                                    decoded_options + j, UNKNOWN_LOCATION,
    6023              :                                    CL_DRIVER, &handlers, global_dc);
    6024       581423 :               break;
    6025              :             }
    6026              :         }
    6027              : 
    6028       580185 :       free (decoded_options);
    6029              : 
    6030       580185 :       alloc_switch ();
    6031       580185 :       switches[n_switches].part1 = 0;
    6032              :     }
    6033      2744123 : }
    6034              : 
    6035              : /* Callback for processing %D and %I specs.  */
    6036              : 
    6037              : struct spec_path {
    6038              :   const char *option;
    6039              :   const char *append;
    6040              :   size_t append_len;
    6041              :   bool omit_relative;
    6042              :   bool separate_options;
    6043              :   bool realpaths;
    6044              : 
    6045              :   void *operator() (char *path);
    6046              : };
    6047              : 
    6048              : void *
    6049      3335044 : spec_path::operator() (char *path)
    6050              : {
    6051      3335044 :   size_t len = 0;
    6052      3335044 :   char save = 0;
    6053              : 
    6054              :   /* The path must exist; we want to resolve it to the realpath so that this
    6055              :      can be embedded as a runpath.  */
    6056      3335044 :   if (realpaths)
    6057            0 :      path = lrealpath (path);
    6058              : 
    6059              :   /* However, if we failed to resolve it - perhaps because there was a bogus
    6060              :      -B option on the command line, then punt on this entry.  */
    6061      3335044 :   if (!path)
    6062              :     return NULL;
    6063              : 
    6064      3335044 :   if (omit_relative && !IS_ABSOLUTE_PATH (path))
    6065              :     return NULL;
    6066              : 
    6067      3335044 :   if (append_len != 0)
    6068              :     {
    6069      1388112 :       len = strlen (path);
    6070      1388112 :       memcpy (path + len, append, append_len + 1);
    6071              :     }
    6072              : 
    6073      3335044 :   if (!is_directory (path))
    6074              :     return NULL;
    6075              : 
    6076      1253094 :   do_spec_1 (option, 1, NULL);
    6077      1253094 :   if (separate_options)
    6078       448941 :     do_spec_1 (" ", 0, NULL);
    6079              : 
    6080      1253094 :   if (append_len == 0)
    6081              :     {
    6082       804153 :       len = strlen (path);
    6083       804153 :       save = path[len - 1];
    6084       804153 :       if (IS_DIR_SEPARATOR (path[len - 1]))
    6085       804153 :         path[len - 1] = '\0';
    6086              :     }
    6087              : 
    6088      1253094 :   do_spec_1 (path, 1, NULL);
    6089      1253094 :   do_spec_1 (" ", 0, NULL);
    6090              : 
    6091              :   /* Must not damage the original path.  */
    6092      1253094 :   if (append_len == 0)
    6093       804153 :     path[len - 1] = save;
    6094              : 
    6095              :   return NULL;
    6096              : }
    6097              : 
    6098              : /* True if we should compile INFILE. */
    6099              : 
    6100              : static bool
    6101        43478 : compile_input_file_p (struct infile *infile)
    6102              : {
    6103        26061 :   if ((!infile->language) || (infile->language[0] != '*'))
    6104        38874 :     if (infile->incompiler == input_file_compiler)
    6105            0 :       return true;
    6106              :   return false;
    6107              : }
    6108              : 
    6109              : /* Process each member of VEC as a spec.  */
    6110              : 
    6111              : static void
    6112       464980 : do_specs_vec (vec<char_p> vec)
    6113              : {
    6114       465098 :   for (char *opt : vec)
    6115              :     {
    6116           70 :       do_spec_1 (opt, 1, NULL);
    6117              :       /* Make each accumulated option a separate argument.  */
    6118           70 :       do_spec_1 (" ", 0, NULL);
    6119              :     }
    6120       464980 : }
    6121              : 
    6122              : /* Add options passed via -Xassembler or -Wa to COLLECT_AS_OPTIONS.  */
    6123              : 
    6124              : static void
    6125       304735 : putenv_COLLECT_AS_OPTIONS (vec<char_p> vec)
    6126              : {
    6127       304735 :   if (vec.is_empty ())
    6128       304735 :      return;
    6129              : 
    6130          103 :   obstack_init (&collect_obstack);
    6131          103 :   obstack_grow (&collect_obstack, "COLLECT_AS_OPTIONS=",
    6132              :                 strlen ("COLLECT_AS_OPTIONS="));
    6133              : 
    6134          103 :   char *opt;
    6135          103 :   unsigned ix;
    6136              : 
    6137          298 :   FOR_EACH_VEC_ELT (vec, ix, opt)
    6138              :     {
    6139          195 :       obstack_1grow (&collect_obstack, '\'');
    6140          195 :       obstack_grow (&collect_obstack, opt, strlen (opt));
    6141          195 :       obstack_1grow (&collect_obstack, '\'');
    6142          195 :       if (ix < vec.length () - 1)
    6143           92 :         obstack_1grow(&collect_obstack, ' ');
    6144              :     }
    6145              : 
    6146          103 :   obstack_1grow (&collect_obstack, '\0');
    6147          103 :   xputenv (XOBFINISH (&collect_obstack, char *));
    6148              : }
    6149              : 
    6150              : /* Process the sub-spec SPEC as a portion of a larger spec.
    6151              :    This is like processing a whole spec except that we do
    6152              :    not initialize at the beginning and we do not supply a
    6153              :    newline by default at the end.
    6154              :    INSWITCH nonzero means don't process %-sequences in SPEC;
    6155              :    in this case, % is treated as an ordinary character.
    6156              :    This is used while substituting switches.
    6157              :    INSWITCH nonzero also causes SPC not to terminate an argument.
    6158              : 
    6159              :    Value is zero unless a line was finished
    6160              :    and the command on that line reported an error.  */
    6161              : 
    6162              : static int
    6163     52837189 : do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
    6164              : {
    6165     52837189 :   const char *p = spec;
    6166     52837189 :   int c;
    6167     52837189 :   int i;
    6168     52837189 :   int value;
    6169              : 
    6170              :   /* If it's an empty string argument to a switch, keep it as is.  */
    6171     52837189 :   if (inswitch && !*p)
    6172            1 :     arg_going = 1;
    6173              : 
    6174    534166460 :   while ((c = *p++))
    6175              :     /* If substituting a switch, treat all chars like letters.
    6176              :        Otherwise, NL, SPC, TAB and % are special.  */
    6177    481375159 :     switch (inswitch ? 'a' : c)
    6178              :       {
    6179       262456 :       case '\n':
    6180       262456 :         end_going_arg ();
    6181              : 
    6182       262456 :         if (argbuf.length () > 0
    6183       524912 :             && !strcmp (argbuf.last (), "|"))
    6184              :           {
    6185              :             /* A `|' before the newline means use a pipe here,
    6186              :                but only if -pipe was specified.
    6187              :                Otherwise, execute now and don't pass the `|' as an arg.  */
    6188       166476 :             if (use_pipes)
    6189              :               {
    6190            0 :                 input_from_pipe = 1;
    6191            0 :                 break;
    6192              :               }
    6193              :             else
    6194       166476 :               argbuf.pop ();
    6195              :           }
    6196              : 
    6197       262456 :         set_collect_gcc_options ();
    6198              : 
    6199       262456 :         if (argbuf.length () > 0)
    6200              :           {
    6201       262456 :             value = execute ();
    6202       262456 :             if (value)
    6203              :               return value;
    6204              :           }
    6205              :         /* Reinitialize for a new command, and for a new argument.  */
    6206       257024 :         clear_args ();
    6207       257024 :         arg_going = 0;
    6208       257024 :         delete_this_arg = 0;
    6209       257024 :         this_is_output_file = 0;
    6210       257024 :         this_is_library_file = 0;
    6211       257024 :         this_is_linker_script = 0;
    6212       257024 :         input_from_pipe = 0;
    6213       257024 :         break;
    6214              : 
    6215       166476 :       case '|':
    6216       166476 :         end_going_arg ();
    6217              : 
    6218              :         /* Use pipe */
    6219       166476 :         obstack_1grow (&obstack, c);
    6220       166476 :         arg_going = 1;
    6221       166476 :         break;
    6222              : 
    6223     69889046 :       case '\t':
    6224     69889046 :       case ' ':
    6225     69889046 :         end_going_arg ();
    6226              : 
    6227              :         /* Reinitialize for a new argument.  */
    6228     69889046 :         delete_this_arg = 0;
    6229     69889046 :         this_is_output_file = 0;
    6230     69889046 :         this_is_library_file = 0;
    6231     69889046 :         this_is_linker_script = 0;
    6232     69889046 :         break;
    6233              : 
    6234     49196480 :       case '%':
    6235     49196480 :         switch (c = *p++)
    6236              :           {
    6237            0 :           case 0:
    6238            0 :             fatal_error (input_location, "spec %qs invalid", spec);
    6239              : 
    6240         3611 :           case 'b':
    6241              :             /* Don't use %b in the linker command.  */
    6242         3611 :             gcc_assert (suffixed_basename_length);
    6243         3611 :             if (!this_is_output_file && dumpdir_length)
    6244          693 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6245         3611 :             if (this_is_output_file || !outbase_length)
    6246         3269 :               obstack_grow (&obstack, input_basename, basename_length);
    6247              :             else
    6248          342 :               obstack_grow (&obstack, outbase, outbase_length);
    6249         3611 :             if (compare_debug < 0)
    6250            6 :               obstack_grow (&obstack, ".gk", 3);
    6251         3611 :             arg_going = 1;
    6252         3611 :             break;
    6253              : 
    6254           10 :           case 'B':
    6255              :             /* Don't use %B in the linker command.  */
    6256           10 :             gcc_assert (suffixed_basename_length);
    6257           10 :             if (!this_is_output_file && dumpdir_length)
    6258            0 :               obstack_grow (&obstack, dumpdir, dumpdir_length);
    6259           10 :             if (this_is_output_file || !outbase_length)
    6260            5 :               obstack_grow (&obstack, input_basename, basename_length);
    6261              :             else
    6262            5 :               obstack_grow (&obstack, outbase, outbase_length);
    6263           10 :             if (compare_debug < 0)
    6264            3 :               obstack_grow (&obstack, ".gk", 3);
    6265           10 :             obstack_grow (&obstack, input_basename + basename_length,
    6266              :                           suffixed_basename_length - basename_length);
    6267              : 
    6268           10 :             arg_going = 1;
    6269           10 :             break;
    6270              : 
    6271        97059 :           case 'd':
    6272        97059 :             delete_this_arg = 2;
    6273        97059 :             break;
    6274              : 
    6275              :           /* Dump out the directories specified with LIBRARY_PATH,
    6276              :              followed by the absolute directories
    6277              :              that we search for startfiles.  */
    6278       105035 :           case 'D':
    6279       105035 :             {
    6280       105035 :               struct spec_path info;
    6281              : 
    6282       105035 :               info.option = "-L";
    6283       105035 :               info.append_len = 0;
    6284              : #ifdef RELATIVE_PREFIX_NOT_LINKDIR
    6285              :               /* Used on systems which record the specified -L dirs
    6286              :                  and use them to search for dynamic linking.
    6287              :                  Relative directories always come from -B,
    6288              :                  and it is better not to use them for searching
    6289              :                  at run time.  In particular, stage1 loses.  */
    6290              :               info.omit_relative = true;
    6291              : #else
    6292       105035 :               info.omit_relative = false;
    6293              : #endif
    6294       105035 :               info.separate_options = false;
    6295       105035 :               info.realpaths = false;
    6296              : 
    6297       105035 :               for_each_path (&startfile_prefixes, true, 0, info);
    6298              :             }
    6299       105035 :             break;
    6300              : 
    6301            0 :           case 'P':
    6302            0 :             {
    6303            0 :               struct spec_path info;
    6304              : 
    6305            0 :               info.option = RUNPATH_OPTION;
    6306            0 :               info.append_len = 0;
    6307            0 :               info.omit_relative = false;
    6308            0 :               info.separate_options = true;
    6309              :               /* We want to embed the actual paths that have the libraries.  */
    6310            0 :               info.realpaths = true;
    6311              : 
    6312            0 :               for_each_path (&startfile_prefixes, true, 0, info);
    6313              :             }
    6314            0 :             break;
    6315              : 
    6316              :           case 'e':
    6317              :             /* %efoo means report an error with `foo' as error message
    6318              :                and don't execute any more commands for this file.  */
    6319              :             {
    6320              :               const char *q = p;
    6321              :               char *buf;
    6322            0 :               while (*p != 0 && *p != '\n')
    6323            0 :                 p++;
    6324            0 :               buf = (char *) alloca (p - q + 1);
    6325            0 :               strncpy (buf, q, p - q);
    6326            0 :               buf[p - q] = 0;
    6327            0 :               error ("%s", _(buf));
    6328            0 :               return -1;
    6329              :             }
    6330              :             break;
    6331              :           case 'n':
    6332              :             /* %nfoo means report a notice with `foo' on stderr.  */
    6333              :             {
    6334              :               const char *q = p;
    6335              :               char *buf;
    6336            0 :               while (*p != 0 && *p != '\n')
    6337            0 :                 p++;
    6338            0 :               buf = (char *) alloca (p - q + 1);
    6339            0 :               strncpy (buf, q, p - q);
    6340            0 :               buf[p - q] = 0;
    6341            0 :               inform (UNKNOWN_LOCATION, "%s", _(buf));
    6342            0 :               if (*p)
    6343            0 :                 p++;
    6344              :             }
    6345              :             break;
    6346              : 
    6347          882 :           case 'j':
    6348          882 :             {
    6349          882 :               struct stat st;
    6350              : 
    6351              :               /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
    6352              :                  defined, and it is not a directory, and it is
    6353              :                  writable, use it.  Otherwise, treat this like any
    6354              :                  other temporary file.  */
    6355              : 
    6356          882 :               if ((!save_temps_flag)
    6357          882 :                   && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
    6358         1764 :                   && (access (HOST_BIT_BUCKET, W_OK) == 0))
    6359              :                 {
    6360          882 :                   obstack_grow (&obstack, HOST_BIT_BUCKET,
    6361              :                                 strlen (HOST_BIT_BUCKET));
    6362          882 :                   delete_this_arg = 0;
    6363          882 :                   arg_going = 1;
    6364          882 :                   break;
    6365              :                 }
    6366              :             }
    6367            0 :             goto create_temp_file;
    6368       166476 :           case '|':
    6369       166476 :             if (use_pipes)
    6370              :               {
    6371            0 :                 obstack_1grow (&obstack, '-');
    6372            0 :                 delete_this_arg = 0;
    6373            0 :                 arg_going = 1;
    6374              : 
    6375              :                 /* consume suffix */
    6376            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6377            0 :                   p++;
    6378            0 :                 if (p[0] == '%' && p[1] == 'O')
    6379            0 :                   p += 2;
    6380              : 
    6381              :                 break;
    6382              :               }
    6383       166476 :             goto create_temp_file;
    6384       161183 :           case 'm':
    6385       161183 :             if (use_pipes)
    6386              :               {
    6387              :                 /* consume suffix */
    6388            0 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6389            0 :                   p++;
    6390            0 :                 if (p[0] == '%' && p[1] == 'O')
    6391            0 :                   p += 2;
    6392              : 
    6393              :                 break;
    6394              :               }
    6395       161183 :             goto create_temp_file;
    6396       517389 :           case 'g':
    6397       517389 :           case 'u':
    6398       517389 :           case 'U':
    6399       517389 :           create_temp_file:
    6400       517389 :               {
    6401       517389 :                 struct temp_name *t;
    6402       517389 :                 int suffix_length;
    6403       517389 :                 const char *suffix = p;
    6404       517389 :                 char *saved_suffix = NULL;
    6405              : 
    6406      1541501 :                 while (*p == '.' || ISALNUM ((unsigned char) *p))
    6407      1024112 :                   p++;
    6408       517389 :                 suffix_length = p - suffix;
    6409       517389 :                 if (p[0] == '%' && p[1] == 'O')
    6410              :                   {
    6411        97281 :                     p += 2;
    6412              :                     /* We don't support extra suffix characters after %O.  */
    6413        97281 :                     if (*p == '.' || ISALNUM ((unsigned char) *p))
    6414            0 :                       fatal_error (input_location,
    6415              :                                    "spec %qs has invalid %<%%0%c%>", spec, *p);
    6416        97281 :                     if (suffix_length == 0)
    6417              :                       suffix = TARGET_OBJECT_SUFFIX;
    6418              :                     else
    6419              :                       {
    6420            0 :                         saved_suffix
    6421            0 :                           = XNEWVEC (char, suffix_length
    6422              :                                      + strlen (TARGET_OBJECT_SUFFIX) + 1);
    6423            0 :                         strncpy (saved_suffix, suffix, suffix_length);
    6424            0 :                         strcpy (saved_suffix + suffix_length,
    6425              :                                 TARGET_OBJECT_SUFFIX);
    6426              :                       }
    6427        97281 :                     suffix_length += strlen (TARGET_OBJECT_SUFFIX);
    6428              :                   }
    6429              : 
    6430       517389 :                 if (compare_debug < 0)
    6431              :                   {
    6432          610 :                     suffix = concat (".gk", suffix, NULL);
    6433          610 :                     suffix_length += 3;
    6434              :                   }
    6435              : 
    6436              :                 /* If -save-temps was specified, use that for the
    6437              :                    temp file.  */
    6438       517389 :                 if (save_temps_flag)
    6439              :                   {
    6440         1201 :                     char *tmp;
    6441         1201 :                     bool adjusted_suffix = false;
    6442         1201 :                     if (suffix_length
    6443         1201 :                         && !outbase_length && !basename_length
    6444          225 :                         && !dumpdir_trailing_dash_added)
    6445              :                       {
    6446           20 :                         adjusted_suffix = true;
    6447           20 :                         suffix++;
    6448           20 :                         suffix_length--;
    6449              :                       }
    6450         1201 :                     temp_filename_length
    6451         1201 :                       = dumpdir_length + suffix_length + 1;
    6452         1201 :                     if (outbase_length)
    6453           72 :                       temp_filename_length += outbase_length;
    6454              :                     else
    6455         1129 :                       temp_filename_length += basename_length;
    6456         1201 :                     tmp = (char *) alloca (temp_filename_length);
    6457         1201 :                     if (dumpdir_length)
    6458         1043 :                       memcpy (tmp, dumpdir, dumpdir_length);
    6459         1201 :                     if (outbase_length)
    6460           72 :                       memcpy (tmp + dumpdir_length, outbase,
    6461              :                               outbase_length);
    6462         1129 :                     else if (basename_length)
    6463          904 :                       memcpy (tmp + dumpdir_length, input_basename,
    6464              :                               basename_length);
    6465         1201 :                     memcpy (tmp + temp_filename_length - suffix_length - 1,
    6466              :                             suffix, suffix_length);
    6467         1201 :                     if (adjusted_suffix)
    6468              :                       {
    6469           20 :                         adjusted_suffix = false;
    6470           20 :                         suffix--;
    6471           20 :                         suffix_length++;
    6472              :                       }
    6473         1201 :                     tmp[temp_filename_length - 1] = '\0';
    6474         1201 :                     temp_filename = tmp;
    6475              : 
    6476         1201 :                     if (filename_cmp (temp_filename, gcc_input_filename) != 0)
    6477              :                       {
    6478              : #ifndef HOST_LACKS_INODE_NUMBERS
    6479         1201 :                         struct stat st_temp;
    6480              : 
    6481              :                         /* Note, set_input() resets input_stat_set to 0.  */
    6482         1201 :                         if (input_stat_set == 0)
    6483              :                           {
    6484          560 :                             input_stat_set = stat (gcc_input_filename,
    6485              :                                                    &input_stat);
    6486          560 :                             if (input_stat_set >= 0)
    6487          560 :                               input_stat_set = 1;
    6488              :                           }
    6489              : 
    6490              :                         /* If we have the stat for the gcc_input_filename
    6491              :                            and we can do the stat for the temp_filename
    6492              :                            then the they could still refer to the same
    6493              :                            file if st_dev/st_ino's are the same.  */
    6494         1201 :                         if (input_stat_set != 1
    6495         1201 :                             || stat (temp_filename, &st_temp) < 0
    6496          367 :                             || input_stat.st_dev != st_temp.st_dev
    6497         1215 :                             || input_stat.st_ino != st_temp.st_ino)
    6498              : #else
    6499              :                         /* Just compare canonical pathnames.  */
    6500              :                         char* input_realname = lrealpath (gcc_input_filename);
    6501              :                         char* temp_realname = lrealpath (temp_filename);
    6502              :                         bool files_differ = filename_cmp (input_realname, temp_realname);
    6503              :                         free (input_realname);
    6504              :                         free (temp_realname);
    6505              :                         if (files_differ)
    6506              : #endif
    6507              :                           {
    6508         1201 :                             temp_filename
    6509         1201 :                               = save_string (temp_filename,
    6510              :                                              temp_filename_length - 1);
    6511         1201 :                             obstack_grow (&obstack, temp_filename,
    6512              :                                                     temp_filename_length);
    6513         1201 :                             arg_going = 1;
    6514         1201 :                             delete_this_arg = 0;
    6515         1201 :                             break;
    6516              :                           }
    6517              :                       }
    6518              :                   }
    6519              : 
    6520              :                 /* See if we already have an association of %g/%u/%U and
    6521              :                    suffix.  */
    6522       883832 :                 for (t = temp_names; t; t = t->next)
    6523       535831 :                   if (t->length == suffix_length
    6524       358477 :                       && strncmp (t->suffix, suffix, suffix_length) == 0
    6525       172127 :                       && t->unique == (c == 'u' || c == 'U' || c == 'j'))
    6526              :                     break;
    6527              : 
    6528              :                 /* Make a new association if needed.  %u and %j
    6529              :                    require one.  */
    6530       516188 :                 if (t == 0 || c == 'u' || c == 'j')
    6531              :                   {
    6532       351741 :                     if (t == 0)
    6533              :                       {
    6534       348001 :                         t = XNEW (struct temp_name);
    6535       348001 :                         t->next = temp_names;
    6536       348001 :                         temp_names = t;
    6537              :                       }
    6538       351741 :                     t->length = suffix_length;
    6539       351741 :                     if (saved_suffix)
    6540              :                       {
    6541            0 :                         t->suffix = saved_suffix;
    6542            0 :                         saved_suffix = NULL;
    6543              :                       }
    6544              :                     else
    6545       351741 :                       t->suffix = save_string (suffix, suffix_length);
    6546       351741 :                     t->unique = (c == 'u' || c == 'U' || c == 'j');
    6547       351741 :                     temp_filename = make_temp_file (t->suffix);
    6548       351741 :                     temp_filename_length = strlen (temp_filename);
    6549       351741 :                     t->filename = temp_filename;
    6550       351741 :                     t->filename_length = temp_filename_length;
    6551              :                   }
    6552              : 
    6553       516188 :                 free (saved_suffix);
    6554              : 
    6555       516188 :                 obstack_grow (&obstack, t->filename, t->filename_length);
    6556       516188 :                 delete_this_arg = 1;
    6557              :               }
    6558       516188 :             arg_going = 1;
    6559       516188 :             break;
    6560              : 
    6561       287370 :           case 'i':
    6562       287370 :             if (combine_inputs)
    6563              :               {
    6564              :                 /* We are going to expand `%i' into `@FILE', where FILE
    6565              :                    is a newly-created temporary filename.  The filenames
    6566              :                    that would usually be expanded in place of %o will be
    6567              :                    written to the temporary file.  */
    6568        29696 :                 if (at_file_supplied)
    6569        12289 :                   open_at_file ();
    6570              : 
    6571        73174 :                 for (i = 0; (int) i < n_infiles; i++)
    6572        86956 :                   if (compile_input_file_p (&infiles[i]))
    6573              :                     {
    6574        38812 :                       store_arg (infiles[i].name, 0, 0);
    6575        38812 :                       infiles[i].compiled = true;
    6576              :                     }
    6577              : 
    6578        29696 :                 if (at_file_supplied)
    6579        12289 :                   close_at_file ();
    6580              :               }
    6581              :             else
    6582              :               {
    6583       257674 :                 obstack_grow (&obstack, gcc_input_filename,
    6584              :                               input_filename_length);
    6585       257674 :                 arg_going = 1;
    6586              :               }
    6587              :             break;
    6588              : 
    6589       223318 :           case 'I':
    6590       223318 :             {
    6591       223318 :               struct spec_path info;
    6592              : 
    6593       223318 :               if (multilib_dir)
    6594              :                 {
    6595         6029 :                   do_spec_1 ("-imultilib", 1, NULL);
    6596              :                   /* Make this a separate argument.  */
    6597         6029 :                   do_spec_1 (" ", 0, NULL);
    6598         6029 :                   do_spec_1 (multilib_dir, 1, NULL);
    6599         6029 :                   do_spec_1 (" ", 0, NULL);
    6600              :                 }
    6601              : 
    6602       223318 :               if (multiarch_dir)
    6603              :                 {
    6604            0 :                   do_spec_1 ("-imultiarch", 1, NULL);
    6605              :                   /* Make this a separate argument.  */
    6606            0 :                   do_spec_1 (" ", 0, NULL);
    6607            0 :                   do_spec_1 (multiarch_dir, 1, NULL);
    6608            0 :                   do_spec_1 (" ", 0, NULL);
    6609              :                 }
    6610              : 
    6611       223318 :               if (gcc_exec_prefix)
    6612              :                 {
    6613       223318 :                   do_spec_1 ("-iprefix", 1, NULL);
    6614              :                   /* Make this a separate argument.  */
    6615       223318 :                   do_spec_1 (" ", 0, NULL);
    6616       223318 :                   do_spec_1 (gcc_exec_prefix, 1, NULL);
    6617       223318 :                   do_spec_1 (" ", 0, NULL);
    6618              :                 }
    6619              : 
    6620       223318 :               if (target_system_root_changed ||
    6621       223318 :                   (target_system_root && target_sysroot_hdrs_suffix))
    6622              :                 {
    6623            0 :                   do_spec_1 ("-isysroot", 1, NULL);
    6624              :                   /* Make this a separate argument.  */
    6625            0 :                   do_spec_1 (" ", 0, NULL);
    6626            0 :                   do_spec_1 (target_system_root, 1, NULL);
    6627            0 :                   if (target_sysroot_hdrs_suffix)
    6628            0 :                     do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
    6629            0 :                   do_spec_1 (" ", 0, NULL);
    6630              :                 }
    6631              : 
    6632       223318 :               info.option = "-isystem";
    6633       223318 :               info.append = "include";
    6634       223318 :               info.append_len = strlen (info.append);
    6635       223318 :               info.omit_relative = false;
    6636       223318 :               info.separate_options = true;
    6637       223318 :               info.realpaths = false;
    6638              : 
    6639       223318 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6640              : 
    6641       223318 :               info.append = "include-fixed";
    6642       223318 :               if (*sysroot_hdrs_suffix_spec)
    6643            0 :                 info.append = concat (info.append, dir_separator_str,
    6644              :                                       multilib_dir, NULL);
    6645       223318 :               else if (multiarch_dir)
    6646              :                 {
    6647              :                   /* For multiarch, search include-fixed/<multiarch-dir>
    6648              :                      before include-fixed.  */
    6649            0 :                   info.append = concat (info.append, dir_separator_str,
    6650              :                                         multiarch_dir, NULL);
    6651            0 :                   info.append_len = strlen (info.append);
    6652            0 :                   for_each_path (&include_prefixes, false,
    6653              :                                  info.append_len, info);
    6654              : 
    6655            0 :                   info.append = "include-fixed";
    6656              :                 }
    6657       223318 :               info.append_len = strlen (info.append);
    6658       223318 :               for_each_path (&include_prefixes, false, info.append_len, info);
    6659              :             }
    6660       223318 :             break;
    6661              : 
    6662        95135 :           case 'o':
    6663              :             /* We are going to expand `%o' into `@FILE', where FILE
    6664              :                is a newly-created temporary filename.  The filenames
    6665              :                that would usually be expanded in place of %o will be
    6666              :                written to the temporary file.  */
    6667        95135 :             if (at_file_supplied)
    6668            6 :               open_at_file ();
    6669              : 
    6670       423731 :             for (i = 0; i < n_infiles + lang_specific_extra_outfiles; i++)
    6671       328596 :               if (outfiles[i])
    6672       328556 :                 store_arg (outfiles[i], 0, 0);
    6673              : 
    6674        95135 :             if (at_file_supplied)
    6675            6 :               close_at_file ();
    6676              :             break;
    6677              : 
    6678         3824 :           case 'O':
    6679         3824 :             obstack_grow (&obstack, TARGET_OBJECT_SUFFIX, strlen (TARGET_OBJECT_SUFFIX));
    6680         3824 :             arg_going = 1;
    6681         3824 :             break;
    6682              : 
    6683       538159 :           case 's':
    6684       538159 :             this_is_library_file = 1;
    6685       538159 :             break;
    6686              : 
    6687            0 :           case 'T':
    6688            0 :             this_is_linker_script = 1;
    6689            0 :             break;
    6690              : 
    6691          433 :           case 'V':
    6692          433 :             outfiles[input_file_number] = NULL;
    6693          433 :             break;
    6694              : 
    6695       100021 :           case 'w':
    6696       100021 :             this_is_output_file = 1;
    6697       100021 :             break;
    6698              : 
    6699       175256 :           case 'W':
    6700       175256 :             {
    6701       175256 :               unsigned int cur_index = argbuf.length ();
    6702              :               /* Handle the {...} following the %W.  */
    6703       175256 :               if (*p != '{')
    6704            0 :                 fatal_error (input_location,
    6705              :                              "spec %qs has invalid %<%%W%c%>", spec, *p);
    6706       175256 :               p = handle_braces (p + 1);
    6707       175256 :               if (p == 0)
    6708              :                 return -1;
    6709       175256 :               end_going_arg ();
    6710              :               /* If any args were output, mark the last one for deletion
    6711              :                  on failure.  */
    6712       350512 :               if (argbuf.length () != cur_index)
    6713       172071 :                 record_temp_file (argbuf.last (), 0, 1);
    6714              :               break;
    6715              :             }
    6716              : 
    6717       301957 :           case '@':
    6718              :             /* Handle the {...} following the %@.  */
    6719       301957 :             if (*p != '{')
    6720            0 :               fatal_error (input_location,
    6721              :                            "spec %qs has invalid %<%%@%c%>", spec, *p);
    6722       301957 :             if (at_file_supplied)
    6723           15 :               open_at_file ();
    6724       301957 :             p = handle_braces (p + 1);
    6725       301957 :             if (at_file_supplied)
    6726           15 :               close_at_file ();
    6727       301957 :             if (p == 0)
    6728              :               return -1;
    6729              :             break;
    6730              : 
    6731              :           /* %x{OPTION} records OPTION for %X to output.  */
    6732            0 :           case 'x':
    6733            0 :             {
    6734            0 :               const char *p1 = p;
    6735            0 :               char *string;
    6736              : 
    6737              :               /* Skip past the option value and make a copy.  */
    6738            0 :               if (*p != '{')
    6739            0 :                 fatal_error (input_location,
    6740              :                              "spec %qs has invalid %<%%x%c%>", spec, *p);
    6741            0 :               while (*p++ != '}')
    6742              :                 ;
    6743            0 :               string = save_string (p1 + 1, p - p1 - 2);
    6744              : 
    6745              :               /* See if we already recorded this option.  */
    6746            0 :               for (const char *opt : linker_options)
    6747            0 :                 if (! strcmp (string, opt))
    6748              :                   {
    6749            0 :                     free (string);
    6750            0 :                     return 0;
    6751              :                   }
    6752              : 
    6753              :               /* This option is new; add it.  */
    6754            0 :               add_linker_option (string, strlen (string));
    6755            0 :               free (string);
    6756              :             }
    6757            0 :             break;
    6758              : 
    6759              :           /* Dump out the options accumulated previously using %x.  */
    6760        95135 :           case 'X':
    6761        95135 :             do_specs_vec (linker_options);
    6762        95135 :             break;
    6763              : 
    6764              :           /* Dump out the options accumulated previously using -Wa,.  */
    6765       163023 :           case 'Y':
    6766       163023 :             do_specs_vec (assembler_options);
    6767       163023 :             break;
    6768              : 
    6769              :           /* Dump out the options accumulated previously using -Wp,.  */
    6770       206822 :           case 'Z':
    6771       206822 :             do_specs_vec (preprocessor_options);
    6772       206822 :             break;
    6773              : 
    6774              :             /* Here are digits and numbers that just process
    6775              :                a certain constant string as a spec.  */
    6776              : 
    6777       284312 :           case '1':
    6778       284312 :             value = do_spec_1 (cc1_spec, 0, NULL);
    6779       284312 :             if (value != 0)
    6780              :               return value;
    6781              :             break;
    6782              : 
    6783        98120 :           case '2':
    6784        98120 :             value = do_spec_1 (cc1plus_spec, 0, NULL);
    6785        98120 :             if (value != 0)
    6786              :               return value;
    6787              :             break;
    6788              : 
    6789       163023 :           case 'a':
    6790       163023 :             value = do_spec_1 (asm_spec, 0, NULL);
    6791       163023 :             if (value != 0)
    6792              :               return value;
    6793              :             break;
    6794              : 
    6795       163023 :           case 'A':
    6796       163023 :             value = do_spec_1 (asm_final_spec, 0, NULL);
    6797       163023 :             if (value != 0)
    6798              :               return value;
    6799              :             break;
    6800              : 
    6801       206822 :           case 'C':
    6802       206822 :             {
    6803       108828 :               const char *const spec
    6804       206822 :                 = (input_file_compiler->cpp_spec
    6805       206822 :                    ? input_file_compiler->cpp_spec
    6806              :                    : cpp_spec);
    6807       206822 :               value = do_spec_1 (spec, 0, NULL);
    6808       206822 :               if (value != 0)
    6809              :                 return value;
    6810              :             }
    6811              :             break;
    6812              : 
    6813        94930 :           case 'E':
    6814        94930 :             value = do_spec_1 (endfile_spec, 0, NULL);
    6815        94930 :             if (value != 0)
    6816              :               return value;
    6817              :             break;
    6818              : 
    6819        95135 :           case 'l':
    6820        95135 :             value = do_spec_1 (link_spec, 0, NULL);
    6821        95135 :             if (value != 0)
    6822              :               return value;
    6823              :             break;
    6824              : 
    6825       184363 :           case 'L':
    6826       184363 :             value = do_spec_1 (lib_spec, 0, NULL);
    6827       184363 :             if (value != 0)
    6828              :               return value;
    6829              :             break;
    6830              : 
    6831            0 :           case 'M':
    6832            0 :             if (multilib_os_dir == NULL)
    6833            0 :               obstack_1grow (&obstack, '.');
    6834              :             else
    6835            0 :               obstack_grow (&obstack, multilib_os_dir,
    6836              :                             strlen (multilib_os_dir));
    6837              :             break;
    6838              : 
    6839       368534 :           case 'G':
    6840       368534 :             value = do_spec_1 (libgcc_spec, 0, NULL);
    6841       368534 :             if (value != 0)
    6842              :               return value;
    6843              :             break;
    6844              : 
    6845            0 :           case 'R':
    6846              :             /* We assume there is a directory
    6847              :                separator at the end of this string.  */
    6848            0 :             if (target_system_root)
    6849              :               {
    6850            0 :                 obstack_grow (&obstack, target_system_root,
    6851              :                               strlen (target_system_root));
    6852            0 :                 if (target_sysroot_suffix)
    6853            0 :                   obstack_grow (&obstack, target_sysroot_suffix,
    6854              :                                 strlen (target_sysroot_suffix));
    6855              :               }
    6856              :             break;
    6857              : 
    6858        94930 :           case 'S':
    6859        94930 :             value = do_spec_1 (startfile_spec, 0, NULL);
    6860        94930 :             if (value != 0)
    6861              :               return value;
    6862              :             break;
    6863              : 
    6864              :             /* Here we define characters other than letters and digits.  */
    6865              : 
    6866     40043361 :           case '{':
    6867     40043361 :             p = handle_braces (p);
    6868     40043361 :             if (p == 0)
    6869              :               return -1;
    6870              :             break;
    6871              : 
    6872       437764 :           case ':':
    6873       437764 :             p = handle_spec_function (p, NULL, soft_matched_part);
    6874       437764 :             if (p == 0)
    6875              :               return -1;
    6876              :             break;
    6877              : 
    6878            0 :           case '%':
    6879            0 :             obstack_1grow (&obstack, '%');
    6880            0 :             break;
    6881              : 
    6882              :           case '.':
    6883              :             {
    6884              :               unsigned len = 0;
    6885              : 
    6886        11898 :               while (p[len] && p[len] != ' ' && p[len] != '%')
    6887         5967 :                 len++;
    6888         5931 :               suffix_subst = save_string (p - 1, len + 1);
    6889         5931 :               p += len;
    6890              :             }
    6891         5931 :            break;
    6892              : 
    6893              :            /* Henceforth ignore the option(s) matching the pattern
    6894              :               after the %<.  */
    6895      1475857 :           case '<':
    6896      1475857 :           case '>':
    6897      1475857 :             {
    6898      1475857 :               unsigned len = 0;
    6899      1475857 :               int have_wildcard = 0;
    6900      1475857 :               int i;
    6901      1475857 :               int switch_option;
    6902              : 
    6903      1475857 :               if (c == '>')
    6904      1475857 :                 switch_option = SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC;
    6905              :               else
    6906      1475835 :                 switch_option = SWITCH_IGNORE;
    6907              : 
    6908     17852597 :               while (p[len] && p[len] != ' ' && p[len] != '\t')
    6909     16376740 :                 len++;
    6910              : 
    6911      1475857 :               if (p[len-1] == '*')
    6912        14679 :                 have_wildcard = 1;
    6913              : 
    6914     35249257 :               for (i = 0; i < n_switches; i++)
    6915     33773400 :                 if (!strncmp (switches[i].part1, p, len - have_wildcard)
    6916        45662 :                     && (have_wildcard || switches[i].part1[len] == '\0'))
    6917              :                   {
    6918        45393 :                     switches[i].live_cond |= switch_option;
    6919              :                     /* User switch be validated from validate_all_switches.
    6920              :                        when the definition is seen from the spec file.
    6921              :                        If not defined anywhere, will be rejected.  */
    6922        45393 :                     if (switches[i].known)
    6923        45393 :                       switches[i].validated = true;
    6924              :                   }
    6925              : 
    6926              :               p += len;
    6927              :             }
    6928              :             break;
    6929              : 
    6930         6803 :           case '*':
    6931         6803 :             if (soft_matched_part)
    6932              :               {
    6933         6803 :                 if (soft_matched_part[0])
    6934          326 :                   do_spec_1 (soft_matched_part, 1, NULL);
    6935              :                 /* Only insert a space after the substitution if it is at the
    6936              :                    end of the current sequence.  So if:
    6937              : 
    6938              :                      "%{foo=*:bar%*}%{foo=*:one%*two}"
    6939              : 
    6940              :                    matches -foo=hello then it will produce:
    6941              : 
    6942              :                      barhello onehellotwo
    6943              :                 */
    6944         6803 :                 if (*p == 0 || *p == '}')
    6945         6803 :                   do_spec_1 (" ", 0, NULL);
    6946              :               }
    6947              :             else
    6948              :               /* Catch the case where a spec string contains something like
    6949              :                  '%{foo:%*}'.  i.e. there is no * in the pattern on the left
    6950              :                  hand side of the :.  */
    6951            0 :               error ("spec failure: %<%%*%> has not been initialized by pattern match");
    6952              :             break;
    6953              : 
    6954              :             /* Process a string found as the value of a spec given by name.
    6955              :                This feature allows individual machine descriptions
    6956              :                to add and use their own specs.  */
    6957              :           case '(':
    6958              :             {
    6959     33166178 :               const char *name = p;
    6960              :               struct spec_list *sl;
    6961              :               int len;
    6962              : 
    6963              :               /* The string after the S/P is the name of a spec that is to be
    6964              :                  processed.  */
    6965     33166178 :               while (*p && *p != ')')
    6966     30607054 :                 p++;
    6967              : 
    6968              :               /* See if it's in the list.  */
    6969     35110481 :               for (len = p - name, sl = specs; sl; sl = sl->next)
    6970     35110481 :                 if (sl->name_len == len && !strncmp (sl->name, name, len))
    6971              :                   {
    6972      2559124 :                     name = *(sl->ptr_spec);
    6973              : #ifdef DEBUG_SPECS
    6974              :                     fnotice (stderr, "Processing spec (%s), which is '%s'\n",
    6975              :                              sl->name, name);
    6976              : #endif
    6977      2559124 :                     break;
    6978              :                   }
    6979              : 
    6980      2559124 :               if (sl)
    6981              :                 {
    6982      2559124 :                   value = do_spec_1 (name, 0, NULL);
    6983      2559124 :                   if (value != 0)
    6984              :                     return value;
    6985              :                 }
    6986              : 
    6987              :               /* Discard the closing paren.  */
    6988      2553831 :               if (*p)
    6989      2553831 :                 p++;
    6990              :             }
    6991              :             break;
    6992              : 
    6993            9 :           case '"':
    6994              :             /* End a previous argument, if there is one, then issue an
    6995              :                empty argument.  */
    6996            9 :             end_going_arg ();
    6997            9 :             arg_going = 1;
    6998            9 :             end_going_arg ();
    6999            9 :             break;
    7000              : 
    7001            0 :           default:
    7002            0 :             error ("spec failure: unrecognized spec option %qc", c);
    7003            0 :             break;
    7004              :           }
    7005              :         break;
    7006              : 
    7007            0 :       case '\\':
    7008              :         /* Backslash: treat next character as ordinary.  */
    7009            0 :         c = *p++;
    7010              : 
    7011              :         /* When adding more cases that previously matched default, make
    7012              :            sure to adjust quote_spec_char_p as well.  */
    7013              : 
    7014              :         /* Fall through.  */
    7015    361860701 :       default:
    7016              :         /* Ordinary character: put it into the current argument.  */
    7017    361860701 :         obstack_1grow (&obstack, c);
    7018    361860701 :         arg_going = 1;
    7019              :       }
    7020              : 
    7021              :   /* End of string.  If we are processing a spec function, we need to
    7022              :      end any pending argument.  */
    7023     52791301 :   if (processing_spec_function)
    7024      4494065 :     end_going_arg ();
    7025              : 
    7026              :   return 0;
    7027              : }
    7028              : 
    7029              : /* Look up a spec function.  */
    7030              : 
    7031              : static const struct spec_function *
    7032      2071457 : lookup_spec_function (const char *name)
    7033              : {
    7034      2071457 :   const struct spec_function *sf;
    7035              : 
    7036     24842127 :   for (sf = static_spec_functions; sf->name != NULL; sf++)
    7037     24842127 :     if (strcmp (sf->name, name) == 0)
    7038              :       return sf;
    7039              : 
    7040              :   return NULL;
    7041              : }
    7042              : 
    7043              : /* Evaluate a spec function.  */
    7044              : 
    7045              : static const char *
    7046      2071457 : eval_spec_function (const char *func, const char *args,
    7047              :                     const char *soft_matched_part)
    7048              : {
    7049      2071457 :   const struct spec_function *sf;
    7050      2071457 :   const char *funcval;
    7051              : 
    7052              :   /* Saved spec processing context.  */
    7053      2071457 :   vec<const_char_p> save_argbuf;
    7054              : 
    7055      2071457 :   int save_arg_going;
    7056      2071457 :   int save_delete_this_arg;
    7057      2071457 :   int save_this_is_output_file;
    7058      2071457 :   int save_this_is_library_file;
    7059      2071457 :   int save_input_from_pipe;
    7060      2071457 :   int save_this_is_linker_script;
    7061      2071457 :   const char *save_suffix_subst;
    7062              : 
    7063      2071457 :   int save_growing_size;
    7064      2071457 :   void *save_growing_value = NULL;
    7065              : 
    7066      2071457 :   sf = lookup_spec_function (func);
    7067      2071457 :   if (sf == NULL)
    7068            0 :     fatal_error (input_location, "unknown spec function %qs", func);
    7069              : 
    7070              :   /* Push the spec processing context.  */
    7071      2071457 :   save_argbuf = argbuf;
    7072              : 
    7073      2071457 :   save_arg_going = arg_going;
    7074      2071457 :   save_delete_this_arg = delete_this_arg;
    7075      2071457 :   save_this_is_output_file = this_is_output_file;
    7076      2071457 :   save_this_is_library_file = this_is_library_file;
    7077      2071457 :   save_this_is_linker_script = this_is_linker_script;
    7078      2071457 :   save_input_from_pipe = input_from_pipe;
    7079      2071457 :   save_suffix_subst = suffix_subst;
    7080              : 
    7081              :   /* If we have some object growing now, finalize it so the args and function
    7082              :      eval proceed from a cleared context.  This is needed to prevent the first
    7083              :      constructed arg from mistakenly including the growing value.  We'll push
    7084              :      this value back on the obstack once the function evaluation is done, to
    7085              :      restore a consistent processing context for our caller.  This is fine as
    7086              :      the address of growing objects isn't guaranteed to remain stable until
    7087              :      they are finalized, and we expect this situation to be rare enough for
    7088              :      the extra copy not to be an issue.  */
    7089      2071457 :   save_growing_size = obstack_object_size (&obstack);
    7090      2071457 :   if (save_growing_size > 0)
    7091        42398 :     save_growing_value = obstack_finish (&obstack);
    7092              : 
    7093              :   /* Create a new spec processing context, and build the function
    7094              :      arguments.  */
    7095              : 
    7096      2071457 :   alloc_args ();
    7097      2071457 :   if (do_spec_2 (args, soft_matched_part) < 0)
    7098            0 :     fatal_error (input_location, "error in arguments to spec function %qs",
    7099              :                  func);
    7100              : 
    7101              :   /* argbuf_index is an index for the next argument to be inserted, and
    7102              :      so contains the count of the args already inserted.  */
    7103              : 
    7104      6214371 :   funcval = (*sf->func) (argbuf.length (),
    7105              :                          argbuf.address ());
    7106              : 
    7107              :   /* Pop the spec processing context.  */
    7108      2071457 :   argbuf.release ();
    7109      2071457 :   argbuf = save_argbuf;
    7110              : 
    7111      2071457 :   arg_going = save_arg_going;
    7112      2071457 :   delete_this_arg = save_delete_this_arg;
    7113      2071457 :   this_is_output_file = save_this_is_output_file;
    7114      2071457 :   this_is_library_file = save_this_is_library_file;
    7115      2071457 :   this_is_linker_script = save_this_is_linker_script;
    7116      2071457 :   input_from_pipe = save_input_from_pipe;
    7117      2071457 :   suffix_subst = save_suffix_subst;
    7118              : 
    7119      2071457 :   if (save_growing_size > 0)
    7120        42398 :     obstack_grow (&obstack, save_growing_value, save_growing_size);
    7121              : 
    7122      2071457 :   return funcval;
    7123              : }
    7124              : 
    7125              : /* Handle a spec function call of the form:
    7126              : 
    7127              :    %:function(args)
    7128              : 
    7129              :    ARGS is processed as a spec in a separate context and split into an
    7130              :    argument vector in the normal fashion.  The function returns a string
    7131              :    containing a spec which we then process in the caller's context, or
    7132              :    NULL if no processing is required.
    7133              : 
    7134              :    If RETVAL_NONNULL is not NULL, then store a bool whether function
    7135              :    returned non-NULL.
    7136              : 
    7137              :    SOFT_MATCHED_PART holds the current value of a matched * pattern, which
    7138              :    may be re-expanded with a %* as part of the function arguments.  */
    7139              : 
    7140              : static const char *
    7141      2071457 : handle_spec_function (const char *p, bool *retval_nonnull,
    7142              :                       const char *soft_matched_part)
    7143              : {
    7144      2071457 :   char *func, *args;
    7145      2071457 :   const char *endp, *funcval;
    7146      2071457 :   int count;
    7147              : 
    7148      2071457 :   processing_spec_function++;
    7149              : 
    7150              :   /* Get the function name.  */
    7151     19209159 :   for (endp = p; *endp != '\0'; endp++)
    7152              :     {
    7153     19209159 :       if (*endp == '(')         /* ) */
    7154              :         break;
    7155              :       /* Only allow [A-Za-z0-9], -, and _ in function names.  */
    7156     17137702 :       if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
    7157            0 :         fatal_error (input_location, "malformed spec function name");
    7158              :     }
    7159      2071457 :   if (*endp != '(')             /* ) */
    7160            0 :     fatal_error (input_location, "no arguments for spec function");
    7161      2071457 :   func = save_string (p, endp - p);
    7162      2071457 :   p = ++endp;
    7163              : 
    7164              :   /* Get the arguments.  */
    7165     25385896 :   for (count = 0; *endp != '\0'; endp++)
    7166              :     {
    7167              :       /* ( */
    7168     25385896 :       if (*endp == ')')
    7169              :         {
    7170      2160892 :           if (count == 0)
    7171              :             break;
    7172        89435 :           count--;
    7173              :         }
    7174     23225004 :       else if (*endp == '(')    /* ) */
    7175        89435 :         count++;
    7176              :     }
    7177              :   /* ( */
    7178      2071457 :   if (*endp != ')')
    7179            0 :     fatal_error (input_location, "malformed spec function arguments");
    7180      2071457 :   args = save_string (p, endp - p);
    7181      2071457 :   p = ++endp;
    7182              : 
    7183              :   /* p now points to just past the end of the spec function expression.  */
    7184              : 
    7185      2071457 :   funcval = eval_spec_function (func, args, soft_matched_part);
    7186      2071457 :   if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
    7187              :     p = NULL;
    7188      2071457 :   if (retval_nonnull)
    7189      1633693 :     *retval_nonnull = funcval != NULL;
    7190              : 
    7191      2071457 :   free (func);
    7192      2071457 :   free (args);
    7193              : 
    7194      2071457 :   processing_spec_function--;
    7195              : 
    7196      2071457 :   return p;
    7197              : }
    7198              : 
    7199              : /* Inline subroutine of handle_braces.  Returns true if the current
    7200              :    input suffix matches the atom bracketed by ATOM and END_ATOM.  */
    7201              : static inline bool
    7202            0 : input_suffix_matches (const char *atom, const char *end_atom)
    7203              : {
    7204            0 :   return (input_suffix
    7205            0 :           && !strncmp (input_suffix, atom, end_atom - atom)
    7206            0 :           && input_suffix[end_atom - atom] == '\0');
    7207              : }
    7208              : 
    7209              : /* Subroutine of handle_braces.  Returns true if the current
    7210              :    input file's spec name matches the atom bracketed by ATOM and END_ATOM.  */
    7211              : static bool
    7212            0 : input_spec_matches (const char *atom, const char *end_atom)
    7213              : {
    7214            0 :   return (input_file_compiler
    7215            0 :           && input_file_compiler->suffix
    7216            0 :           && input_file_compiler->suffix[0] != '\0'
    7217            0 :           && !strncmp (input_file_compiler->suffix + 1, atom,
    7218            0 :                        end_atom - atom)
    7219            0 :           && input_file_compiler->suffix[end_atom - atom + 1] == '\0');
    7220              : }
    7221              : 
    7222              : /* Subroutine of handle_braces.  Returns true if a switch
    7223              :    matching the atom bracketed by ATOM and END_ATOM appeared on the
    7224              :    command line.  */
    7225              : static bool
    7226     38489559 : switch_matches (const char *atom, const char *end_atom, int starred)
    7227              : {
    7228     38489559 :   int i;
    7229     38489559 :   int len = end_atom - atom;
    7230     38489559 :   int plen = starred ? len : -1;
    7231              : 
    7232    906708001 :   for (i = 0; i < n_switches; i++)
    7233    869592886 :     if (!strncmp (switches[i].part1, atom, len)
    7234      2323625 :         && (starred || switches[i].part1[len] == '\0')
    7235    870967947 :         && check_live_switch (i, plen))
    7236              :       return true;
    7237              : 
    7238              :     /* Check if a switch with separated form matching the atom.
    7239              :        We check -D and -U switches. */
    7240    868218443 :     else if (switches[i].args != 0)
    7241              :       {
    7242    200506771 :         if ((*switches[i].part1 == 'D' || *switches[i].part1 == 'U')
    7243      8265160 :             && *switches[i].part1 == atom[0])
    7244              :           {
    7245            1 :             if (!strncmp (switches[i].args[0], &atom[1], len - 1)
    7246            1 :                 && (starred || (switches[i].part1[1] == '\0'
    7247            1 :                                 && switches[i].args[0][len - 1] == '\0'))
    7248            2 :                 && check_live_switch (i, (starred ? 1 : -1)))
    7249              :               return true;
    7250              :           }
    7251              :       }
    7252              : 
    7253              :   return false;
    7254              : }
    7255              : 
    7256              : /* Inline subroutine of handle_braces.  Mark all of the switches which
    7257              :    match ATOM (extends to END_ATOM; STARRED indicates whether there
    7258              :    was a star after the atom) for later processing.  */
    7259              : static inline void
    7260     11162315 : mark_matching_switches (const char *atom, const char *end_atom, int starred)
    7261              : {
    7262     11162315 :   int i;
    7263     11162315 :   int len = end_atom - atom;
    7264     11162315 :   int plen = starred ? len : -1;
    7265              : 
    7266    266843030 :   for (i = 0; i < n_switches; i++)
    7267    255680715 :     if (!strncmp (switches[i].part1, atom, len)
    7268      6374726 :         && (starred || switches[i].part1[len] == '\0')
    7269    261836059 :         && check_live_switch (i, plen))
    7270      6109961 :       switches[i].ordering = 1;
    7271     11162315 : }
    7272              : 
    7273              : /* Inline subroutine of handle_braces.  Process all the currently
    7274              :    marked switches through give_switch, and clear the marks.  */
    7275              : static inline void
    7276      9688913 : process_marked_switches (void)
    7277              : {
    7278      9688913 :   int i;
    7279              : 
    7280    231572006 :   for (i = 0; i < n_switches; i++)
    7281    221883093 :     if (switches[i].ordering == 1)
    7282              :       {
    7283      6109961 :         switches[i].ordering = 0;
    7284      6109961 :         give_switch (i, 0);
    7285              :       }
    7286      9688913 : }
    7287              : 
    7288              : /* Handle a %{ ... } construct.  P points just inside the leading {.
    7289              :    Returns a pointer one past the end of the brace block, or 0
    7290              :    if we call do_spec_1 and that returns -1.  */
    7291              : 
    7292              : static const char *
    7293     40520574 : handle_braces (const char *p)
    7294              : {
    7295     40520574 :   const char *atom, *end_atom;
    7296     40520574 :   const char *d_atom = NULL, *d_end_atom = NULL;
    7297     40520574 :   char *esc_buf = NULL, *d_esc_buf = NULL;
    7298     40520574 :   int esc;
    7299     40520574 :   const char *orig = p;
    7300              : 
    7301     40520574 :   bool a_is_suffix;
    7302     40520574 :   bool a_is_spectype;
    7303     40520574 :   bool a_is_starred;
    7304     40520574 :   bool a_is_negated;
    7305     40520574 :   bool a_matched;
    7306              : 
    7307     40520574 :   bool a_must_be_last = false;
    7308     40520574 :   bool ordered_set    = false;
    7309     40520574 :   bool disjunct_set   = false;
    7310     40520574 :   bool disj_matched   = false;
    7311     40520574 :   bool disj_starred   = true;
    7312     40520574 :   bool n_way_choice   = false;
    7313     40520574 :   bool n_way_matched  = false;
    7314              : 
    7315              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    7316              : 
    7317     53861998 :   do
    7318              :     {
    7319     53861998 :       if (a_must_be_last)
    7320            0 :         goto invalid;
    7321              : 
    7322              :       /* Scan one "atom" (S in the description above of %{}, possibly
    7323              :          with '!', '.', '@', ',', or '*' modifiers).  */
    7324     53861998 :       a_matched = false;
    7325     53861998 :       a_is_suffix = false;
    7326     53861998 :       a_is_starred = false;
    7327     53861998 :       a_is_negated = false;
    7328     53861998 :       a_is_spectype = false;
    7329              : 
    7330     61367530 :       SKIP_WHITE ();
    7331     53861998 :       if (*p == '!')
    7332     13032849 :         p++, a_is_negated = true;
    7333              : 
    7334     53861998 :       SKIP_WHITE ();
    7335     53861998 :       if (*p == '%' && p[1] == ':')
    7336              :         {
    7337      1633693 :           atom = NULL;
    7338      1633693 :           end_atom = NULL;
    7339      1633693 :           p = handle_spec_function (p + 2, &a_matched, NULL);
    7340              :         }
    7341              :       else
    7342              :         {
    7343     52228305 :           if (*p == '.')
    7344            0 :             p++, a_is_suffix = true;
    7345     52228305 :           else if (*p == ',')
    7346            0 :             p++, a_is_spectype = true;
    7347              : 
    7348     52228305 :           atom = p;
    7349     52228305 :           esc = 0;
    7350     52228305 :           while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    7351    393816702 :                  || *p == ',' || *p == '.' || *p == '@' || *p == '\\')
    7352              :             {
    7353    341588397 :               if (*p == '\\')
    7354              :                 {
    7355            0 :                   p++;
    7356            0 :                   if (!*p)
    7357            0 :                     fatal_error (input_location,
    7358              :                                  "braced spec %qs ends in escape", orig);
    7359            0 :                   esc++;
    7360              :                 }
    7361    341588397 :               p++;
    7362              :             }
    7363     52228305 :           end_atom = p;
    7364              : 
    7365     52228305 :           if (esc)
    7366              :             {
    7367            0 :               const char *ap;
    7368            0 :               char *ep;
    7369              : 
    7370            0 :               if (esc_buf && esc_buf != d_esc_buf)
    7371            0 :                 free (esc_buf);
    7372            0 :               esc_buf = NULL;
    7373            0 :               ep = esc_buf = (char *) xmalloc (end_atom - atom - esc + 1);
    7374            0 :               for (ap = atom; ap != end_atom; ap++, ep++)
    7375              :                 {
    7376            0 :                   if (*ap == '\\')
    7377            0 :                     ap++;
    7378            0 :                   *ep = *ap;
    7379              :                 }
    7380            0 :               *ep = '\0';
    7381            0 :               atom = esc_buf;
    7382            0 :               end_atom = ep;
    7383              :             }
    7384              : 
    7385     52228305 :           if (*p == '*')
    7386     11798157 :             p++, a_is_starred = 1;
    7387              :         }
    7388              : 
    7389     53861998 :       SKIP_WHITE ();
    7390     53861998 :       switch (*p)
    7391              :         {
    7392     11162315 :         case '&': case '}':
    7393              :           /* Substitute the switch(es) indicated by the current atom.  */
    7394     11162315 :           ordered_set = true;
    7395     11162315 :           if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
    7396     11162315 :               || a_is_spectype || atom == end_atom)
    7397            0 :             goto invalid;
    7398              : 
    7399     11162315 :           mark_matching_switches (atom, end_atom, a_is_starred);
    7400              : 
    7401     11162315 :           if (*p == '}')
    7402      9688913 :             process_marked_switches ();
    7403              :           break;
    7404              : 
    7405     42699683 :         case '|': case ':':
    7406              :           /* Substitute some text if the current atom appears as a switch
    7407              :              or suffix.  */
    7408     42699683 :           disjunct_set = true;
    7409     42699683 :           if (ordered_set)
    7410            0 :             goto invalid;
    7411              : 
    7412     42699683 :           if (atom && atom == end_atom)
    7413              :             {
    7414      1762975 :               if (!n_way_choice || disj_matched || *p == '|'
    7415      1762975 :                   || a_is_negated || a_is_suffix || a_is_spectype
    7416      1762975 :                   || a_is_starred)
    7417            0 :                 goto invalid;
    7418              : 
    7419              :               /* An empty term may appear as the last choice of an
    7420              :                  N-way choice set; it means "otherwise".  */
    7421      1762975 :               a_must_be_last = true;
    7422      1762975 :               disj_matched = !n_way_matched;
    7423      1762975 :               disj_starred = false;
    7424              :             }
    7425              :           else
    7426              :             {
    7427     40936708 :               if ((a_is_suffix || a_is_spectype) && a_is_starred)
    7428            0 :                 goto invalid;
    7429              : 
    7430     40936708 :               if (!a_is_starred)
    7431     35346379 :                 disj_starred = false;
    7432              : 
    7433              :               /* Don't bother testing this atom if we already have a
    7434              :                  match.  */
    7435     40936708 :               if (!disj_matched && !n_way_matched)
    7436              :                 {
    7437     39924373 :                   if (atom == NULL)
    7438              :                     /* a_matched is already set by handle_spec_function.  */;
    7439     38394420 :                   else if (a_is_suffix)
    7440            0 :                     a_matched = input_suffix_matches (atom, end_atom);
    7441     38394420 :                   else if (a_is_spectype)
    7442            0 :                     a_matched = input_spec_matches (atom, end_atom);
    7443              :                   else
    7444     38394420 :                     a_matched = switch_matches (atom, end_atom, a_is_starred);
    7445              : 
    7446     39924373 :                   if (a_matched != a_is_negated)
    7447              :                     {
    7448     12908201 :                       disj_matched = true;
    7449     12908201 :                       d_atom = atom;
    7450     12908201 :                       d_end_atom = end_atom;
    7451     12908201 :                       d_esc_buf = esc_buf;
    7452              :                     }
    7453              :                 }
    7454              :             }
    7455              : 
    7456     42699683 :           if (*p == ':')
    7457              :             {
    7458              :               /* Found the body, that is, the text to substitute if the
    7459              :                  current disjunction matches.  */
    7460     67638230 :               p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
    7461     33819115 :                                       disj_matched && !n_way_matched);
    7462     33819115 :               if (p == 0)
    7463        35163 :                 goto done;
    7464              : 
    7465              :               /* If we have an N-way choice, reset state for the next
    7466              :                  disjunction.  */
    7467     33783952 :               if (*p == ';')
    7468              :                 {
    7469      2987454 :                   n_way_choice = true;
    7470      2987454 :                   n_way_matched |= disj_matched;
    7471      2987454 :                   disj_matched = false;
    7472      2987454 :                   disj_starred = true;
    7473      2987454 :                   d_atom = d_end_atom = NULL;
    7474              :                 }
    7475              :             }
    7476              :           break;
    7477              : 
    7478            0 :         default:
    7479            0 :           goto invalid;
    7480              :         }
    7481              :     }
    7482     53826835 :   while (*p++ != '}');
    7483              : 
    7484     40485411 :  done:
    7485     40520574 :   if (d_esc_buf && d_esc_buf != esc_buf)
    7486            0 :     free (d_esc_buf);
    7487     40520574 :   if (esc_buf)
    7488            0 :     free (esc_buf);
    7489              : 
    7490     40520574 :   return p;
    7491              : 
    7492            0 :  invalid:
    7493            0 :   fatal_error (input_location, "braced spec %qs is invalid at %qc", orig, *p);
    7494              : 
    7495              : #undef SKIP_WHITE
    7496              : }
    7497              : 
    7498              : /* Subroutine of handle_braces.  Scan and process a brace substitution body
    7499              :    (X in the description of %{} syntax).  P points one past the colon;
    7500              :    ATOM and END_ATOM bracket the first atom which was found to be true
    7501              :    (present) in the current disjunction; STARRED indicates whether all
    7502              :    the atoms in the current disjunction were starred (for syntax validation);
    7503              :    MATCHED indicates whether the disjunction matched or not, and therefore
    7504              :    whether or not the body is to be processed through do_spec_1 or just
    7505              :    skipped.  Returns a pointer to the closing } or ;, or 0 if do_spec_1
    7506              :    returns -1.  */
    7507              : 
    7508              : static const char *
    7509     33819115 : process_brace_body (const char *p, const char *atom, const char *end_atom,
    7510              :                     int starred, int matched)
    7511              : {
    7512     33819115 :   const char *body, *end_body;
    7513     33819115 :   unsigned int nesting_level;
    7514     33819115 :   bool have_subst     = false;
    7515              : 
    7516              :   /* Locate the closing } or ;, honoring nested braces.
    7517              :      Trim trailing whitespace.  */
    7518     33819115 :   body = p;
    7519     33819115 :   nesting_level = 1;
    7520  11422289671 :   for (;;)
    7521              :     {
    7522   5728054393 :       if (*p == '{')
    7523    170793672 :         nesting_level++;
    7524   5557260721 :       else if (*p == '}')
    7525              :         {
    7526    201625333 :           if (!--nesting_level)
    7527              :             break;
    7528              :         }
    7529   5355635388 :       else if (*p == ';' && nesting_level == 1)
    7530              :         break;
    7531   5352647934 :       else if (*p == '%' && p[1] == '*' && nesting_level == 1)
    7532              :         have_subst = true;
    7533   5351859098 :       else if (*p == '\0')
    7534            0 :         goto invalid;
    7535   5694235278 :       p++;
    7536              :     }
    7537              : 
    7538              :   end_body = p;
    7539     36588077 :   while (end_body[-1] == ' ' || end_body[-1] == '\t')
    7540      2768962 :     end_body--;
    7541              : 
    7542     33819115 :   if (have_subst && !starred)
    7543            0 :     goto invalid;
    7544              : 
    7545     33819115 :   if (matched)
    7546              :     {
    7547              :       /* Copy the substitution body to permanent storage and execute it.
    7548              :          If have_subst is false, this is a simple matter of running the
    7549              :          body through do_spec_1...  */
    7550     13859594 :       char *string = save_string (body, end_body - body);
    7551     13859594 :       if (!have_subst)
    7552              :         {
    7553     13852795 :           if (do_spec_1 (string, 0, NULL) < 0)
    7554              :             {
    7555        35163 :               free (string);
    7556        35163 :               return 0;
    7557              :             }
    7558              :         }
    7559              :       else
    7560              :         {
    7561              :           /* ... but if have_subst is true, we have to process the
    7562              :              body once for each matching switch, with %* set to the
    7563              :              variant part of the switch.  */
    7564         6799 :           unsigned int hard_match_len = end_atom - atom;
    7565         6799 :           int i;
    7566              : 
    7567       274144 :           for (i = 0; i < n_switches; i++)
    7568       267345 :             if (!strncmp (switches[i].part1, atom, hard_match_len)
    7569       267345 :                 && check_live_switch (i, hard_match_len))
    7570              :               {
    7571         6803 :                 if (do_spec_1 (string, 0,
    7572              :                                &switches[i].part1[hard_match_len]) < 0)
    7573              :                   {
    7574            0 :                     free (string);
    7575            0 :                     return 0;
    7576              :                   }
    7577              :                 /* Pass any arguments this switch has.  */
    7578         6803 :                 give_switch (i, 1);
    7579         6803 :                 suffix_subst = NULL;
    7580              :               }
    7581              :         }
    7582     13824431 :       free (string);
    7583              :     }
    7584              : 
    7585              :   return p;
    7586              : 
    7587            0 :  invalid:
    7588            0 :   fatal_error (input_location, "braced spec body %qs is invalid", body);
    7589              : }
    7590              : 
    7591              : /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
    7592              :    on the command line.  PREFIX_LENGTH is the length of XXX in an {XXX*}
    7593              :    spec, or -1 if either exact match or %* is used.
    7594              : 
    7595              :    A -O switch is obsoleted by a later -O switch.  A -f, -g, -m, or -W switch
    7596              :    whose value does not begin with "no-" is obsoleted by the same value
    7597              :    with the "no-", similarly for a switch with the "no-" prefix.  */
    7598              : 
    7599              : static int
    7600      7537209 : check_live_switch (int switchnum, int prefix_length)
    7601              : {
    7602      7537209 :   const char *name = switches[switchnum].part1;
    7603      7537209 :   int i;
    7604              : 
    7605              :   /* If we already processed this switch and determined if it was
    7606              :      live or not, return our past determination.  */
    7607      7537209 :   if (switches[switchnum].live_cond != 0)
    7608       948476 :     return ((switches[switchnum].live_cond & SWITCH_LIVE) != 0
    7609       902493 :             && (switches[switchnum].live_cond & SWITCH_FALSE) == 0
    7610      1850969 :             && (switches[switchnum].live_cond & SWITCH_IGNORE_PERMANENTLY)
    7611       948476 :                == 0);
    7612              : 
    7613              :   /* In the common case of {<at-most-one-letter>*}, a negating
    7614              :      switch would always match, so ignore that case.  We will just
    7615              :      send the conflicting switches to the compiler phase.  */
    7616      6588733 :   if (prefix_length >= 0 && prefix_length <= 1)
    7617              :     return 1;
    7618              : 
    7619              :   /* Now search for duplicate in a manner that depends on the name.  */
    7620       899207 :   switch (*name)
    7621              :     {
    7622           62 :     case 'O':
    7623          344 :       for (i = switchnum + 1; i < n_switches; i++)
    7624          287 :         if (switches[i].part1[0] == 'O')
    7625              :           {
    7626            5 :             switches[switchnum].validated = true;
    7627            5 :             switches[switchnum].live_cond = SWITCH_FALSE;
    7628            5 :             return 0;
    7629              :           }
    7630              :       break;
    7631              : 
    7632       297730 :     case 'W':  case 'f':  case 'm': case 'g':
    7633       297730 :       if (startswith (name + 1, "no-"))
    7634              :         {
    7635              :           /* We have Xno-YYY, search for XYYY.  */
    7636        35238 :           for (i = switchnum + 1; i < n_switches; i++)
    7637        29621 :             if (switches[i].part1[0] == name[0]
    7638         5658 :                 && ! strcmp (&switches[i].part1[1], &name[4]))
    7639              :               {
    7640              :                 /* --specs are validated with the validate_switches mechanism.  */
    7641            0 :                 if (switches[switchnum].known)
    7642            0 :                   switches[switchnum].validated = true;
    7643            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7644            0 :                 return 0;
    7645              :               }
    7646              :         }
    7647              :       else
    7648              :         {
    7649              :           /* We have XYYY, search for Xno-YYY.  */
    7650      3102214 :           for (i = switchnum + 1; i < n_switches; i++)
    7651      2810101 :             if (switches[i].part1[0] == name[0]
    7652      1726433 :                 && switches[i].part1[1] == 'n'
    7653       219707 :                 && switches[i].part1[2] == 'o'
    7654       219706 :                 && switches[i].part1[3] == '-'
    7655       219676 :                 && !strcmp (&switches[i].part1[4], &name[1]))
    7656              :               {
    7657              :                 /* --specs are validated with the validate_switches mechanism.  */
    7658            0 :                 if (switches[switchnum].known)
    7659            0 :                   switches[switchnum].validated = true;
    7660            0 :                 switches[switchnum].live_cond = SWITCH_FALSE;
    7661            0 :                 return 0;
    7662              :               }
    7663              :         }
    7664              :       break;
    7665              :     }
    7666              : 
    7667              :   /* Otherwise the switch is live.  */
    7668       899202 :   switches[switchnum].live_cond |= SWITCH_LIVE;
    7669       899202 :   return 1;
    7670              : }
    7671              : 
    7672              : /* Pass a switch to the current accumulating command
    7673              :    in the same form that we received it.
    7674              :    SWITCHNUM identifies the switch; it is an index into
    7675              :    the vector of switches gcc received, which is `switches'.
    7676              :    This cannot fail since it never finishes a command line.
    7677              : 
    7678              :    If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.  */
    7679              : 
    7680              : static void
    7681      6116764 : give_switch (int switchnum, int omit_first_word)
    7682              : {
    7683      6116764 :   if ((switches[switchnum].live_cond & SWITCH_IGNORE) != 0)
    7684              :     return;
    7685              : 
    7686      6116753 :   if (!omit_first_word)
    7687              :     {
    7688      6109950 :       do_spec_1 ("-", 0, NULL);
    7689      6109950 :       do_spec_1 (switches[switchnum].part1, 1, NULL);
    7690              :     }
    7691              : 
    7692      6116753 :   if (switches[switchnum].args != 0)
    7693              :     {
    7694              :       const char **p;
    7695      2477280 :       for (p = switches[switchnum].args; *p; p++)
    7696              :         {
    7697      1238640 :           const char *arg = *p;
    7698              : 
    7699      1238640 :           do_spec_1 (" ", 0, NULL);
    7700      1238640 :           if (suffix_subst)
    7701              :             {
    7702         5931 :               unsigned length = strlen (arg);
    7703         5931 :               int dot = 0;
    7704              : 
    7705        11862 :               while (length-- && !IS_DIR_SEPARATOR (arg[length]))
    7706        11862 :                 if (arg[length] == '.')
    7707              :                   {
    7708         5931 :                     (const_cast<char *> (arg))[length] = 0;
    7709         5931 :                     dot = 1;
    7710         5931 :                     break;
    7711              :                   }
    7712         5931 :               do_spec_1 (arg, 1, NULL);
    7713         5931 :               if (dot)
    7714         5931 :                 (const_cast<char *> (arg))[length] = '.';
    7715         5931 :               do_spec_1 (suffix_subst, 1, NULL);
    7716              :             }
    7717              :           else
    7718      1232709 :             do_spec_1 (arg, 1, NULL);
    7719              :         }
    7720              :     }
    7721              : 
    7722      6116753 :   do_spec_1 (" ", 0, NULL);
    7723      6116753 :   switches[switchnum].validated = true;
    7724              : }
    7725              : 
    7726              : /* Print GCC configuration (e.g. version, thread model, target,
    7727              :    configuration_arguments) to a given FILE.  */
    7728              : 
    7729              : static void
    7730         1561 : print_configuration (FILE *file)
    7731              : {
    7732         1561 :   int n;
    7733         1561 :   const char *thrmod;
    7734              : 
    7735         1561 :   fnotice (file, "Target: %s\n", spec_machine);
    7736         1561 :   fnotice (file, "Configured with: %s\n", configuration_arguments);
    7737              : 
    7738              : #ifdef THREAD_MODEL_SPEC
    7739              :   /* We could have defined THREAD_MODEL_SPEC to "%*" by default,
    7740              :   but there's no point in doing all this processing just to get
    7741              :   thread_model back.  */
    7742              :   obstack_init (&obstack);
    7743              :   do_spec_1 (THREAD_MODEL_SPEC, 0, thread_model);
    7744              :   obstack_1grow (&obstack, '\0');
    7745              :   thrmod = XOBFINISH (&obstack, const char *);
    7746              : #else
    7747         1561 :   thrmod = thread_model;
    7748              : #endif
    7749              : 
    7750         1561 :   fnotice (file, "Thread model: %s\n", thrmod);
    7751         1561 :   fnotice (file, "Supported LTO compression algorithms: zlib");
    7752              : #ifdef HAVE_ZSTD_H
    7753         1561 :   fnotice (file, " zstd");
    7754              : #endif
    7755         1561 :   fnotice (file, "\n");
    7756              : 
    7757              :   /* compiler_version is truncated at the first space when initialized
    7758              :   from version string, so truncate version_string at the first space
    7759              :   before comparing.  */
    7760        12488 :   for (n = 0; version_string[n]; n++)
    7761        10927 :     if (version_string[n] == ' ')
    7762              :       break;
    7763              : 
    7764         1561 :   if (! strncmp (version_string, compiler_version, n)
    7765         1561 :       && compiler_version[n] == 0)
    7766         1561 :     fnotice (file, "gcc version %s %s\n", version_string,
    7767              :              pkgversion_string);
    7768              :   else
    7769            0 :     fnotice (file, "gcc driver version %s %sexecuting gcc version %s\n",
    7770              :              version_string, pkgversion_string, compiler_version);
    7771              : 
    7772         1561 : }
    7773              : 
    7774              : #define RETRY_ICE_ATTEMPTS 3
    7775              : 
    7776              : /* Returns true if FILE1 and FILE2 contain equivalent data, 0 otherwise.
    7777              :    If lines start with 0x followed by 1-16 lowercase hexadecimal digits
    7778              :    followed by a space, ignore anything before that space.  These are
    7779              :    typically function addresses from libbacktrace and those can differ
    7780              :    due to ASLR.  */
    7781              : 
    7782              : static bool
    7783            0 : files_equal_p (char *file1, char *file2)
    7784              : {
    7785            0 :   FILE *f1 = fopen (file1, "rb");
    7786            0 :   FILE *f2 = fopen (file2, "rb");
    7787            0 :   char line1[256], line2[256];
    7788              : 
    7789            0 :   bool line_start = true;
    7790            0 :   while (fgets (line1, sizeof (line1), f1))
    7791              :     {
    7792            0 :       if (!fgets (line2, sizeof (line2), f2))
    7793            0 :         goto error;
    7794            0 :       char *p1 = line1, *p2 = line2;
    7795            0 :       if (line_start
    7796            0 :           && line1[0] == '0'
    7797            0 :           && line1[1] == 'x'
    7798            0 :           && line2[0] == '0'
    7799            0 :           && line2[1] == 'x')
    7800              :         {
    7801              :           int i, j;
    7802            0 :           for (i = 0; i < 16; ++i)
    7803            0 :             if (!ISXDIGIT (line1[2 + i]) || ISUPPER (line1[2 + i]))
    7804              :               break;
    7805            0 :           for (j = 0; j < 16; ++j)
    7806            0 :             if (!ISXDIGIT (line2[2 + j]) || ISUPPER (line2[2 + j]))
    7807              :               break;
    7808            0 :           if (i && line1[2 + i] == ' ' && j && line2[2 + j] == ' ')
    7809              :             {
    7810            0 :               p1 = line1 + i + 3;
    7811            0 :               p2 = line2 + j + 3;
    7812              :             }
    7813              :         }
    7814            0 :       if (strcmp (p1, p2) != 0)
    7815            0 :         goto error;
    7816            0 :       line_start = strchr (line1, '\n') != NULL;
    7817              :     }
    7818            0 :   if (fgets (line2, sizeof (line2), f2))
    7819            0 :     goto error;
    7820              : 
    7821            0 :   fclose (f1);
    7822            0 :   fclose (f2);
    7823            0 :   return 1;
    7824              : 
    7825            0 : error:
    7826            0 :   fclose (f1);
    7827            0 :   fclose (f2);
    7828            0 :   return 0;
    7829              : }
    7830              : 
    7831              : /* Check that compiler's output doesn't differ across runs.
    7832              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are arrays of files, containing
    7833              :    stdout and stderr for each compiler run.  Return true if all of
    7834              :    TEMP_STDOUT_FILES and TEMP_STDERR_FILES are equivalent.  */
    7835              : 
    7836              : static bool
    7837            0 : check_repro (char **temp_stdout_files, char **temp_stderr_files)
    7838              : {
    7839            0 :   int i;
    7840            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS - 2; ++i)
    7841              :     {
    7842            0 :      if (!files_equal_p (temp_stdout_files[i], temp_stdout_files[i + 1])
    7843            0 :          || !files_equal_p (temp_stderr_files[i], temp_stderr_files[i + 1]))
    7844              :        {
    7845            0 :          fnotice (stderr, "The bug is not reproducible, so it is"
    7846              :                   " likely a hardware or OS problem.\n");
    7847            0 :          break;
    7848              :        }
    7849              :     }
    7850            0 :   return i == RETRY_ICE_ATTEMPTS - 2;
    7851              : }
    7852              : 
    7853              : enum attempt_status {
    7854              :   ATTEMPT_STATUS_FAIL_TO_RUN,
    7855              :   ATTEMPT_STATUS_SUCCESS,
    7856              :   ATTEMPT_STATUS_ICE
    7857              : };
    7858              : 
    7859              : 
    7860              : /* Run compiler with arguments NEW_ARGV to reproduce the ICE, storing stdout
    7861              :    to OUT_TEMP and stderr to ERR_TEMP.  If APPEND is TRUE, append to OUT_TEMP
    7862              :    and ERR_TEMP instead of truncating.  If EMIT_SYSTEM_INFO is TRUE, also write
    7863              :    GCC configuration into to ERR_TEMP.  Return ATTEMPT_STATUS_FAIL_TO_RUN if
    7864              :    compiler failed to run, ATTEMPT_STATUS_ICE if compiled ICE-ed and
    7865              :    ATTEMPT_STATUS_SUCCESS otherwise.  */
    7866              : 
    7867              : static enum attempt_status
    7868            0 : run_attempt (const char **new_argv, const char *out_temp,
    7869              :              const char *err_temp, int emit_system_info, int append)
    7870              : {
    7871              : 
    7872            0 :   if (emit_system_info)
    7873              :     {
    7874            0 :       FILE *file_out = fopen (err_temp, "a");
    7875            0 :       print_configuration (file_out);
    7876            0 :       fputs ("\n", file_out);
    7877            0 :       fclose (file_out);
    7878              :     }
    7879              : 
    7880            0 :   int exit_status;
    7881            0 :   const char *errmsg;
    7882            0 :   struct pex_obj *pex;
    7883            0 :   int err;
    7884            0 :   int pex_flags = PEX_USE_PIPES | PEX_LAST;
    7885            0 :   enum attempt_status status = ATTEMPT_STATUS_FAIL_TO_RUN;
    7886              : 
    7887            0 :   if (append)
    7888            0 :     pex_flags |= PEX_STDOUT_APPEND | PEX_STDERR_APPEND;
    7889              : 
    7890            0 :   pex = pex_init (PEX_USE_PIPES, new_argv[0], NULL);
    7891            0 :   if (!pex)
    7892              :     fatal_error (input_location, "%<pex_init%> failed: %m");
    7893              : 
    7894            0 :   errmsg = pex_run (pex, pex_flags, new_argv[0],
    7895            0 :                     const_cast<char *const *> (&new_argv[1]),
    7896              :                     out_temp, err_temp, &err);
    7897            0 :   if (errmsg != NULL)
    7898              :     {
    7899            0 :       errno = err;
    7900            0 :       fatal_error (input_location,
    7901              :                    err ? G_ ("cannot execute %qs: %s: %m")
    7902              :                    : G_ ("cannot execute %qs: %s"),
    7903              :                    new_argv[0], errmsg);
    7904              :     }
    7905              : 
    7906            0 :   if (!pex_get_status (pex, 1, &exit_status))
    7907            0 :     goto out;
    7908              : 
    7909            0 :   switch (WEXITSTATUS (exit_status))
    7910              :     {
    7911              :       case ICE_EXIT_CODE:
    7912            0 :         status = ATTEMPT_STATUS_ICE;
    7913              :         break;
    7914              : 
    7915            0 :       case SUCCESS_EXIT_CODE:
    7916            0 :         status = ATTEMPT_STATUS_SUCCESS;
    7917            0 :         break;
    7918              : 
    7919            0 :       default:
    7920            0 :         ;
    7921              :     }
    7922              : 
    7923            0 : out:
    7924            0 :   pex_free (pex);
    7925            0 :   return status;
    7926              : }
    7927              : 
    7928              : /* This routine reads lines from IN file, adds C++ style comments
    7929              :    at the beginning of each line and writes result into OUT.  */
    7930              : 
    7931              : static void
    7932            0 : insert_comments (const char *file_in, const char *file_out)
    7933              : {
    7934            0 :   FILE *in = fopen (file_in, "rb");
    7935            0 :   FILE *out = fopen (file_out, "wb");
    7936            0 :   char line[256];
    7937              : 
    7938            0 :   bool add_comment = true;
    7939            0 :   while (fgets (line, sizeof (line), in))
    7940              :     {
    7941            0 :       if (add_comment)
    7942            0 :         fputs ("// ", out);
    7943            0 :       fputs (line, out);
    7944            0 :       add_comment = strchr (line, '\n') != NULL;
    7945              :     }
    7946              : 
    7947            0 :   fclose (in);
    7948            0 :   fclose (out);
    7949            0 : }
    7950              : 
    7951              : /* This routine adds preprocessed source code into the given ERR_FILE.
    7952              :    To do this, it adds "-E" to NEW_ARGV and execute RUN_ATTEMPT routine to
    7953              :    add information in report file.  RUN_ATTEMPT should return
    7954              :    ATTEMPT_STATUS_SUCCESS, in other case we cannot generate the report.  */
    7955              : 
    7956              : static void
    7957            0 : do_report_bug (const char **new_argv, const int nargs,
    7958              :                char **out_file, char **err_file)
    7959              : {
    7960            0 :   int i, status;
    7961            0 :   int fd = open (*out_file, O_RDWR | O_APPEND);
    7962            0 :   if (fd < 0)
    7963              :     return;
    7964            0 :   write (fd, "\n//", 3);
    7965            0 :   for (i = 0; i < nargs; i++)
    7966              :     {
    7967            0 :       write (fd, " ", 1);
    7968            0 :       write (fd, new_argv[i], strlen (new_argv[i]));
    7969              :     }
    7970            0 :   write (fd, "\n\n", 2);
    7971            0 :   close (fd);
    7972            0 :   new_argv[nargs] = "-E";
    7973            0 :   new_argv[nargs + 1] = NULL;
    7974              : 
    7975            0 :   status = run_attempt (new_argv, *out_file, *err_file, 0, 1);
    7976              : 
    7977            0 :   if (status == ATTEMPT_STATUS_SUCCESS)
    7978              :     {
    7979            0 :       fnotice (stderr, "Preprocessed source stored into %s file,"
    7980              :                " please attach this to your bugreport.\n", *out_file);
    7981              :       /* Make sure it is not deleted.  */
    7982            0 :       free (*out_file);
    7983            0 :       *out_file = NULL;
    7984              :     }
    7985              : }
    7986              : 
    7987              : /* Try to reproduce ICE.  If bug is reproducible, generate report .err file
    7988              :    containing GCC configuration, backtrace, compiler's command line options
    7989              :    and preprocessed source code.  */
    7990              : 
    7991              : static void
    7992            0 : try_generate_repro (const char **argv)
    7993              : {
    7994            0 :   int i, nargs, out_arg = -1, quiet = 0, attempt;
    7995            0 :   const char **new_argv;
    7996            0 :   char *temp_files[RETRY_ICE_ATTEMPTS * 2];
    7997            0 :   char **temp_stdout_files = &temp_files[0];
    7998            0 :   char **temp_stderr_files = &temp_files[RETRY_ICE_ATTEMPTS];
    7999              : 
    8000            0 :   if (gcc_input_filename == NULL || ! strcmp (gcc_input_filename, "-"))
    8001            0 :     return;
    8002              : 
    8003            0 :   for (nargs = 0; argv[nargs] != NULL; ++nargs)
    8004              :     /* Only retry compiler ICEs, not preprocessor ones.  */
    8005            0 :     if (! strcmp (argv[nargs], "-E"))
    8006              :       return;
    8007            0 :     else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o')
    8008              :       {
    8009            0 :         if (out_arg == -1)
    8010              :           out_arg = nargs;
    8011              :         else
    8012              :           return;
    8013              :       }
    8014              :     /* If the compiler is going to output any time information,
    8015              :        it might varry between invocations.  */
    8016            0 :     else if (! strcmp (argv[nargs], "-quiet"))
    8017              :       quiet = 1;
    8018            0 :     else if (! strcmp (argv[nargs], "-ftime-report"))
    8019              :       return;
    8020              : 
    8021            0 :   if (out_arg == -1 || !quiet)
    8022              :     return;
    8023              : 
    8024            0 :   memset (temp_files, '\0', sizeof (temp_files));
    8025            0 :   new_argv = XALLOCAVEC (const char *, nargs + 4);
    8026            0 :   memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *));
    8027            0 :   new_argv[nargs++] = "-frandom-seed=0";
    8028            0 :   new_argv[nargs++] = "-fdump-noaddr";
    8029            0 :   new_argv[nargs] = NULL;
    8030            0 :   if (new_argv[out_arg][2] == '\0')
    8031            0 :     new_argv[out_arg + 1] = "-";
    8032              :   else
    8033            0 :     new_argv[out_arg] = "-o-";
    8034              : 
    8035              : #ifdef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
    8036            0 :   personality (personality (0xffffffffU) | ADDR_NO_RANDOMIZE);
    8037              : #endif
    8038              : 
    8039            0 :   int status;
    8040            0 :   for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS; ++attempt)
    8041              :     {
    8042            0 :       int emit_system_info = 0;
    8043            0 :       int append = 0;
    8044            0 :       temp_stdout_files[attempt] = make_temp_file (".out");
    8045            0 :       temp_stderr_files[attempt] = make_temp_file (".err");
    8046              : 
    8047            0 :       if (attempt == RETRY_ICE_ATTEMPTS - 1)
    8048              :         {
    8049            0 :           append = 1;
    8050            0 :           emit_system_info = 1;
    8051              :         }
    8052              : 
    8053            0 :       status = run_attempt (new_argv, temp_stdout_files[attempt],
    8054              :                             temp_stderr_files[attempt], emit_system_info,
    8055              :                             append);
    8056              : 
    8057            0 :       if (status != ATTEMPT_STATUS_ICE)
    8058              :         {
    8059            0 :           fnotice (stderr, "The bug is not reproducible, so it is"
    8060              :                    " likely a hardware or OS problem.\n");
    8061            0 :           goto out;
    8062              :         }
    8063              :     }
    8064              : 
    8065            0 :   if (!check_repro (temp_stdout_files, temp_stderr_files))
    8066            0 :     goto out;
    8067              : 
    8068            0 :   {
    8069              :     /* Insert commented out backtrace into report file.  */
    8070            0 :     char **stderr_commented = &temp_stdout_files[RETRY_ICE_ATTEMPTS - 1];
    8071            0 :     insert_comments (temp_stderr_files[RETRY_ICE_ATTEMPTS - 1],
    8072              :                      *stderr_commented);
    8073              : 
    8074              :     /* In final attempt we append compiler options and preprocesssed code to last
    8075              :        generated .out file with configuration and backtrace.  */
    8076            0 :     char **err = &temp_stderr_files[RETRY_ICE_ATTEMPTS - 1];
    8077            0 :     do_report_bug (new_argv, nargs, stderr_commented, err);
    8078              :   }
    8079              : 
    8080              : out:
    8081            0 :   for (i = 0; i < RETRY_ICE_ATTEMPTS * 2; i++)
    8082            0 :     if (temp_files[i])
    8083              :       {
    8084            0 :         unlink (temp_stdout_files[i]);
    8085            0 :         free (temp_stdout_files[i]);
    8086              :       }
    8087              : }
    8088              : 
    8089              : /* Search for a file named NAME trying various prefixes including the
    8090              :    user's -B prefix and some standard ones.
    8091              :    Return the absolute file name found.  If nothing is found, return NAME.  */
    8092              : 
    8093              : static const char *
    8094       544988 : find_file (const char *name)
    8095              : {
    8096       544988 :   char *newname = find_a_file (&startfile_prefixes, name, R_OK, true);
    8097       544988 :   return newname ? newname : name;
    8098              : }
    8099              : 
    8100              : /* Determine whether a directory exists.  */
    8101              : 
    8102              : static int
    8103     10369368 : is_directory (const char *path1)
    8104              : {
    8105     10369368 :   int len1;
    8106     10369368 :   char *path;
    8107     10369368 :   char *cp;
    8108     10369368 :   struct stat st;
    8109              : 
    8110              :   /* Ensure the string ends with "/.".  The resulting path will be a
    8111              :      directory even if the given path is a symbolic link.  */
    8112     10369368 :   len1 = strlen (path1);
    8113     10369368 :   path = (char *) alloca (3 + len1);
    8114     10369368 :   memcpy (path, path1, len1);
    8115     10369368 :   cp = path + len1;
    8116     10369368 :   if (!IS_DIR_SEPARATOR (cp[-1]))
    8117      1500395 :     *cp++ = DIR_SEPARATOR;
    8118     10369368 :   *cp++ = '.';
    8119     10369368 :   *cp = '\0';
    8120              : 
    8121     10369368 :   return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
    8122              : }
    8123              : 
    8124              : /* Set up the various global variables to indicate that we're processing
    8125              :    the input file named FILENAME.  */
    8126              : 
    8127              : void
    8128       836336 : set_input (const char *filename)
    8129              : {
    8130       836336 :   const char *p;
    8131              : 
    8132       836336 :   gcc_input_filename = filename;
    8133       836336 :   input_filename_length = strlen (gcc_input_filename);
    8134       836336 :   input_basename = lbasename (gcc_input_filename);
    8135              : 
    8136              :   /* Find a suffix starting with the last period,
    8137              :      and set basename_length to exclude that suffix.  */
    8138       836336 :   basename_length = strlen (input_basename);
    8139       836336 :   suffixed_basename_length = basename_length;
    8140       836336 :   p = input_basename + basename_length;
    8141      3690941 :   while (p != input_basename && *p != '.')
    8142      2854605 :     --p;
    8143       836336 :   if (*p == '.' && p != input_basename)
    8144              :     {
    8145       596875 :       basename_length = p - input_basename;
    8146       596875 :       input_suffix = p + 1;
    8147              :     }
    8148              :   else
    8149       239461 :     input_suffix = "";
    8150              : 
    8151              :   /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then
    8152              :      we will need to do a stat on the gcc_input_filename.  The
    8153              :      INPUT_STAT_SET signals that the stat is needed.  */
    8154       836336 :   input_stat_set = 0;
    8155       836336 : }
    8156              : 
    8157              : /* On fatal signals, delete all the temporary files.  */
    8158              : 
    8159              : static void
    8160            0 : fatal_signal (int signum)
    8161              : {
    8162            0 :   signal (signum, SIG_DFL);
    8163            0 :   delete_failure_queue ();
    8164            0 :   delete_temp_files ();
    8165              :   /* Get the same signal again, this time not handled,
    8166              :      so its normal effect occurs.  */
    8167            0 :   kill (getpid (), signum);
    8168            0 : }
    8169              : 
    8170              : /* Compare the contents of the two files named CMPFILE[0] and
    8171              :    CMPFILE[1].  Return zero if they're identical, nonzero
    8172              :    otherwise.  */
    8173              : 
    8174              : static int
    8175          613 : compare_files (char *cmpfile[])
    8176              : {
    8177          613 :   int ret = 0;
    8178          613 :   FILE *temp[2] = { NULL, NULL };
    8179          613 :   int i;
    8180              : 
    8181              : #if HAVE_MMAP_FILE
    8182          613 :   {
    8183          613 :     size_t length[2];
    8184          613 :     void *map[2] = { NULL, NULL };
    8185              : 
    8186         1839 :     for (i = 0; i < 2; i++)
    8187              :       {
    8188         1226 :         struct stat st;
    8189              : 
    8190         1226 :         if (stat (cmpfile[i], &st) < 0 || !S_ISREG (st.st_mode))
    8191              :           {
    8192            0 :             error ("%s: could not determine length of compare-debug file %s",
    8193              :                    gcc_input_filename, cmpfile[i]);
    8194            0 :             ret = 1;
    8195            0 :             break;
    8196              :           }
    8197              : 
    8198         1226 :         length[i] = st.st_size;
    8199              :       }
    8200              : 
    8201          613 :     if (!ret && length[0] != length[1])
    8202              :       {
    8203           14 :         error ("%s: %<-fcompare-debug%> failure (length)", gcc_input_filename);
    8204           14 :         ret = 1;
    8205              :       }
    8206              : 
    8207           14 :     if (!ret)
    8208         1735 :       for (i = 0; i < 2; i++)
    8209              :         {
    8210         1167 :           int fd = open (cmpfile[i], O_RDONLY);
    8211         1167 :           if (fd < 0)
    8212              :             {
    8213            0 :               error ("%s: could not open compare-debug file %s",
    8214              :                      gcc_input_filename, cmpfile[i]);
    8215            0 :               ret = 1;
    8216            0 :               break;
    8217              :             }
    8218              : 
    8219         1167 :           map[i] = mmap (NULL, length[i], PROT_READ, MAP_PRIVATE, fd, 0);
    8220         1167 :           close (fd);
    8221              : 
    8222         1167 :           if (map[i] == (void *) MAP_FAILED)
    8223              :             {
    8224              :               ret = -1;
    8225              :               break;
    8226              :             }
    8227              :         }
    8228              : 
    8229          599 :     if (!ret)
    8230              :       {
    8231          568 :         if (memcmp (map[0], map[1], length[0]) != 0)
    8232              :           {
    8233            0 :             error ("%s: %<-fcompare-debug%> failure", gcc_input_filename);
    8234            0 :             ret = 1;
    8235              :           }
    8236              :       }
    8237              : 
    8238         1839 :     for (i = 0; i < 2; i++)
    8239         1226 :       if (map[i])
    8240         1167 :         munmap ((caddr_t) map[i], length[i]);
    8241              : 
    8242          613 :     if (ret >= 0)
    8243          582 :       return ret;
    8244              : 
    8245           31 :     ret = 0;
    8246              :   }
    8247              : #endif
    8248              : 
    8249           93 :   for (i = 0; i < 2; i++)
    8250              :     {
    8251           62 :       temp[i] = fopen (cmpfile[i], "r");
    8252           62 :       if (!temp[i])
    8253              :         {
    8254            0 :           error ("%s: could not open compare-debug file %s",
    8255              :                  gcc_input_filename, cmpfile[i]);
    8256            0 :           ret = 1;
    8257            0 :           break;
    8258              :         }
    8259              :     }
    8260              : 
    8261           31 :   if (!ret && temp[0] && temp[1])
    8262           31 :     for (;;)
    8263              :       {
    8264           31 :         int c0, c1;
    8265           31 :         c0 = fgetc (temp[0]);
    8266           31 :         c1 = fgetc (temp[1]);
    8267              : 
    8268           31 :         if (c0 != c1)
    8269              :           {
    8270            0 :             error ("%s: %<-fcompare-debug%> failure",
    8271              :                    gcc_input_filename);
    8272            0 :             ret = 1;
    8273            0 :             break;
    8274              :           }
    8275              : 
    8276           31 :         if (c0 == EOF)
    8277              :           break;
    8278              :       }
    8279              : 
    8280           93 :   for (i = 1; i >= 0; i--)
    8281              :     {
    8282           62 :       if (temp[i])
    8283           62 :         fclose (temp[i]);
    8284              :     }
    8285              : 
    8286              :   return ret;
    8287              : }
    8288              : 
    8289       305022 : driver::driver (bool can_finalize, bool debug) :
    8290       305022 :   explicit_link_files (NULL),
    8291       305022 :   decoded_options (NULL)
    8292              : {
    8293       305022 :   env.init (can_finalize, debug);
    8294       305022 : }
    8295              : 
    8296       304540 : driver::~driver ()
    8297              : {
    8298       304540 :   XDELETEVEC (explicit_link_files);
    8299       304540 :   XDELETEVEC (decoded_options);
    8300       304540 : }
    8301              : 
    8302              : /* driver::main is implemented as a series of driver:: method calls.  */
    8303              : 
    8304              : int
    8305       305022 : driver::main (int argc, char **argv)
    8306              : {
    8307       305022 :   bool early_exit;
    8308              : 
    8309       305022 :   set_progname (argv[0]);
    8310       305022 :   expand_at_files (&argc, &argv);
    8311       305022 :   decode_argv (argc, const_cast <const char **> (argv));
    8312       305022 :   global_initializations ();
    8313       305022 :   build_multilib_strings ();
    8314       305022 :   set_up_specs ();
    8315       304735 :   putenv_COLLECT_AS_OPTIONS (assembler_options);
    8316       304735 :   putenv_COLLECT_GCC (argv[0]);
    8317       304735 :   maybe_putenv_COLLECT_LTO_WRAPPER ();
    8318       304735 :   maybe_putenv_OFFLOAD_TARGETS ();
    8319       304735 :   handle_unrecognized_options ();
    8320              : 
    8321       304735 :   if (completion)
    8322              :     {
    8323            5 :       m_option_proposer.suggest_completion (completion);
    8324            5 :       return 0;
    8325              :     }
    8326              : 
    8327       304730 :   if (!maybe_print_and_exit ())
    8328              :     return 0;
    8329              : 
    8330       283816 :   early_exit = prepare_infiles ();
    8331       283622 :   if (early_exit)
    8332          439 :     return get_exit_code ();
    8333              : 
    8334       283183 :   do_spec_on_infiles ();
    8335       283183 :   maybe_run_linker (argv[0]);
    8336       283183 :   final_actions ();
    8337       283183 :   return get_exit_code ();
    8338              : }
    8339              : 
    8340              : /* Locate the final component of argv[0] after any leading path, and set
    8341              :    the program name accordingly.  */
    8342              : 
    8343              : void
    8344       305022 : driver::set_progname (const char *argv0) const
    8345              : {
    8346       305022 :   const char *p = argv0 + strlen (argv0);
    8347      1680734 :   while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
    8348      1375712 :     --p;
    8349       305022 :   progname = p;
    8350              : 
    8351       305022 :   xmalloc_set_program_name (progname);
    8352       305022 : }
    8353              : 
    8354              : /* Expand any @ files within the command-line args,
    8355              :    setting at_file_supplied if any were expanded.  */
    8356              : 
    8357              : void
    8358       305022 : driver::expand_at_files (int *argc, char ***argv) const
    8359              : {
    8360       305022 :   char **old_argv = *argv;
    8361              : 
    8362       305022 :   expandargv (argc, argv);
    8363              : 
    8364              :   /* Determine if any expansions were made.  */
    8365       305022 :   if (*argv != old_argv)
    8366        12295 :     at_file_supplied = true;
    8367       305022 : }
    8368              : 
    8369              : /* Decode the command-line arguments from argc/argv into the
    8370              :    decoded_options array.  */
    8371              : 
    8372              : void
    8373       305022 : driver::decode_argv (int argc, const char **argv)
    8374              : {
    8375       305022 :   init_opts_obstack ();
    8376       305022 :   init_options_struct (&global_options, &global_options_set);
    8377              : 
    8378       305022 :   decode_cmdline_options_to_array (argc, argv,
    8379              :                                    CL_DRIVER,
    8380              :                                    &decoded_options, &decoded_options_count);
    8381       305022 : }
    8382              : 
    8383              : /* Perform various initializations and setup.  */
    8384              : 
    8385              : void
    8386       305022 : driver::global_initializations ()
    8387              : {
    8388              :   /* Unlock the stdio streams.  */
    8389       305022 :   unlock_std_streams ();
    8390              : 
    8391       305022 :   gcc_init_libintl ();
    8392              : 
    8393       305022 :   diagnostic_initialize (global_dc, 0);
    8394       305022 :   diagnostic_color_init (global_dc);
    8395       305022 :   diagnostic_urls_init (global_dc);
    8396       305022 :   global_dc->push_owned_urlifier (make_gcc_urlifier (0));
    8397              : 
    8398              : #ifdef GCC_DRIVER_HOST_INITIALIZATION
    8399              :   /* Perform host dependent initialization when needed.  */
    8400              :   GCC_DRIVER_HOST_INITIALIZATION;
    8401              : #endif
    8402              : 
    8403       305022 :   if (atexit (delete_temp_files) != 0)
    8404            0 :     fatal_error (input_location, "atexit failed");
    8405              : 
    8406       305022 :   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
    8407       304871 :     signal (SIGINT, fatal_signal);
    8408              : #ifdef SIGHUP
    8409       305022 :   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
    8410        21389 :     signal (SIGHUP, fatal_signal);
    8411              : #endif
    8412       305022 :   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
    8413       305022 :     signal (SIGTERM, fatal_signal);
    8414              : #ifdef SIGPIPE
    8415       305022 :   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
    8416       305022 :     signal (SIGPIPE, fatal_signal);
    8417              : #endif
    8418              : #ifdef SIGCHLD
    8419              :   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
    8420              :      receive the signal.  A different setting is inheritable */
    8421       305022 :   signal (SIGCHLD, SIG_DFL);
    8422              : #endif
    8423              : 
    8424              :   /* Parsing and gimplification sometimes need quite large stack.
    8425              :      Increase stack size limits if possible.  */
    8426       305022 :   stack_limit_increase (64 * 1024 * 1024);
    8427              : 
    8428              :   /* Allocate the argument vector.  */
    8429       305022 :   alloc_args ();
    8430              : 
    8431       305022 :   obstack_init (&obstack);
    8432       305022 : }
    8433              : 
    8434              : /* Build multilib_select, et. al from the separate lines that make up each
    8435              :    multilib selection.  */
    8436              : 
    8437              : void
    8438       305022 : driver::build_multilib_strings () const
    8439              : {
    8440       305022 :   {
    8441       305022 :     const char *p;
    8442       305022 :     const char *const *q = multilib_raw;
    8443       305022 :     int need_space;
    8444              : 
    8445       305022 :     obstack_init (&multilib_obstack);
    8446       305022 :     while ((p = *q++) != (char *) 0)
    8447      1220088 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8448              : 
    8449       305022 :     obstack_1grow (&multilib_obstack, 0);
    8450       305022 :     multilib_select = XOBFINISH (&multilib_obstack, const char *);
    8451              : 
    8452       305022 :     q = multilib_matches_raw;
    8453       305022 :     while ((p = *q++) != (char *) 0)
    8454       915066 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8455              : 
    8456       305022 :     obstack_1grow (&multilib_obstack, 0);
    8457       305022 :     multilib_matches = XOBFINISH (&multilib_obstack, const char *);
    8458              : 
    8459       305022 :     q = multilib_exclusions_raw;
    8460       305022 :     while ((p = *q++) != (char *) 0)
    8461       305022 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8462              : 
    8463       305022 :     obstack_1grow (&multilib_obstack, 0);
    8464       305022 :     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
    8465              : 
    8466       305022 :     q = multilib_reuse_raw;
    8467       305022 :     while ((p = *q++) != (char *) 0)
    8468       305022 :       obstack_grow (&multilib_obstack, p, strlen (p));
    8469              : 
    8470       305022 :     obstack_1grow (&multilib_obstack, 0);
    8471       305022 :     multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
    8472              : 
    8473       305022 :     need_space = false;
    8474       610044 :     for (size_t i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
    8475              :       {
    8476       305022 :         if (need_space)
    8477            0 :           obstack_1grow (&multilib_obstack, ' ');
    8478       305022 :         obstack_grow (&multilib_obstack,
    8479              :                       multilib_defaults_raw[i],
    8480              :                       strlen (multilib_defaults_raw[i]));
    8481       305022 :         need_space = true;
    8482              :       }
    8483              : 
    8484       305022 :     obstack_1grow (&multilib_obstack, 0);
    8485       305022 :     multilib_defaults = XOBFINISH (&multilib_obstack, const char *);
    8486              :   }
    8487       305022 : }
    8488              : 
    8489              : /* Set up the spec-handling machinery.  */
    8490              : 
    8491              : void
    8492       305022 : driver::set_up_specs () const
    8493              : {
    8494       305022 :   const char *spec_machine_suffix;
    8495       305022 :   char *specs_file;
    8496       305022 :   size_t i;
    8497              : 
    8498              : #ifdef INIT_ENVIRONMENT
    8499              :   /* Set up any other necessary machine specific environment variables.  */
    8500              :   xputenv (INIT_ENVIRONMENT);
    8501              : #endif
    8502              : 
    8503              :   /* Make a table of what switches there are (switches, n_switches).
    8504              :      Make a table of specified input files (infiles, n_infiles).
    8505              :      Decode switches that are handled locally.  */
    8506              : 
    8507       305022 :   process_command (decoded_options_count, decoded_options);
    8508              : 
    8509              :   /* Initialize the vector of specs to just the default.
    8510              :      This means one element containing 0s, as a terminator.  */
    8511              : 
    8512       304736 :   compilers = XNEWVAR (struct compiler, sizeof default_compilers);
    8513       304736 :   memcpy (compilers, default_compilers, sizeof default_compilers);
    8514       304736 :   n_compilers = n_default_compilers;
    8515              : 
    8516              :   /* Read specs from a file if there is one.  */
    8517              : 
    8518       304736 :   machine_suffix = concat (spec_host_machine, dir_separator_str, spec_version,
    8519              :                            accel_dir_suffix, dir_separator_str, NULL);
    8520       304736 :   just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
    8521              : 
    8522       304736 :   specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
    8523              :   /* Read the specs file unless it is a default one.  */
    8524       304736 :   if (specs_file != 0 && strcmp (specs_file, "specs"))
    8525       303597 :     read_specs (specs_file, true, false);
    8526              :   else
    8527         1139 :     init_spec ();
    8528              : 
    8529              : #ifdef ACCEL_COMPILER
    8530              :   spec_machine_suffix = machine_suffix;
    8531              : #else
    8532       304736 :   spec_machine_suffix = just_machine_suffix;
    8533              : #endif
    8534              : 
    8535       304736 :   const char *exec_prefix
    8536       304736 :     = gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix;
    8537              :   /* We need to check standard_exec_prefix/spec_machine_suffix/specs
    8538              :      for any override of as, ld and libraries.  */
    8539       304736 :   specs_file = (char *) alloca (
    8540              :     strlen (exec_prefix) + strlen (spec_machine_suffix) + sizeof ("specs"));
    8541       304736 :   strcpy (specs_file, exec_prefix);
    8542       304736 :   strcat (specs_file, spec_machine_suffix);
    8543       304736 :   strcat (specs_file, "specs");
    8544       304736 :   if (access (specs_file, R_OK) == 0)
    8545            0 :     read_specs (specs_file, true, false);
    8546              : 
    8547              :   /* Process any configure-time defaults specified for the command line
    8548              :      options, via OPTION_DEFAULT_SPECS.  */
    8549      3352096 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
    8550      3047360 :     do_option_spec (option_default_specs[i].name,
    8551      3047360 :                     option_default_specs[i].spec);
    8552              : 
    8553              :   /* Process DRIVER_SELF_SPECS, adding any new options to the end
    8554              :      of the command line.  */
    8555              : 
    8556      2133152 :   for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
    8557      1828416 :     do_self_spec (driver_self_specs[i]);
    8558              : 
    8559              :   /* If not cross-compiling, look for executables in the standard
    8560              :      places.  */
    8561       304736 :   if (*cross_compile == '0')
    8562              :     {
    8563       304736 :       if (*md_exec_prefix)
    8564              :         {
    8565            0 :           add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
    8566              :                       PREFIX_PRIORITY_LAST, 0, 0);
    8567              :         }
    8568              :     }
    8569              : 
    8570              :   /* Process sysroot_suffix_spec.  */
    8571       304736 :   if (*sysroot_suffix_spec != 0
    8572            0 :       && !no_sysroot_suffix
    8573       304736 :       && do_spec_2 (sysroot_suffix_spec, NULL) == 0)
    8574              :     {
    8575            0 :       if (argbuf.length () > 1)
    8576            0 :         error ("spec failure: more than one argument to "
    8577              :                "%<SYSROOT_SUFFIX_SPEC%>");
    8578            0 :       else if (argbuf.length () == 1)
    8579            0 :         target_sysroot_suffix = xstrdup (argbuf.last ());
    8580              :     }
    8581              : 
    8582              : #ifdef HAVE_LD_SYSROOT
    8583              :   /* Pass the --sysroot option to the linker, if it supports that.  If
    8584              :      there is a sysroot_suffix_spec, it has already been processed by
    8585              :      this point, so target_system_root really is the system root we
    8586              :      should be using.  */
    8587       304736 :   if (target_system_root)
    8588              :     {
    8589            0 :       obstack_grow (&obstack, "%(sysroot_spec) ", strlen ("%(sysroot_spec) "));
    8590            0 :       obstack_grow0 (&obstack, link_spec, strlen (link_spec));
    8591            0 :       set_spec ("link", XOBFINISH (&obstack, const char *), false);
    8592              :     }
    8593              : #endif
    8594              : 
    8595              :   /* Process sysroot_hdrs_suffix_spec.  */
    8596       304736 :   if (*sysroot_hdrs_suffix_spec != 0
    8597            0 :       && !no_sysroot_suffix
    8598       304736 :       && do_spec_2 (sysroot_hdrs_suffix_spec, NULL) == 0)
    8599              :     {
    8600            0 :       if (argbuf.length () > 1)
    8601            0 :         error ("spec failure: more than one argument "
    8602              :                "to %<SYSROOT_HEADERS_SUFFIX_SPEC%>");
    8603            0 :       else if (argbuf.length () == 1)
    8604            0 :         target_sysroot_hdrs_suffix = xstrdup (argbuf.last ());
    8605              :     }
    8606              : 
    8607              :   /* Look for startfiles in the standard places.  */
    8608       304736 :   if (*startfile_prefix_spec != 0
    8609            0 :       && do_spec_2 (startfile_prefix_spec, NULL) == 0
    8610       304736 :       && do_spec_1 (" ", 0, NULL) == 0)
    8611              :     {
    8612            0 :       for (const char *arg : argbuf)
    8613            0 :         add_sysrooted_prefix (&startfile_prefixes, arg, "BINUTILS",
    8614              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8615              :     }
    8616              :   /* We should eventually get rid of all these and stick to
    8617              :      startfile_prefix_spec exclusively.  */
    8618       304736 :   else if (*cross_compile == '0' || target_system_root)
    8619              :     {
    8620       304736 :       if (*md_startfile_prefix)
    8621            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
    8622              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8623              : 
    8624       304736 :       if (*md_startfile_prefix_1)
    8625            0 :         add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
    8626              :                               "GCC", PREFIX_PRIORITY_LAST, 0, 1);
    8627              : 
    8628              :       /* If standard_startfile_prefix is relative, base it on
    8629              :          standard_exec_prefix.  This lets us move the installed tree
    8630              :          as a unit.  If GCC_EXEC_PREFIX is defined, base
    8631              :          standard_startfile_prefix on that as well.
    8632              : 
    8633              :          If the prefix is relative, only search it for native compilers;
    8634              :          otherwise we will search a directory containing host libraries.  */
    8635       304736 :       if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
    8636              :         add_sysrooted_prefix (&startfile_prefixes,
    8637              :                               standard_startfile_prefix, "BINUTILS",
    8638              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8639       304736 :       else if (*cross_compile == '0')
    8640              :         {
    8641       304736 :           add_prefix (&startfile_prefixes,
    8642       609472 :                       concat (gcc_exec_prefix
    8643              :                               ? gcc_exec_prefix : standard_exec_prefix,
    8644              :                               machine_suffix,
    8645              :                               standard_startfile_prefix, NULL),
    8646              :                       NULL, PREFIX_PRIORITY_LAST, 0, 1);
    8647              :         }
    8648              : 
    8649              :       /* Sysrooted prefixes are relocated because target_system_root is
    8650              :          also relocated by gcc_exec_prefix.  */
    8651       304736 :       if (*standard_startfile_prefix_1)
    8652       304736 :         add_sysrooted_prefix (&startfile_prefixes,
    8653              :                               standard_startfile_prefix_1, "BINUTILS",
    8654              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8655       304736 :       if (*standard_startfile_prefix_2)
    8656       304736 :         add_sysrooted_prefix (&startfile_prefixes,
    8657              :                               standard_startfile_prefix_2, "BINUTILS",
    8658              :                               PREFIX_PRIORITY_LAST, 0, 1);
    8659              :     }
    8660              : 
    8661              :   /* Process any user specified specs in the order given on the command
    8662              :      line.  */
    8663       304738 :   for (struct user_specs *uptr = user_specs_head; uptr; uptr = uptr->next)
    8664              :     {
    8665            3 :       char *filename = find_a_file (&startfile_prefixes, uptr->filename,
    8666              :                                     R_OK, true);
    8667            3 :       read_specs (filename ? filename : uptr->filename, false, true);
    8668              :     }
    8669              : 
    8670              :   /* Process any user self specs.  */
    8671       304735 :   {
    8672       304735 :     struct spec_list *sl;
    8673     14322545 :     for (sl = specs; sl; sl = sl->next)
    8674     14017810 :       if (sl->name_len == sizeof "self_spec" - 1
    8675      2133145 :           && !strcmp (sl->name, "self_spec"))
    8676       304735 :         do_self_spec (*sl->ptr_spec);
    8677              :   }
    8678              : 
    8679       304735 :   if (compare_debug)
    8680              :     {
    8681          619 :       enum save_temps save;
    8682              : 
    8683          619 :       if (!compare_debug_second)
    8684              :         {
    8685          619 :           n_switches_debug_check[1] = n_switches;
    8686          619 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8687          619 :           switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
    8688              :                                              n_switches_alloc);
    8689              : 
    8690          619 :           do_self_spec ("%:compare-debug-self-opt()");
    8691          619 :           n_switches_debug_check[0] = n_switches;
    8692          619 :           n_switches_alloc_debug_check[0] = n_switches_alloc;
    8693          619 :           switches_debug_check[0] = switches;
    8694              : 
    8695          619 :           n_switches = n_switches_debug_check[1];
    8696          619 :           n_switches_alloc = n_switches_alloc_debug_check[1];
    8697          619 :           switches = switches_debug_check[1];
    8698              :         }
    8699              : 
    8700              :       /* Avoid crash when computing %j in this early.  */
    8701          619 :       save = save_temps_flag;
    8702          619 :       save_temps_flag = SAVE_TEMPS_NONE;
    8703              : 
    8704          619 :       compare_debug = -compare_debug;
    8705          619 :       do_self_spec ("%:compare-debug-self-opt()");
    8706              : 
    8707          619 :       save_temps_flag = save;
    8708              : 
    8709          619 :       if (!compare_debug_second)
    8710              :         {
    8711          619 :           n_switches_debug_check[1] = n_switches;
    8712          619 :           n_switches_alloc_debug_check[1] = n_switches_alloc;
    8713          619 :           switches_debug_check[1] = switches;
    8714          619 :           compare_debug = -compare_debug;
    8715          619 :           n_switches = n_switches_debug_check[0];
    8716          619 :           n_switches_alloc = n_switches_debug_check[0];
    8717          619 :           switches = switches_debug_check[0];
    8718              :         }
    8719              :     }
    8720              : 
    8721              : 
    8722              :   /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake.  */
    8723       304735 :   if (gcc_exec_prefix)
    8724       304735 :     gcc_exec_prefix = concat (gcc_exec_prefix, spec_host_machine,
    8725              :                               dir_separator_str, spec_version,
    8726              :                               accel_dir_suffix, dir_separator_str, NULL);
    8727              : 
    8728              :   /* Now we have the specs.
    8729              :      Set the `valid' bits for switches that match anything in any spec.  */
    8730              : 
    8731       304735 :   validate_all_switches ();
    8732              : 
    8733              :   /* Now that we have the switches and the specs, set
    8734              :      the subdirectory based on the options.  */
    8735       304735 :   set_multilib_dir ();
    8736       304735 : }
    8737              : 
    8738              : /* Set up to remember the pathname of gcc and any options
    8739              :    needed for collect.  We use argv[0] instead of progname because
    8740              :    we need the complete pathname.  */
    8741              : 
    8742              : void
    8743       304735 : driver::putenv_COLLECT_GCC (const char *argv0) const
    8744              : {
    8745       304735 :   obstack_init (&collect_obstack);
    8746       304735 :   obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
    8747       304735 :   obstack_grow (&collect_obstack, argv0, strlen (argv0) + 1);
    8748       304735 :   xputenv (XOBFINISH (&collect_obstack, char *));
    8749       304735 : }
    8750              : 
    8751              : /* Set up to remember the pathname of the lto wrapper. */
    8752              : 
    8753              : void
    8754       304735 : driver::maybe_putenv_COLLECT_LTO_WRAPPER () const
    8755              : {
    8756       304735 :   char *lto_wrapper_file;
    8757              : 
    8758       304735 :   if (have_c)
    8759              :     lto_wrapper_file = NULL;
    8760              :   else
    8761       116398 :     lto_wrapper_file = find_a_program ("lto-wrapper");
    8762       116398 :   if (lto_wrapper_file)
    8763              :     {
    8764       228258 :       lto_wrapper_file = convert_white_space (lto_wrapper_file);
    8765       114129 :       set_static_spec_owned (&lto_wrapper_spec, lto_wrapper_file);
    8766       114129 :       obstack_init (&collect_obstack);
    8767       114129 :       obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
    8768              :                     sizeof ("COLLECT_LTO_WRAPPER=") - 1);
    8769       114129 :       obstack_grow (&collect_obstack, lto_wrapper_spec,
    8770              :                     strlen (lto_wrapper_spec) + 1);
    8771       114129 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8772              :     }
    8773              : 
    8774       304735 : }
    8775              : 
    8776              : /* Set up to remember the names of offload targets.  */
    8777              : 
    8778              : void
    8779       304735 : driver::maybe_putenv_OFFLOAD_TARGETS () const
    8780              : {
    8781       304735 :   if (offload_targets && offload_targets[0] != '\0')
    8782              :     {
    8783            0 :       obstack_grow (&collect_obstack, "OFFLOAD_TARGET_NAMES=",
    8784              :                     sizeof ("OFFLOAD_TARGET_NAMES=") - 1);
    8785            0 :       obstack_grow (&collect_obstack, offload_targets,
    8786              :                     strlen (offload_targets) + 1);
    8787            0 :       xputenv (XOBFINISH (&collect_obstack, char *));
    8788              : #if OFFLOAD_DEFAULTED
    8789              :       if (offload_targets_default)
    8790              :         xputenv ("OFFLOAD_TARGET_DEFAULT=1");
    8791              : #endif
    8792              :     }
    8793              : 
    8794       304735 :   free (offload_targets);
    8795       304735 :   offload_targets = NULL;
    8796       304735 : }
    8797              : 
    8798              : /* Reject switches that no pass was interested in.  */
    8799              : 
    8800              : void
    8801       304735 : driver::handle_unrecognized_options ()
    8802              : {
    8803      7130669 :   for (size_t i = 0; (int) i < n_switches; i++)
    8804      6825934 :     if (! switches[i].validated)
    8805              :       {
    8806          601 :         const char *hint = m_option_proposer.suggest_option (switches[i].part1);
    8807          601 :         if (hint)
    8808          229 :           error ("unrecognized command-line option %<-%s%>;"
    8809              :                  " did you mean %<-%s%>?",
    8810          229 :                  switches[i].part1, hint);
    8811              :         else
    8812          372 :           error ("unrecognized command-line option %<-%s%>",
    8813          372 :                  switches[i].part1);
    8814              :       }
    8815       304735 : }
    8816              : 
    8817              : /* Handle the various -print-* options, returning 0 if the driver
    8818              :    should exit, or nonzero if the driver should continue.  */
    8819              : 
    8820              : int
    8821       304730 : driver::maybe_print_and_exit () const
    8822              : {
    8823       304730 :   if (print_search_dirs)
    8824              :     {
    8825           56 :       printf (_("install: %s%s\n"),
    8826              :               gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
    8827           28 :               gcc_exec_prefix ? "" : machine_suffix);
    8828           28 :       printf (_("programs: %s\n"),
    8829              :               build_search_list (&exec_prefixes, "", false, false));
    8830           28 :       printf (_("libraries: %s\n"),
    8831              :               build_search_list (&startfile_prefixes, "", false, true));
    8832           28 :       return (0);
    8833              :     }
    8834              : 
    8835       304702 :   if (print_autofdo_gcov_version)
    8836              :     {
    8837            0 :       printf ("%d\n", AUTO_PROFILE_VERSION);
    8838            0 :       return (0);
    8839              :     }
    8840              : 
    8841       304702 :   if (print_file_name)
    8842              :     {
    8843         6433 :       printf ("%s\n", find_file (print_file_name));
    8844         6433 :       return (0);
    8845              :     }
    8846              : 
    8847       298269 :   if (print_prog_name)
    8848              :     {
    8849          109 :       if (use_ld != NULL && ! strcmp (print_prog_name, "ld"))
    8850              :         {
    8851              :           /* Append USE_LD to the default linker.  */
    8852              : #ifdef DEFAULT_LINKER
    8853              :           char *ld;
    8854              : # ifdef HAVE_HOST_EXECUTABLE_SUFFIX
    8855              :           int len = (sizeof (DEFAULT_LINKER)
    8856              :                      - sizeof (HOST_EXECUTABLE_SUFFIX));
    8857              :           ld = NULL;
    8858              :           if (len > 0)
    8859              :             {
    8860              :               char *default_linker = xstrdup (DEFAULT_LINKER);
    8861              :               /* Strip HOST_EXECUTABLE_SUFFIX if DEFAULT_LINKER contains
    8862              :                  HOST_EXECUTABLE_SUFFIX.  */
    8863              :               if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
    8864              :                 {
    8865              :                   default_linker[len] = '\0';
    8866              :                   ld = concat (default_linker, use_ld,
    8867              :                                HOST_EXECUTABLE_SUFFIX, NULL);
    8868              :                 }
    8869              :             }
    8870              :           if (ld == NULL)
    8871              : # endif
    8872              :           ld = concat (DEFAULT_LINKER, use_ld, NULL);
    8873              :           if (access (ld, X_OK) == 0)
    8874              :             {
    8875              :               printf ("%s\n", ld);
    8876              :               return (0);
    8877              :             }
    8878              : #endif
    8879            0 :           print_prog_name = concat (print_prog_name, use_ld, NULL);
    8880              :         }
    8881          109 :       char *newname = find_a_program (print_prog_name);
    8882          109 :       printf ("%s\n", (newname ? newname : print_prog_name));
    8883          109 :       return (0);
    8884              :     }
    8885              : 
    8886       298160 :   if (print_multi_lib)
    8887              :     {
    8888         6961 :       print_multilib_info ();
    8889         6961 :       return (0);
    8890              :     }
    8891              : 
    8892       291199 :   if (print_multi_directory)
    8893              :     {
    8894         6387 :       if (multilib_dir == NULL)
    8895         6362 :         printf (".\n");
    8896              :       else
    8897           25 :         printf ("%s\n", multilib_dir);
    8898         6387 :       return (0);
    8899              :     }
    8900              : 
    8901       284812 :   if (print_multiarch)
    8902              :     {
    8903            0 :       if (multiarch_dir == NULL)
    8904            0 :         printf ("\n");
    8905              :       else
    8906            0 :         printf ("%s\n", multiarch_dir);
    8907            0 :       return (0);
    8908              :     }
    8909              : 
    8910       284812 :   if (print_sysroot)
    8911              :     {
    8912            0 :       if (target_system_root)
    8913              :         {
    8914            0 :           if (target_sysroot_suffix)
    8915            0 :             printf ("%s%s\n", target_system_root, target_sysroot_suffix);
    8916              :           else
    8917            0 :             printf ("%s\n", target_system_root);
    8918              :         }
    8919            0 :       return (0);
    8920              :     }
    8921              : 
    8922       284812 :   if (print_multi_os_directory)
    8923              :     {
    8924          149 :       if (multilib_os_dir == NULL)
    8925            0 :         printf (".\n");
    8926              :       else
    8927          149 :         printf ("%s\n", multilib_os_dir);
    8928          149 :       return (0);
    8929              :     }
    8930              : 
    8931       284663 :   if (print_sysroot_headers_suffix)
    8932              :     {
    8933            1 :       if (*sysroot_hdrs_suffix_spec)
    8934              :         {
    8935            0 :           printf("%s\n", (target_sysroot_hdrs_suffix
    8936              :                           ? target_sysroot_hdrs_suffix
    8937              :                           : ""));
    8938            0 :           return (0);
    8939              :         }
    8940              :       else
    8941              :         /* The error status indicates that only one set of fixed
    8942              :            headers should be built.  */
    8943            1 :         fatal_error (input_location,
    8944              :                      "not configured with sysroot headers suffix");
    8945              :     }
    8946              : 
    8947       284662 :   if (print_help_list)
    8948              :     {
    8949            4 :       display_help ();
    8950              : 
    8951            4 :       if (! verbose_flag)
    8952              :         {
    8953            1 :           printf (_("\nFor bug reporting instructions, please see:\n"));
    8954            1 :           printf ("%s.\n", bug_report_url);
    8955              : 
    8956            1 :           return (0);
    8957              :         }
    8958              : 
    8959              :       /* We do not exit here.  Instead we have created a fake input file
    8960              :          called 'help-dummy' which needs to be compiled, and we pass this
    8961              :          on the various sub-processes, along with the --help switch.
    8962              :          Ensure their output appears after ours.  */
    8963            3 :       fputc ('\n', stdout);
    8964            3 :       fflush (stdout);
    8965              :     }
    8966              : 
    8967       284661 :   if (print_version)
    8968              :     {
    8969           78 :       printf (_("%s %s%s\n"), progname, pkgversion_string,
    8970              :               version_string);
    8971           78 :       printf ("Copyright %s 2026 Free Software Foundation, Inc.\n",
    8972              :               _("(C)"));
    8973           78 :       fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
    8974              : warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
    8975              :              stdout);
    8976           78 :       if (! verbose_flag)
    8977              :         return 0;
    8978              : 
    8979              :       /* We do not exit here. We use the same mechanism of --help to print
    8980              :          the version of the sub-processes. */
    8981            0 :       fputc ('\n', stdout);
    8982            0 :       fflush (stdout);
    8983              :     }
    8984              : 
    8985       284583 :   if (verbose_flag)
    8986              :     {
    8987         1561 :       print_configuration (stderr);
    8988         1561 :       if (n_infiles == 0)
    8989              :         return (0);
    8990              :     }
    8991              : 
    8992              :   return 1;
    8993              : }
    8994              : 
    8995              : /* Figure out what to do with each input file.
    8996              :    Return true if we need to exit early from "main", false otherwise.  */
    8997              : 
    8998              : bool
    8999       283816 : driver::prepare_infiles ()
    9000              : {
    9001       283816 :   size_t i;
    9002       283816 :   int lang_n_infiles = 0;
    9003              : 
    9004       283816 :   if (n_infiles == added_libraries)
    9005          194 :     fatal_error (input_location, "no input files");
    9006              : 
    9007       283622 :   if (seen_error ())
    9008              :     /* Early exit needed from main.  */
    9009              :     return true;
    9010              : 
    9011              :   /* Make a place to record the compiler output file names
    9012              :      that correspond to the input files.  */
    9013              : 
    9014       283183 :   i = n_infiles;
    9015       283183 :   i += lang_specific_extra_outfiles;
    9016       283183 :   outfiles = XCNEWVEC (const char *, i);
    9017              : 
    9018              :   /* Record which files were specified explicitly as link input.  */
    9019              : 
    9020       283183 :   explicit_link_files = XCNEWVEC (char, n_infiles);
    9021              : 
    9022       283183 :   combine_inputs = have_o || flag_wpa;
    9023              : 
    9024       838248 :   for (i = 0; (int) i < n_infiles; i++)
    9025              :     {
    9026       555065 :       const char *name = infiles[i].name;
    9027       555065 :       struct compiler *compiler = lookup_compiler (name,
    9028              :                                                    strlen (name),
    9029              :                                                    infiles[i].language);
    9030              : 
    9031       555065 :       if (compiler && !(compiler->combinable))
    9032       254773 :         combine_inputs = false;
    9033              : 
    9034       555065 :       if (lang_n_infiles > 0 && compiler != input_file_compiler
    9035       250119 :           && infiles[i].language && infiles[i].language[0] != '*')
    9036           33 :         infiles[i].incompiler = compiler;
    9037       555032 :       else if (infiles[i].artificial)
    9038              :         /* Leave lang_n_infiles alone so files added by the driver don't
    9039              :            interfere with -c -o.  */
    9040            3 :         infiles[i].incompiler = compiler;
    9041       555029 :       else if (compiler)
    9042              :         {
    9043       294154 :           lang_n_infiles++;
    9044       294154 :           input_file_compiler = compiler;
    9045       294154 :           infiles[i].incompiler = compiler;
    9046              :         }
    9047              :       else
    9048              :         {
    9049              :           /* Since there is no compiler for this input file, assume it is a
    9050              :              linker file.  */
    9051       260875 :           explicit_link_files[i] = 1;
    9052       260875 :           infiles[i].incompiler = NULL;
    9053              :         }
    9054       555065 :       infiles[i].compiled = false;
    9055       555065 :       infiles[i].preprocessed = false;
    9056              :     }
    9057              : 
    9058       283183 :   if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
    9059            0 :     fatal_error (input_location,
    9060              :                  "cannot specify %<-o%> with %<-c%>, %<-S%> or %<-E%> "
    9061              :                  "with multiple files");
    9062              : 
    9063              :   /* No early exit needed from main; we can continue.  */
    9064              :   return false;
    9065              : }
    9066              : 
    9067              : /* Run the spec machinery on each input file.  */
    9068              : 
    9069              : void
    9070       283183 : driver::do_spec_on_infiles () const
    9071              : {
    9072       283183 :   size_t i;
    9073              : 
    9074       838248 :   for (i = 0; (int) i < n_infiles; i++)
    9075              :     {
    9076       555065 :       int this_file_error = 0;
    9077              : 
    9078              :       /* Tell do_spec what to substitute for %i.  */
    9079              : 
    9080       555065 :       input_file_number = i;
    9081       555065 :       set_input (infiles[i].name);
    9082              : 
    9083       555065 :       if (infiles[i].compiled)
    9084         9116 :         continue;
    9085              : 
    9086              :       /* Use the same thing in %o, unless cp->spec says otherwise.  */
    9087              : 
    9088       545949 :       outfiles[i] = gcc_input_filename;
    9089              : 
    9090              :       /* Figure out which compiler from the file's suffix.  */
    9091              : 
    9092       545949 :       input_file_compiler
    9093       545949 :         = lookup_compiler (infiles[i].name, input_filename_length,
    9094              :                            infiles[i].language);
    9095              : 
    9096       545949 :       if (input_file_compiler)
    9097              :         {
    9098              :           /* Ok, we found an applicable compiler.  Run its spec.  */
    9099              : 
    9100       285074 :           if (input_file_compiler->spec[0] == '#')
    9101              :             {
    9102            0 :               error ("%s: %s compiler not installed on this system",
    9103              :                      gcc_input_filename, &input_file_compiler->spec[1]);
    9104            0 :               this_file_error = 1;
    9105              :             }
    9106              :           else
    9107              :             {
    9108       285074 :               int value;
    9109              : 
    9110       285074 :               if (compare_debug)
    9111              :                 {
    9112          617 :                   free (debug_check_temp_file[0]);
    9113          617 :                   debug_check_temp_file[0] = NULL;
    9114              : 
    9115          617 :                   free (debug_check_temp_file[1]);
    9116          617 :                   debug_check_temp_file[1] = NULL;
    9117              :                 }
    9118              : 
    9119       285074 :               value = do_spec (input_file_compiler->spec);
    9120       285074 :               infiles[i].compiled = true;
    9121       285074 :               if (value < 0)
    9122              :                 this_file_error = 1;
    9123       255808 :               else if (compare_debug && debug_check_temp_file[0])
    9124              :                 {
    9125          613 :                   if (verbose_flag)
    9126            0 :                     inform (UNKNOWN_LOCATION,
    9127              :                             "recompiling with %<-fcompare-debug%>");
    9128              : 
    9129          613 :                   compare_debug = -compare_debug;
    9130          613 :                   n_switches = n_switches_debug_check[1];
    9131          613 :                   n_switches_alloc = n_switches_alloc_debug_check[1];
    9132          613 :                   switches = switches_debug_check[1];
    9133              : 
    9134          613 :                   value = do_spec (input_file_compiler->spec);
    9135              : 
    9136          613 :                   compare_debug = -compare_debug;
    9137          613 :                   n_switches = n_switches_debug_check[0];
    9138          613 :                   n_switches_alloc = n_switches_alloc_debug_check[0];
    9139          613 :                   switches = switches_debug_check[0];
    9140              : 
    9141          613 :                   if (value < 0)
    9142              :                     {
    9143            2 :                       error ("during %<-fcompare-debug%> recompilation");
    9144            2 :                       this_file_error = 1;
    9145              :                     }
    9146              : 
    9147          613 :                   gcc_assert (debug_check_temp_file[1]
    9148              :                               && filename_cmp (debug_check_temp_file[0],
    9149              :                                                debug_check_temp_file[1]));
    9150              : 
    9151          613 :                   if (verbose_flag)
    9152            0 :                     inform (UNKNOWN_LOCATION, "comparing final insns dumps");
    9153              : 
    9154          613 :                   if (compare_files (debug_check_temp_file))
    9155        29280 :                     this_file_error = 1;
    9156              :                 }
    9157              : 
    9158       285074 :               if (compare_debug)
    9159              :                 {
    9160          617 :                   free (debug_check_temp_file[0]);
    9161          617 :                   debug_check_temp_file[0] = NULL;
    9162              : 
    9163          617 :                   free (debug_check_temp_file[1]);
    9164          617 :                   debug_check_temp_file[1] = NULL;
    9165              :                 }
    9166              :             }
    9167              :         }
    9168              : 
    9169              :       /* If this file's name does not contain a recognized suffix,
    9170              :          record it as explicit linker input.  */
    9171              : 
    9172              :       else
    9173       260875 :         explicit_link_files[i] = 1;
    9174              : 
    9175              :       /* Clear the delete-on-failure queue, deleting the files in it
    9176              :          if this compilation failed.  */
    9177              : 
    9178       545949 :       if (this_file_error)
    9179              :         {
    9180        29280 :           delete_failure_queue ();
    9181        29280 :           errorcount++;
    9182              :         }
    9183              :       /* If this compilation succeeded, don't delete those files later.  */
    9184       545949 :       clear_failure_queue ();
    9185              :     }
    9186              : 
    9187              :   /* Reset the input file name to the first compile/object file name, for use
    9188              :      with %b in LINK_SPEC. We use the first input file that we can find
    9189              :      a compiler to compile it instead of using infiles.language since for
    9190              :      languages other than C we use aliases that we then lookup later.  */
    9191       283183 :   if (n_infiles > 0)
    9192              :     {
    9193              :       int i;
    9194              : 
    9195       295371 :       for (i = 0; i < n_infiles ; i++)
    9196       293459 :         if (infiles[i].incompiler
    9197        12188 :             || (infiles[i].language && infiles[i].language[0] != '*'))
    9198              :           {
    9199       281271 :             set_input (infiles[i].name);
    9200       281271 :             break;
    9201              :           }
    9202              :     }
    9203              : 
    9204       283183 :   if (!seen_error ())
    9205              :     {
    9206              :       /* Make sure INPUT_FILE_NUMBER points to first available open
    9207              :          slot.  */
    9208       253903 :       input_file_number = n_infiles;
    9209       253903 :       if (lang_specific_pre_link ())
    9210            0 :         errorcount++;
    9211              :     }
    9212       283183 : }
    9213              : 
    9214              : /* If we have to run the linker, do it now.  */
    9215              : 
    9216              : void
    9217       283183 : driver::maybe_run_linker (const char *argv0) const
    9218              : {
    9219       283183 :   size_t i;
    9220       283183 :   int linker_was_run = 0;
    9221       283183 :   int num_linker_inputs;
    9222              : 
    9223              :   /* Determine if there are any linker input files.  */
    9224       283183 :   num_linker_inputs = 0;
    9225       838248 :   for (i = 0; (int) i < n_infiles; i++)
    9226       555065 :     if (explicit_link_files[i] || outfiles[i] != NULL)
    9227       545516 :       num_linker_inputs++;
    9228              : 
    9229              :   /* Arrange for temporary file names created during linking to take
    9230              :      on names related with the linker output rather than with the
    9231              :      inputs when appropriate.  */
    9232       283183 :   if (outbase && *outbase)
    9233              :     {
    9234       260539 :       if (dumpdir)
    9235              :         {
    9236        89124 :           char *tofree = dumpdir;
    9237        89124 :           gcc_checking_assert (strlen (dumpdir) == dumpdir_length);
    9238        89124 :           dumpdir = concat (dumpdir, outbase, ".", NULL);
    9239        89124 :           free (tofree);
    9240              :         }
    9241              :       else
    9242       171415 :         dumpdir = concat (outbase, ".", NULL);
    9243       260539 :       dumpdir_length += strlen (outbase) + 1;
    9244       260539 :       dumpdir_trailing_dash_added = true;
    9245       260539 :     }
    9246        22644 :   else if (dumpdir_trailing_dash_added)
    9247              :     {
    9248        17771 :       gcc_assert (dumpdir[dumpdir_length - 1] == '-');
    9249        17771 :       dumpdir[dumpdir_length - 1] = '.';
    9250              :     }
    9251              : 
    9252       283183 :   if (dumpdir_trailing_dash_added)
    9253              :     {
    9254       278310 :       gcc_assert (dumpdir_length > 0);
    9255       278310 :       gcc_assert (dumpdir[dumpdir_length - 1] == '.');
    9256       278310 :       dumpdir_length--;
    9257              :     }
    9258              : 
    9259       283183 :   free (outbase);
    9260       283183 :   input_basename = outbase = NULL;
    9261       283183 :   outbase_length = suffixed_basename_length = basename_length = 0;
    9262              : 
    9263              :   /* Run ld to link all the compiler output files.  */
    9264              : 
    9265       283183 :   if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
    9266              :     {
    9267       253407 :       int tmp = execution_count;
    9268              : 
    9269       253407 :       detect_jobserver ();
    9270              : 
    9271       253407 :       if (! have_c)
    9272              :         {
    9273              : #if HAVE_LTO_PLUGIN > 0
    9274              : #if HAVE_LTO_PLUGIN == 2
    9275        95139 :           const char *fno_use_linker_plugin = "fno-use-linker-plugin";
    9276              : #else
    9277              :           const char *fuse_linker_plugin = "fuse-linker-plugin";
    9278              : #endif
    9279              : #endif
    9280              : 
    9281              :           /* We'll use ld if we can't find collect2.  */
    9282        95139 :           if (! strcmp (linker_name_spec, "collect2"))
    9283              :             {
    9284        95139 :               char *s = find_a_program ("collect2");
    9285        95139 :               if (s == NULL)
    9286         1129 :                 set_static_spec_shared (&linker_name_spec, "ld");
    9287              :             }
    9288              : 
    9289              : #if HAVE_LTO_PLUGIN > 0
    9290              : #if HAVE_LTO_PLUGIN == 2
    9291        95139 :           if (!switch_matches (fno_use_linker_plugin,
    9292              :                                fno_use_linker_plugin
    9293              :                                + strlen (fno_use_linker_plugin), 0))
    9294              : #else
    9295              :           if (switch_matches (fuse_linker_plugin,
    9296              :                               fuse_linker_plugin
    9297              :                               + strlen (fuse_linker_plugin), 0))
    9298              : #endif
    9299              :             {
    9300        89637 :               char *temp_spec = find_a_file (&exec_prefixes,
    9301              :                                              LTOPLUGINSONAME, R_OK,
    9302              :                                              false);
    9303        89637 :               if (!temp_spec)
    9304            0 :                 fatal_error (input_location,
    9305              :                              "%<-fuse-linker-plugin%>, but %s not found",
    9306              :                              LTOPLUGINSONAME);
    9307        89637 :               linker_plugin_file_spec = convert_white_space (temp_spec);
    9308              :             }
    9309              : #endif
    9310        95139 :           set_static_spec_shared (&lto_gcc_spec, argv0);
    9311              :         }
    9312              : 
    9313              :       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
    9314              :          for collect.  */
    9315       253407 :       putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
    9316       253407 :       putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
    9317              : 
    9318       253407 :       if (print_subprocess_help == 1)
    9319              :         {
    9320            0 :           printf (_("\nLinker options\n==============\n\n"));
    9321            0 :           printf (_("Use \"-Wl,OPTION\" to pass \"OPTION\""
    9322              :                     " to the linker.\n\n"));
    9323            0 :           fflush (stdout);
    9324              :         }
    9325       253407 :       int value = do_spec (link_command_spec);
    9326       253407 :       if (value < 0)
    9327          131 :         errorcount = 1;
    9328       253407 :       linker_was_run = (tmp != execution_count);
    9329              :     }
    9330              : 
    9331              :   /* If options said don't run linker,
    9332              :      complain about input files to be given to the linker.  */
    9333              : 
    9334       283183 :   if (! linker_was_run && !seen_error ())
    9335       352428 :     for (i = 0; (int) i < n_infiles; i++)
    9336       193660 :       if (explicit_link_files[i]
    9337        25791 :           && !(infiles[i].language && infiles[i].language[0] == '*'))
    9338              :         {
    9339           38 :           warning (0, "%s: linker input file unused because linking not done",
    9340           19 :                    outfiles[i]);
    9341           19 :           if (access (outfiles[i], F_OK) < 0)
    9342              :             /* This is can be an indication the user specifed an errorneous
    9343              :                separated option value, (or used the wrong prefix for an
    9344              :                option).  */
    9345            7 :             error ("%s: linker input file not found: %m", outfiles[i]);
    9346              :         }
    9347       283183 : }
    9348              : 
    9349              : /* The end of "main".  */
    9350              : 
    9351              : void
    9352       283183 : driver::final_actions () const
    9353              : {
    9354              :   /* Delete some or all of the temporary files we made.  */
    9355              : 
    9356       283183 :   if (seen_error ())
    9357        29416 :     delete_failure_queue ();
    9358       283183 :   delete_temp_files ();
    9359              : 
    9360       283183 :   if (totruncate_file != NULL && !seen_error ())
    9361              :     /* Truncate file specified by -truncate.
    9362              :        Used by lto-wrapper to reduce temporary disk-space usage. */
    9363         8111 :     truncate(totruncate_file, 0);
    9364              : 
    9365       283183 :   if (print_help_list)
    9366              :     {
    9367            3 :       printf (("\nFor bug reporting instructions, please see:\n"));
    9368            3 :       printf ("%s\n", bug_report_url);
    9369              :     }
    9370       283183 : }
    9371              : 
    9372              : /* Detect whether jobserver is active and working.  If not drop
    9373              :    --jobserver-auth from MAKEFLAGS.  */
    9374              : 
    9375              : void
    9376       253407 : driver::detect_jobserver () const
    9377              : {
    9378       253407 :   jobserver_info jinfo;
    9379       253407 :   if (!jinfo.is_active && !jinfo.skipped_makeflags.empty ())
    9380            0 :     xputenv (xstrdup (jinfo.skipped_makeflags.c_str ()));
    9381       253407 : }
    9382              : 
    9383              : /* Determine what the exit code of the driver should be.  */
    9384              : 
    9385              : int
    9386       283622 : driver::get_exit_code () const
    9387              : {
    9388       283622 :   return (signal_count != 0 ? 2
    9389       283622 :           : seen_error () ? (pass_exit_codes ? greatest_status : 1)
    9390            0 :           : 0);
    9391              : }
    9392              : 
    9393              : /* Find the proper compilation spec for the file name NAME,
    9394              :    whose length is LENGTH.  LANGUAGE is the specified language,
    9395              :    or 0 if this file is to be passed to the linker.  */
    9396              : 
    9397              : static struct compiler *
    9398      1101014 : lookup_compiler (const char *name, size_t length, const char *language)
    9399              : {
    9400      1607395 :   struct compiler *cp;
    9401              : 
    9402              :   /* If this was specified by the user to be a linker input, indicate that.  */
    9403      1607395 :   if (language != 0 && language[0] == '*')
    9404              :     return 0;
    9405              : 
    9406              :   /* Otherwise, look for the language, if one is spec'd.  */
    9407      1132933 :   if (language != 0)
    9408              :     {
    9409     22901875 :       for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9410     22901875 :         if (cp->suffix[0] == '@' && !strcmp (cp->suffix + 1, language))
    9411              :           {
    9412       579250 :             if (name != NULL && strcmp (name, "-") == 0
    9413         2078 :                 && (strcmp (cp->suffix, "@c-header") == 0
    9414         2078 :                     || strcmp (cp->suffix, "@c++-header") == 0)
    9415            0 :                 && !have_E)
    9416            0 :               fatal_error (input_location,
    9417              :                            "cannot use %<-%> as input filename for a "
    9418              :                            "precompiled header");
    9419              : 
    9420              :             return cp;
    9421              :           }
    9422              : 
    9423            0 :       error ("language %s not recognized", language);
    9424            0 :       return 0;
    9425              :     }
    9426              : 
    9427              :   /* Look for a suffix.  */
    9428     30559461 :   for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9429              :     {
    9430     30512173 :       if (/* The suffix `-' matches only the file name `-'.  */
    9431     30512173 :           (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9432     30512159 :           || (strlen (cp->suffix) < length
    9433              :               /* See if the suffix matches the end of NAME.  */
    9434     30071810 :               && !strcmp (cp->suffix,
    9435     30071810 :                           name + length - strlen (cp->suffix))
    9436              :          ))
    9437              :         break;
    9438              :     }
    9439              : 
    9440              : #if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
    9441              :   /* Look again, but case-insensitively this time.  */
    9442              :   if (cp < compilers)
    9443              :     for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
    9444              :       {
    9445              :         if (/* The suffix `-' matches only the file name `-'.  */
    9446              :             (!strcmp (cp->suffix, "-") && !strcmp (name, "-"))
    9447              :             || (strlen (cp->suffix) < length
    9448              :                 /* See if the suffix matches the end of NAME.  */
    9449              :                 && ((!strcmp (cp->suffix,
    9450              :                              name + length - strlen (cp->suffix))
    9451              :                      || !strpbrk (cp->suffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
    9452              :                     && !strcasecmp (cp->suffix,
    9453              :                                     name + length - strlen (cp->suffix)))
    9454              :            ))
    9455              :           break;
    9456              :       }
    9457              : #endif
    9458              : 
    9459       553683 :   if (cp >= compilers)
    9460              :     {
    9461       506395 :       if (cp->spec[0] != '@')
    9462              :         /* A non-alias entry: return it.  */
    9463              :         return cp;
    9464              : 
    9465              :       /* An alias entry maps a suffix to a language.
    9466              :          Search for the language; pass 0 for NAME and LENGTH
    9467              :          to avoid infinite recursion if language not found.  */
    9468       506381 :       return lookup_compiler (NULL, 0, cp->spec + 1);
    9469              :     }
    9470              :   return 0;
    9471              : }
    9472              : 
    9473              : static char *
    9474     46954900 : save_string (const char *s, int len)
    9475              : {
    9476     46954900 :   char *result = XNEWVEC (char, len + 1);
    9477              : 
    9478     46954900 :   gcc_checking_assert (strlen (s) >= (unsigned int) len);
    9479     46954900 :   memcpy (result, s, len);
    9480     46954900 :   result[len] = 0;
    9481     46954900 :   return result;
    9482              : }
    9483              : 
    9484              : 
    9485              : static inline void
    9486     47233925 : validate_switches_from_spec (const char *spec, bool user)
    9487              : {
    9488     47233925 :   const char *p = spec;
    9489     47233925 :   char c;
    9490    582958058 :   while ((c = *p++))
    9491    488490208 :     if (c == '%'
    9492    488490208 :         && (*p == '{'
    9493     11579930 :             || *p == '<'
    9494     10665725 :             || (*p == 'W' && *++p == '{')
    9495     10665725 :             || (*p == '@' && *++p == '{')))
    9496              :       /* We have a switch spec.  */
    9497     46929192 :       p = validate_switches (p + 1, user, *p == '{');
    9498     47233925 : }
    9499              : 
    9500              : static void
    9501       304735 : validate_all_switches (void)
    9502              : {
    9503       304735 :   struct compiler *comp;
    9504       304735 :   struct spec_list *spec;
    9505              : 
    9506     33216115 :   for (comp = compilers; comp->spec; comp++)
    9507     32911380 :     validate_switches_from_spec (comp->spec, false);
    9508              : 
    9509              :   /* Look through the linked list of specs read from the specs file.  */
    9510     14322545 :   for (spec = specs; spec; spec = spec->next)
    9511     14017810 :     validate_switches_from_spec (*spec->ptr_spec, spec->user_p);
    9512              : 
    9513       304735 :   validate_switches_from_spec (link_command_spec, false);
    9514       304735 : }
    9515              : 
    9516              : /* Look at the switch-name that comes after START and mark as valid
    9517              :    all supplied switches that match it.  If BRACED, handle other
    9518              :    switches after '|' and '&', and specs after ':' until ';' or '}',
    9519              :    going back for more switches after ';'.  Without BRACED, handle
    9520              :    only one atom.  Return a pointer to whatever follows the handled
    9521              :    items, after the closing brace if BRACED.  */
    9522              : 
    9523              : static const char *
    9524    202953512 : validate_switches (const char *start, bool user_spec, bool braced)
    9525              : {
    9526    202953512 :   const char *p = start;
    9527    261767367 :   const char *atom;
    9528    261767367 :   size_t len;
    9529    261767367 :   int i;
    9530    261767367 :   bool suffix;
    9531    261767367 :   bool starred;
    9532              : 
    9533              : #define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
    9534              : 
    9535    261767367 : next_member:
    9536    261767367 :   suffix = false;
    9537    261767367 :   starred = false;
    9538              : 
    9539    289193517 :   SKIP_WHITE ();
    9540              : 
    9541    261767367 :   if (*p == '!')
    9542     81059511 :     p++;
    9543              : 
    9544    261767367 :   SKIP_WHITE ();
    9545    261767367 :   if (*p == '.' || *p == ',')
    9546            0 :     suffix = true, p++;
    9547              : 
    9548    261767367 :   atom = p;
    9549    261767367 :   while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
    9550   1752531001 :          || *p == ',' || *p == '.' || *p == '@')
    9551   1490763634 :     p++;
    9552    261767367 :   len = p - atom;
    9553              : 
    9554    261767367 :   if (*p == '*')
    9555     69174845 :     starred = true, p++;
    9556              : 
    9557    262986307 :   SKIP_WHITE ();
    9558              : 
    9559    261767367 :   if (!suffix)
    9560              :     {
    9561              :       /* Mark all matching switches as valid.  */
    9562   6125244703 :       for (i = 0; i < n_switches; i++)
    9563   5863477336 :         if (!strncmp (switches[i].part1, atom, len)
    9564    487916743 :             && (starred || switches[i].part1[len] == '\0')
    9565     50709249 :             && (switches[i].known || user_spec))
    9566     50706771 :               switches[i].validated = true;
    9567              :     }
    9568              : 
    9569    261767367 :   if (!braced)
    9570              :     return p;
    9571              : 
    9572    260243692 :   if (*p) p++;
    9573    260243692 :   if (*p && (p[-1] == '|' || p[-1] == '&'))
    9574     40225020 :     goto next_member;
    9575              : 
    9576    220018672 :   if (*p && p[-1] == ':')
    9577              :     {
    9578   2954710556 :       while (*p && *p != ';' && *p != '}')
    9579              :         {
    9580   2784973158 :           if (*p == '%')
    9581              :             {
    9582    262072100 :               p++;
    9583    262072100 :               if (*p == '{' || *p == '<')
    9584    153281705 :                 p = validate_switches (p+1, user_spec, *p == '{');
    9585    108790395 :               else if (p[0] == 'W' && p[1] == '{')
    9586      2437880 :                 p = validate_switches (p+2, user_spec, true);
    9587    106352515 :               else if (p[0] == '@' && p[1] == '{')
    9588       304735 :                 p = validate_switches (p+2, user_spec, true);
    9589              :             }
    9590              :           else
    9591   2522901058 :             p++;
    9592              :         }
    9593              : 
    9594    169737398 :       if (*p) p++;
    9595    169737398 :       if (*p && p[-1] == ';')
    9596     18588835 :         goto next_member;
    9597              :     }
    9598              : 
    9599              :   return p;
    9600              : #undef SKIP_WHITE
    9601              : }
    9602              : 
    9603              : struct mdswitchstr
    9604              : {
    9605              :   const char *str;
    9606              :   int len;
    9607              : };
    9608              : 
    9609              : static struct mdswitchstr *mdswitches;
    9610              : static int n_mdswitches;
    9611              : 
    9612              : /* Check whether a particular argument was used.  The first time we
    9613              :    canonicalize the switches to keep only the ones we care about.  */
    9614              : 
    9615              : struct used_arg_t
    9616              : {
    9617              :  public:
    9618              :   int operator () (const char *p, int len);
    9619              :   void finalize ();
    9620              : 
    9621              :  private:
    9622              :   struct mswitchstr
    9623              :   {
    9624              :     const char *str;
    9625              :     const char *replace;
    9626              :     int len;
    9627              :     int rep_len;
    9628              :   };
    9629              : 
    9630              :   mswitchstr *mswitches;
    9631              :   int n_mswitches;
    9632              : 
    9633              : };
    9634              : 
    9635              : used_arg_t used_arg;
    9636              : 
    9637              : int
    9638      1841871 : used_arg_t::operator () (const char *p, int len)
    9639              : {
    9640      1841871 :   int i, j;
    9641              : 
    9642      1841871 :   if (!mswitches)
    9643              :     {
    9644       304735 :       struct mswitchstr *matches;
    9645       304735 :       const char *q;
    9646       304735 :       int cnt = 0;
    9647              : 
    9648              :       /* Break multilib_matches into the component strings of string
    9649              :          and replacement string.  */
    9650      5180495 :       for (q = multilib_matches; *q != '\0'; q++)
    9651      4875760 :         if (*q == ';')
    9652       609470 :           cnt++;
    9653              : 
    9654       304735 :       matches
    9655       304735 :         = (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
    9656       304735 :       i = 0;
    9657       304735 :       q = multilib_matches;
    9658       914205 :       while (*q != '\0')
    9659              :         {
    9660       609470 :           matches[i].str = q;
    9661      2437880 :           while (*q != ' ')
    9662              :             {
    9663      1828410 :               if (*q == '\0')
    9664              :                 {
    9665            0 :                 invalid_matches:
    9666            0 :                   fatal_error (input_location, "multilib spec %qs is invalid",
    9667              :                                multilib_matches);
    9668              :                 }
    9669      1828410 :               q++;
    9670              :             }
    9671       609470 :           matches[i].len = q - matches[i].str;
    9672              : 
    9673       609470 :           matches[i].replace = ++q;
    9674      2437880 :           while (*q != ';' && *q != '\0')
    9675              :             {
    9676      1828410 :               if (*q == ' ')
    9677            0 :                 goto invalid_matches;
    9678      1828410 :               q++;
    9679              :             }
    9680       609470 :           matches[i].rep_len = q - matches[i].replace;
    9681       609470 :           i++;
    9682       609470 :           if (*q == ';')
    9683       609470 :             q++;
    9684              :         }
    9685              : 
    9686              :       /* Now build a list of the replacement string for switches that we care
    9687              :          about.  Make sure we allocate at least one entry.  This prevents
    9688              :          xmalloc from calling fatal, and prevents us from re-executing this
    9689              :          block of code.  */
    9690       304735 :       mswitches
    9691       609470 :         = XNEWVEC (struct mswitchstr, n_mdswitches + (n_switches ? n_switches : 1));
    9692      7130669 :       for (i = 0; i < n_switches; i++)
    9693      6825934 :         if ((switches[i].live_cond & SWITCH_IGNORE) == 0)
    9694              :           {
    9695      6825928 :             int xlen = strlen (switches[i].part1);
    9696     20464966 :             for (j = 0; j < cnt; j++)
    9697     13649421 :               if (xlen == matches[j].len
    9698        19193 :                   && ! strncmp (switches[i].part1, matches[j].str, xlen))
    9699              :                 {
    9700        10383 :                   mswitches[n_mswitches].str = matches[j].replace;
    9701        10383 :                   mswitches[n_mswitches].len = matches[j].rep_len;
    9702        10383 :                   mswitches[n_mswitches].replace = (char *) 0;
    9703        10383 :                   mswitches[n_mswitches].rep_len = 0;
    9704        10383 :                   n_mswitches++;
    9705        10383 :                   break;
    9706              :                 }
    9707              :           }
    9708              : 
    9709              :       /* Add MULTILIB_DEFAULTS switches too, as long as they were not present
    9710              :          on the command line nor any options mutually incompatible with
    9711              :          them.  */
    9712       609470 :       for (i = 0; i < n_mdswitches; i++)
    9713              :         {
    9714       304735 :           const char *r;
    9715              : 
    9716       609470 :           for (q = multilib_options; *q != '\0'; *q && q++)
    9717              :             {
    9718       304735 :               while (*q == ' ')
    9719            0 :                 q++;
    9720              : 
    9721       304735 :               r = q;
    9722       304735 :               while (strncmp (q, mdswitches[i].str, mdswitches[i].len) != 0
    9723       304735 :                      || strchr (" /", q[mdswitches[i].len]) == NULL)
    9724              :                 {
    9725            0 :                   while (*q != ' ' && *q != '/' && *q != '\0')
    9726            0 :                     q++;
    9727            0 :                   if (*q != '/')
    9728              :                     break;
    9729            0 :                   q++;
    9730              :                 }
    9731              : 
    9732       304735 :               if (*q != ' ' && *q != '\0')
    9733              :                 {
    9734       607035 :                   while (*r != ' ' && *r != '\0')
    9735              :                     {
    9736              :                       q = r;
    9737      2428140 :                       while (*q != ' ' && *q != '/' && *q != '\0')
    9738      1821105 :                         q++;
    9739              : 
    9740       607035 :                       if (used_arg (r, q - r))
    9741              :                         break;
    9742              : 
    9743       596652 :                       if (*q != '/')
    9744              :                         {
    9745       294352 :                           mswitches[n_mswitches].str = mdswitches[i].str;
    9746       294352 :                           mswitches[n_mswitches].len = mdswitches[i].len;
    9747       294352 :                           mswitches[n_mswitches].replace = (char *) 0;
    9748       294352 :                           mswitches[n_mswitches].rep_len = 0;
    9749       294352 :                           n_mswitches++;
    9750       294352 :                           break;
    9751              :                         }
    9752              : 
    9753       302300 :                       r = q + 1;
    9754              :                     }
    9755              :                   break;
    9756              :                 }
    9757              :             }
    9758              :         }
    9759              :     }
    9760              : 
    9761      2467237 :   for (i = 0; i < n_mswitches; i++)
    9762      1253167 :     if (len == mswitches[i].len && ! strncmp (p, mswitches[i].str, len))
    9763              :       return 1;
    9764              : 
    9765              :   return 0;
    9766              : }
    9767              : 
    9768         1134 : void used_arg_t::finalize ()
    9769              : {
    9770         1134 :   XDELETEVEC (mswitches);
    9771         1134 :   mswitches = NULL;
    9772         1134 :   n_mswitches = 0;
    9773         1134 : }
    9774              : 
    9775              : 
    9776              : static int
    9777      1262680 : default_arg (const char *p, int len)
    9778              : {
    9779      1262680 :   int i;
    9780              : 
    9781      1887059 :   for (i = 0; i < n_mdswitches; i++)
    9782      1262680 :     if (len == mdswitches[i].len && ! strncmp (p, mdswitches[i].str, len))
    9783              :       return 1;
    9784              : 
    9785              :   return 0;
    9786              : }
    9787              : 
    9788              : /* Use multilib_dir as key to find corresponding multilib_os_dir and
    9789              :    multiarch_dir.  */
    9790              : 
    9791              : static void
    9792            0 : find_multilib_os_dir_by_multilib_dir (const char *multilib_dir,
    9793              :                                       const char **p_multilib_os_dir,
    9794              :                                       const char **p_multiarch_dir)
    9795              : {
    9796            0 :   const char *p = multilib_select;
    9797            0 :   unsigned int this_path_len;
    9798            0 :   const char *this_path;
    9799            0 :   int ok = 0;
    9800              : 
    9801            0 :   while (*p != '\0')
    9802              :     {
    9803              :       /* Ignore newlines.  */
    9804            0 :       if (*p == '\n')
    9805              :         {
    9806            0 :           ++p;
    9807            0 :           continue;
    9808              :         }
    9809              : 
    9810              :       /* Get the initial path.  */
    9811              :       this_path = p;
    9812            0 :       while (*p != ' ')
    9813              :         {
    9814            0 :           if (*p == '\0')
    9815              :             {
    9816            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
    9817              :                            multilib_select, multilib_reuse);
    9818              :             }
    9819            0 :           ++p;
    9820              :         }
    9821            0 :       this_path_len = p - this_path;
    9822              : 
    9823            0 :       ok = 0;
    9824              : 
    9825              :       /* Skip any arguments, we don't care at this stage.  */
    9826            0 :       while (*++p != ';');
    9827              : 
    9828            0 :       if (this_path_len != 1
    9829            0 :           || this_path[0] != '.')
    9830              :         {
    9831            0 :           char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
    9832            0 :           char *q;
    9833              : 
    9834            0 :           strncpy (new_multilib_dir, this_path, this_path_len);
    9835            0 :           new_multilib_dir[this_path_len] = '\0';
    9836            0 :           q = strchr (new_multilib_dir, ':');
    9837            0 :           if (q != NULL)
    9838            0 :             *q = '\0';
    9839              : 
    9840            0 :           if (strcmp (new_multilib_dir, multilib_dir) == 0)
    9841            0 :             ok = 1;
    9842              :         }
    9843              : 
    9844              :       /* Found matched multilib_dir, update multilib_os_dir and
    9845              :          multiarch_dir.  */
    9846            0 :       if (ok)
    9847              :         {
    9848            0 :           const char *q = this_path, *end = this_path + this_path_len;
    9849              : 
    9850            0 :           while (q < end && *q != ':')
    9851            0 :             q++;
    9852            0 :           if (q < end)
    9853              :             {
    9854            0 :               const char *q2 = q + 1, *ml_end = end;
    9855            0 :               char *new_multilib_os_dir;
    9856              : 
    9857            0 :               while (q2 < end && *q2 != ':')
    9858            0 :                 q2++;
    9859            0 :               if (*q2 == ':')
    9860            0 :                 ml_end = q2;
    9861            0 :               if (ml_end - q == 1)
    9862            0 :                 *p_multilib_os_dir = xstrdup (".");
    9863              :               else
    9864              :                 {
    9865            0 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
    9866            0 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
    9867            0 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
    9868            0 :                   *p_multilib_os_dir = new_multilib_os_dir;
    9869              :                 }
    9870              : 
    9871            0 :               if (q2 < end && *q2 == ':')
    9872              :                 {
    9873            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
    9874            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
    9875            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
    9876            0 :                   *p_multiarch_dir = new_multiarch_dir;
    9877              :                 }
    9878              :               break;
    9879              :             }
    9880              :         }
    9881            0 :       ++p;
    9882              :     }
    9883            0 : }
    9884              : 
    9885              : /* Work out the subdirectory to use based on the options. The format of
    9886              :    multilib_select is a list of elements. Each element is a subdirectory
    9887              :    name followed by a list of options followed by a semicolon. The format
    9888              :    of multilib_exclusions is the same, but without the preceding
    9889              :    directory. First gcc will check the exclusions, if none of the options
    9890              :    beginning with an exclamation point are present, and all of the other
    9891              :    options are present, then we will ignore this completely. Passing
    9892              :    that, gcc will consider each multilib_select in turn using the same
    9893              :    rules for matching the options. If a match is found, that subdirectory
    9894              :    will be used.
    9895              :    A subdirectory name is optionally followed by a colon and the corresponding
    9896              :    multiarch name.  */
    9897              : 
    9898              : static void
    9899       304735 : set_multilib_dir (void)
    9900              : {
    9901       304735 :   const char *p;
    9902       304735 :   unsigned int this_path_len;
    9903       304735 :   const char *this_path, *this_arg;
    9904       304735 :   const char *start, *end;
    9905       304735 :   int not_arg;
    9906       304735 :   int ok, ndfltok, first;
    9907              : 
    9908       304735 :   n_mdswitches = 0;
    9909       304735 :   start = multilib_defaults;
    9910       304735 :   while (*start == ' ' || *start == '\t')
    9911            0 :     start++;
    9912       609470 :   while (*start != '\0')
    9913              :     {
    9914       304735 :       n_mdswitches++;
    9915      1218940 :       while (*start != ' ' && *start != '\t' && *start != '\0')
    9916       914205 :         start++;
    9917       304735 :       while (*start == ' ' || *start == '\t')
    9918            0 :         start++;
    9919              :     }
    9920              : 
    9921       304735 :   if (n_mdswitches)
    9922              :     {
    9923       304735 :       int i = 0;
    9924              : 
    9925       304735 :       mdswitches = XNEWVEC (struct mdswitchstr, n_mdswitches);
    9926       304735 :       for (start = multilib_defaults; *start != '\0'; start = end + 1)
    9927              :         {
    9928       304735 :           while (*start == ' ' || *start == '\t')
    9929            0 :             start++;
    9930              : 
    9931       304735 :           if (*start == '\0')
    9932              :             break;
    9933              : 
    9934       914205 :           for (end = start + 1;
    9935       914205 :                *end != ' ' && *end != '\t' && *end != '\0'; end++)
    9936              :             ;
    9937              : 
    9938       304735 :           obstack_grow (&multilib_obstack, start, end - start);
    9939       304735 :           obstack_1grow (&multilib_obstack, 0);
    9940       304735 :           mdswitches[i].str = XOBFINISH (&multilib_obstack, const char *);
    9941       304735 :           mdswitches[i++].len = end - start;
    9942              : 
    9943       304735 :           if (*end == '\0')
    9944              :             break;
    9945              :         }
    9946              :     }
    9947              : 
    9948       304735 :   p = multilib_exclusions;
    9949       304735 :   while (*p != '\0')
    9950              :     {
    9951              :       /* Ignore newlines.  */
    9952            0 :       if (*p == '\n')
    9953              :         {
    9954            0 :           ++p;
    9955            0 :           continue;
    9956              :         }
    9957              : 
    9958              :       /* Check the arguments.  */
    9959              :       ok = 1;
    9960            0 :       while (*p != ';')
    9961              :         {
    9962            0 :           if (*p == '\0')
    9963              :             {
    9964            0 :             invalid_exclusions:
    9965            0 :               fatal_error (input_location, "multilib exclusions %qs is invalid",
    9966              :                            multilib_exclusions);
    9967              :             }
    9968              : 
    9969            0 :           if (! ok)
    9970              :             {
    9971            0 :               ++p;
    9972            0 :               continue;
    9973              :             }
    9974              : 
    9975            0 :           this_arg = p;
    9976            0 :           while (*p != ' ' && *p != ';')
    9977              :             {
    9978            0 :               if (*p == '\0')
    9979            0 :                 goto invalid_exclusions;
    9980            0 :               ++p;
    9981              :             }
    9982              : 
    9983            0 :           if (*this_arg != '!')
    9984              :             not_arg = 0;
    9985              :           else
    9986              :             {
    9987            0 :               not_arg = 1;
    9988            0 :               ++this_arg;
    9989              :             }
    9990              : 
    9991            0 :           ok = used_arg (this_arg, p - this_arg);
    9992            0 :           if (not_arg)
    9993            0 :             ok = ! ok;
    9994              : 
    9995            0 :           if (*p == ' ')
    9996            0 :             ++p;
    9997              :         }
    9998              : 
    9999            0 :       if (ok)
   10000              :         return;
   10001              : 
   10002            0 :       ++p;
   10003              :     }
   10004              : 
   10005       304735 :   first = 1;
   10006       304735 :   p = multilib_select;
   10007              : 
   10008              :   /* Append multilib reuse rules if any.  With those rules, we can reuse
   10009              :      one multilib for certain different options sets.  */
   10010       304735 :   if (strlen (multilib_reuse) > 0)
   10011            0 :     p = concat (p, multilib_reuse, NULL);
   10012              : 
   10013       617418 :   while (*p != '\0')
   10014              :     {
   10015              :       /* Ignore newlines.  */
   10016       617418 :       if (*p == '\n')
   10017              :         {
   10018            0 :           ++p;
   10019            0 :           continue;
   10020              :         }
   10021              : 
   10022              :       /* Get the initial path.  */
   10023              :       this_path = p;
   10024      4345770 :       while (*p != ' ')
   10025              :         {
   10026      3728352 :           if (*p == '\0')
   10027              :             {
   10028            0 :             invalid_select:
   10029            0 :               fatal_error (input_location, "multilib select %qs %qs is invalid",
   10030              :                            multilib_select, multilib_reuse);
   10031              :             }
   10032      3728352 :           ++p;
   10033              :         }
   10034       617418 :       this_path_len = p - this_path;
   10035              : 
   10036              :       /* Check the arguments.  */
   10037       617418 :       ok = 1;
   10038       617418 :       ndfltok = 1;
   10039       617418 :       ++p;
   10040      1852254 :       while (*p != ';')
   10041              :         {
   10042      1234836 :           if (*p == '\0')
   10043            0 :             goto invalid_select;
   10044              : 
   10045      1234836 :           if (! ok)
   10046              :             {
   10047            0 :               ++p;
   10048            0 :               continue;
   10049              :             }
   10050              : 
   10051      5861497 :           this_arg = p;
   10052      5861497 :           while (*p != ' ' && *p != ';')
   10053              :             {
   10054      4626661 :               if (*p == '\0')
   10055            0 :                 goto invalid_select;
   10056      4626661 :               ++p;
   10057              :             }
   10058              : 
   10059      1234836 :           if (*this_arg != '!')
   10060              :             not_arg = 0;
   10061              :           else
   10062              :             {
   10063       922153 :               not_arg = 1;
   10064       922153 :               ++this_arg;
   10065              :             }
   10066              : 
   10067              :           /* If this is a default argument, we can just ignore it.
   10068              :              This is true even if this_arg begins with '!'.  Beginning
   10069              :              with '!' does not mean that this argument is necessarily
   10070              :              inappropriate for this library: it merely means that
   10071              :              there is a more specific library which uses this
   10072              :              argument.  If this argument is a default, we need not
   10073              :              consider that more specific library.  */
   10074      1234836 :           ok = used_arg (this_arg, p - this_arg);
   10075      1234836 :           if (not_arg)
   10076       922153 :             ok = ! ok;
   10077              : 
   10078      1234836 :           if (! ok)
   10079       320631 :             ndfltok = 0;
   10080              : 
   10081      1234836 :           if (default_arg (this_arg, p - this_arg))
   10082       617418 :             ok = 1;
   10083              : 
   10084      1234836 :           if (*p == ' ')
   10085       617418 :             ++p;
   10086              :         }
   10087              : 
   10088       617418 :       if (ok && first)
   10089              :         {
   10090       304735 :           if (this_path_len != 1
   10091       296787 :               || this_path[0] != '.')
   10092              :             {
   10093         7948 :               char *new_multilib_dir = XNEWVEC (char, this_path_len + 1);
   10094         7948 :               char *q;
   10095              : 
   10096         7948 :               strncpy (new_multilib_dir, this_path, this_path_len);
   10097         7948 :               new_multilib_dir[this_path_len] = '\0';
   10098         7948 :               q = strchr (new_multilib_dir, ':');
   10099         7948 :               if (q != NULL)
   10100         7948 :                 *q = '\0';
   10101         7948 :               multilib_dir = new_multilib_dir;
   10102              :             }
   10103              :           first = 0;
   10104              :         }
   10105              : 
   10106       617418 :       if (ndfltok)
   10107              :         {
   10108       304735 :           const char *q = this_path, *end = this_path + this_path_len;
   10109              : 
   10110       914205 :           while (q < end && *q != ':')
   10111       609470 :             q++;
   10112       304735 :           if (q < end)
   10113              :             {
   10114       304735 :               const char *q2 = q + 1, *ml_end = end;
   10115       304735 :               char *new_multilib_os_dir;
   10116              : 
   10117      2726719 :               while (q2 < end && *q2 != ':')
   10118      2421984 :                 q2++;
   10119       304735 :               if (*q2 == ':')
   10120            0 :                 ml_end = q2;
   10121       304735 :               if (ml_end - q == 1)
   10122            0 :                 multilib_os_dir = xstrdup (".");
   10123              :               else
   10124              :                 {
   10125       304735 :                   new_multilib_os_dir = XNEWVEC (char, ml_end - q);
   10126       304735 :                   memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1);
   10127       304735 :                   new_multilib_os_dir[ml_end - q - 1] = '\0';
   10128       304735 :                   multilib_os_dir = new_multilib_os_dir;
   10129              :                 }
   10130              : 
   10131       304735 :               if (q2 < end && *q2 == ':')
   10132              :                 {
   10133            0 :                   char *new_multiarch_dir = XNEWVEC (char, end - q2);
   10134            0 :                   memcpy (new_multiarch_dir, q2 + 1, end - q2 - 1);
   10135            0 :                   new_multiarch_dir[end - q2 - 1] = '\0';
   10136            0 :                   multiarch_dir = new_multiarch_dir;
   10137              :                 }
   10138              :               break;
   10139              :             }
   10140              :         }
   10141              : 
   10142       312683 :       ++p;
   10143              :     }
   10144              : 
   10145       609470 :   multilib_dir =
   10146       304735 :     targetm_common.compute_multilib (
   10147              :       switches,
   10148              :       n_switches,
   10149              :       multilib_dir,
   10150              :       multilib_defaults,
   10151              :       multilib_select,
   10152              :       multilib_matches,
   10153              :       multilib_exclusions,
   10154              :       multilib_reuse);
   10155              : 
   10156       304735 :   if (multilib_dir == NULL && multilib_os_dir != NULL
   10157       296787 :       && strcmp (multilib_os_dir, ".") == 0)
   10158              :     {
   10159            0 :       free (const_cast<char *> (multilib_os_dir));
   10160            0 :       multilib_os_dir = NULL;
   10161              :     }
   10162       304735 :   else if (multilib_dir != NULL && multilib_os_dir == NULL)
   10163              :     {
   10164              :       /* Give second chance to search matched multilib_os_dir again by matching
   10165              :          the multilib_dir since some target may use TARGET_COMPUTE_MULTILIB
   10166              :          hook rather than the builtin way.  */
   10167            0 :       find_multilib_os_dir_by_multilib_dir (multilib_dir, &multilib_os_dir,
   10168              :                                             &multiarch_dir);
   10169              : 
   10170            0 :       if (multilib_os_dir == NULL)
   10171            0 :         multilib_os_dir = multilib_dir;
   10172              :     }
   10173              : }
   10174              : 
   10175              : /* Print out the multiple library subdirectory selection
   10176              :    information.  This prints out a series of lines.  Each line looks
   10177              :    like SUBDIRECTORY;@OPTION@OPTION, with as many options as is
   10178              :    required.  Only the desired options are printed out, the negative
   10179              :    matches.  The options are print without a leading dash.  There are
   10180              :    no spaces to make it easy to use the information in the shell.
   10181              :    Each subdirectory is printed only once.  This assumes the ordering
   10182              :    generated by the genmultilib script. Also, we leave out ones that match
   10183              :    the exclusions.  */
   10184              : 
   10185              : static void
   10186         6961 : print_multilib_info (void)
   10187              : {
   10188         6961 :   const char *p = multilib_select;
   10189         6961 :   const char *last_path = 0, *this_path;
   10190         6961 :   int skip;
   10191         6961 :   int not_arg;
   10192         6961 :   unsigned int last_path_len = 0;
   10193              : 
   10194        27844 :   while (*p != '\0')
   10195              :     {
   10196        20883 :       skip = 0;
   10197              :       /* Ignore newlines.  */
   10198        20883 :       if (*p == '\n')
   10199              :         {
   10200            0 :           ++p;
   10201            0 :           continue;
   10202              :         }
   10203              : 
   10204              :       /* Get the initial path.  */
   10205              :       this_path = p;
   10206       167064 :       while (*p != ' ')
   10207              :         {
   10208       146181 :           if (*p == '\0')
   10209              :             {
   10210            0 :             invalid_select:
   10211            0 :               fatal_error (input_location,
   10212              :                            "multilib select %qs is invalid", multilib_select);
   10213              :             }
   10214              : 
   10215       146181 :           ++p;
   10216              :         }
   10217              : 
   10218              :       /* When --disable-multilib was used but target defines
   10219              :          MULTILIB_OSDIRNAMES, entries starting with .: (and not starting
   10220              :          with .:: for multiarch configurations) are there just to find
   10221              :          multilib_os_dir, so skip them from output.  */
   10222        20883 :       if (this_path[0] == '.' && this_path[1] == ':' && this_path[2] != ':')
   10223        20883 :         skip = 1;
   10224              : 
   10225              :       /* Check for matches with the multilib_exclusions. We don't bother
   10226              :          with the '!' in either list. If any of the exclusion rules match
   10227              :          all of its options with the select rule, we skip it.  */
   10228        20883 :       {
   10229        20883 :         const char *e = multilib_exclusions;
   10230        20883 :         const char *this_arg;
   10231              : 
   10232        20883 :         while (*e != '\0')
   10233              :           {
   10234            0 :             int m = 1;
   10235              :             /* Ignore newlines.  */
   10236            0 :             if (*e == '\n')
   10237              :               {
   10238            0 :                 ++e;
   10239            0 :                 continue;
   10240              :               }
   10241              : 
   10242              :             /* Check the arguments.  */
   10243            0 :             while (*e != ';')
   10244              :               {
   10245            0 :                 const char *q;
   10246            0 :                 int mp = 0;
   10247              : 
   10248            0 :                 if (*e == '\0')
   10249              :                   {
   10250            0 :                   invalid_exclusion:
   10251            0 :                     fatal_error (input_location,
   10252              :                                  "multilib exclusion %qs is invalid",
   10253              :                                  multilib_exclusions);
   10254              :                   }
   10255              : 
   10256            0 :                 if (! m)
   10257              :                   {
   10258            0 :                     ++e;
   10259            0 :                     continue;
   10260              :                   }
   10261              : 
   10262              :                 this_arg = e;
   10263              : 
   10264            0 :                 while (*e != ' ' && *e != ';')
   10265              :                   {
   10266            0 :                     if (*e == '\0')
   10267            0 :                       goto invalid_exclusion;
   10268            0 :                     ++e;
   10269              :                   }
   10270              : 
   10271            0 :                 q = p + 1;
   10272            0 :                 while (*q != ';')
   10273              :                   {
   10274            0 :                     const char *arg;
   10275            0 :                     int len = e - this_arg;
   10276              : 
   10277            0 :                     if (*q == '\0')
   10278            0 :                       goto invalid_select;
   10279              : 
   10280              :                     arg = q;
   10281              : 
   10282            0 :                     while (*q != ' ' && *q != ';')
   10283              :                       {
   10284            0 :                         if (*q == '\0')
   10285            0 :                           goto invalid_select;
   10286            0 :                         ++q;
   10287              :                       }
   10288              : 
   10289            0 :                     if (! strncmp (arg, this_arg,
   10290            0 :                                    (len < q - arg) ? q - arg : len)
   10291            0 :                         || default_arg (this_arg, e - this_arg))
   10292              :                       {
   10293              :                         mp = 1;
   10294              :                         break;
   10295              :                       }
   10296              : 
   10297            0 :                     if (*q == ' ')
   10298            0 :                       ++q;
   10299              :                   }
   10300              : 
   10301            0 :                 if (! mp)
   10302            0 :                   m = 0;
   10303              : 
   10304            0 :                 if (*e == ' ')
   10305            0 :                   ++e;
   10306              :               }
   10307              : 
   10308            0 :             if (m)
   10309              :               {
   10310              :                 skip = 1;
   10311              :                 break;
   10312              :               }
   10313              : 
   10314            0 :             if (*e != '\0')
   10315            0 :               ++e;
   10316              :           }
   10317              :       }
   10318              : 
   10319        20883 :       if (! skip)
   10320              :         {
   10321              :           /* If this is a duplicate, skip it.  */
   10322        41766 :           skip = (last_path != 0
   10323        13922 :                   && (unsigned int) (p - this_path) == last_path_len
   10324        20883 :                   && ! filename_ncmp (last_path, this_path, last_path_len));
   10325              : 
   10326        20883 :           last_path = this_path;
   10327        20883 :           last_path_len = p - this_path;
   10328              :         }
   10329              : 
   10330              :       /* If all required arguments are default arguments, and no default
   10331              :          arguments appear in the ! argument list, then we can skip it.
   10332              :          We will already have printed a directory identical to this one
   10333              :          which does not require that default argument.  */
   10334        20883 :       if (! skip)
   10335              :         {
   10336        20883 :           const char *q;
   10337        20883 :           bool default_arg_ok = false;
   10338              : 
   10339        20883 :           q = p + 1;
   10340        34805 :           while (*q != ';')
   10341              :             {
   10342        27844 :               const char *arg;
   10343              : 
   10344        27844 :               if (*q == '\0')
   10345            0 :                 goto invalid_select;
   10346              : 
   10347        27844 :               if (*q == '!')
   10348              :                 {
   10349        20883 :                   not_arg = 1;
   10350        20883 :                   q++;
   10351              :                 }
   10352              :               else
   10353              :                 not_arg = 0;
   10354        27844 :               arg = q;
   10355              : 
   10356       111376 :               while (*q != ' ' && *q != ';')
   10357              :                 {
   10358        83532 :                   if (*q == '\0')
   10359            0 :                     goto invalid_select;
   10360        83532 :                   ++q;
   10361              :                 }
   10362              : 
   10363        27844 :               if (default_arg (arg, q - arg))
   10364              :                 {
   10365              :                   /* Stop checking if any default arguments appeared in not
   10366              :                      list.  */
   10367        20883 :                   if (not_arg)
   10368              :                     {
   10369              :                       default_arg_ok = false;
   10370              :                       break;
   10371              :                     }
   10372              : 
   10373              :                   default_arg_ok = true;
   10374              :                 }
   10375         6961 :               else if (!not_arg)
   10376              :                 {
   10377              :                   /* Stop checking if any required argument is not provided by
   10378              :                      default arguments.  */
   10379              :                   default_arg_ok = false;
   10380              :                   break;
   10381              :                 }
   10382              : 
   10383        13922 :               if (*q == ' ')
   10384         6961 :                 ++q;
   10385              :             }
   10386              : 
   10387              :           /* Make sure all default argument is OK for this multi-lib set.  */
   10388        20883 :           if (default_arg_ok)
   10389              :             skip = 1;
   10390              :           else
   10391              :             skip = 0;
   10392              :         }
   10393              : 
   10394              :       if (! skip)
   10395              :         {
   10396              :           const char *p1;
   10397              : 
   10398        34805 :           for (p1 = last_path; p1 < p && *p1 != ':'; p1++)
   10399        20883 :             putchar (*p1);
   10400        13922 :           putchar (';');
   10401              :         }
   10402              : 
   10403        20883 :       ++p;
   10404       104415 :       while (*p != ';')
   10405              :         {
   10406        83532 :           int use_arg;
   10407              : 
   10408        83532 :           if (*p == '\0')
   10409            0 :             goto invalid_select;
   10410              : 
   10411        83532 :           if (skip)
   10412              :             {
   10413        55688 :               ++p;
   10414        55688 :               continue;
   10415              :             }
   10416              : 
   10417        27844 :           use_arg = *p != '!';
   10418              : 
   10419        27844 :           if (use_arg)
   10420         6961 :             putchar ('@');
   10421              : 
   10422       132259 :           while (*p != ' ' && *p != ';')
   10423              :             {
   10424       104415 :               if (*p == '\0')
   10425            0 :                 goto invalid_select;
   10426       104415 :               if (use_arg)
   10427        20883 :                 putchar (*p);
   10428       104415 :               ++p;
   10429              :             }
   10430              : 
   10431        27844 :           if (*p == ' ')
   10432        13922 :             ++p;
   10433              :         }
   10434              : 
   10435        20883 :       if (! skip)
   10436              :         {
   10437              :           /* If there are extra options, print them now.  */
   10438        13922 :           if (multilib_extra && *multilib_extra)
   10439              :             {
   10440              :               int print_at = true;
   10441              :               const char *q;
   10442              : 
   10443            0 :               for (q = multilib_extra; *q != '\0'; q++)
   10444              :                 {
   10445            0 :                   if (*q == ' ')
   10446              :                     print_at = true;
   10447              :                   else
   10448              :                     {
   10449            0 :                       if (print_at)
   10450            0 :                         putchar ('@');
   10451            0 :                       putchar (*q);
   10452            0 :                       print_at = false;
   10453              :                     }
   10454              :                 }
   10455              :             }
   10456              : 
   10457        13922 :           putchar ('\n');
   10458              :         }
   10459              : 
   10460        20883 :       ++p;
   10461              :     }
   10462         6961 : }
   10463              : 
   10464              : /* getenv built-in spec function.
   10465              : 
   10466              :    Returns the value of the environment variable given by its first argument,
   10467              :    concatenated with the second argument.  If the variable is not defined, a
   10468              :    fatal error is issued unless such undefs are internally allowed, in which
   10469              :    case the variable name prefixed by a '/' is used as the variable value.
   10470              : 
   10471              :    The leading '/' allows using the result at a spot where a full path would
   10472              :    normally be expected and when the actual value doesn't really matter since
   10473              :    undef vars are allowed.  */
   10474              : 
   10475              : static const char *
   10476            0 : getenv_spec_function (int argc, const char **argv)
   10477              : {
   10478            0 :   const char *value;
   10479            0 :   const char *varname;
   10480              : 
   10481            0 :   char *result;
   10482            0 :   char *ptr;
   10483            0 :   size_t len;
   10484              : 
   10485            0 :   if (argc != 2)
   10486              :     return NULL;
   10487              : 
   10488            0 :   varname = argv[0];
   10489            0 :   value = env.get (varname);
   10490              : 
   10491              :   /* If the variable isn't defined and this is allowed, craft our expected
   10492              :      return value.  Assume variable names used in specs strings don't contain
   10493              :      any active spec character so don't need escaping.  */
   10494            0 :   if (!value && spec_undefvar_allowed)
   10495              :     {
   10496            0 :       result = XNEWVAR (char, strlen(varname) + 2);
   10497            0 :       sprintf (result, "/%s", varname);
   10498            0 :       return result;
   10499              :     }
   10500              : 
   10501            0 :   if (!value)
   10502            0 :     fatal_error (input_location,
   10503              :                  "environment variable %qs not defined", varname);
   10504              : 
   10505              :   /* We have to escape every character of the environment variable so
   10506              :      they are not interpreted as active spec characters.  A
   10507              :      particularly painful case is when we are reading a variable
   10508              :      holding a windows path complete with \ separators.  */
   10509            0 :   len = strlen (value) * 2 + strlen (argv[1]) + 1;
   10510            0 :   result = XNEWVAR (char, len);
   10511            0 :   for (ptr = result; *value; ptr += 2)
   10512              :     {
   10513            0 :       ptr[0] = '\\';
   10514            0 :       ptr[1] = *value++;
   10515              :     }
   10516              : 
   10517            0 :   strcpy (ptr, argv[1]);
   10518              : 
   10519            0 :   return result;
   10520              : }
   10521              : 
   10522              : /* if-exists built-in spec function.
   10523              : 
   10524              :    Checks to see if the file specified by the absolute pathname in
   10525              :    ARGS exists.  Returns that pathname if found.
   10526              : 
   10527              :    The usual use for this function is to check for a library file
   10528              :    (whose name has been expanded with %s).  */
   10529              : 
   10530              : static const char *
   10531            0 : if_exists_spec_function (int argc, const char **argv)
   10532              : {
   10533              :   /* Must have only one argument.  */
   10534            0 :   if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10535            0 :     return argv[0];
   10536              : 
   10537              :   return NULL;
   10538              : }
   10539              : 
   10540              : /* if-exists-else built-in spec function.
   10541              : 
   10542              :    This is like if-exists, but takes an additional argument which
   10543              :    is returned if the first argument does not exist.  */
   10544              : 
   10545              : static const char *
   10546            0 : if_exists_else_spec_function (int argc, const char **argv)
   10547              : {
   10548              :   /* Must have exactly two arguments.  */
   10549            0 :   if (argc != 2)
   10550              :     return NULL;
   10551              : 
   10552            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10553            0 :     return argv[0];
   10554              : 
   10555            0 :   return argv[1];
   10556              : }
   10557              : 
   10558              : /* if-exists-then-else built-in spec function.
   10559              : 
   10560              :    Checks to see if the file specified by the absolute pathname in
   10561              :    the first arg exists.  Returns the second arg if so, otherwise returns
   10562              :    the third arg if it is present.  */
   10563              : 
   10564              : static const char *
   10565            0 : if_exists_then_else_spec_function (int argc, const char **argv)
   10566              : {
   10567              : 
   10568              :   /* Must have two or three arguments.  */
   10569            0 :   if (argc != 2 && argc != 3)
   10570              :     return NULL;
   10571              : 
   10572            0 :   if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
   10573            0 :     return argv[1];
   10574              : 
   10575            0 :   if (argc == 3)
   10576            0 :     return argv[2];
   10577              : 
   10578              :   return NULL;
   10579              : }
   10580              : 
   10581              : /* sanitize built-in spec function.
   10582              : 
   10583              :    This returns non-NULL, if sanitizing address, thread or
   10584              :    any of the undefined behavior sanitizers.  */
   10585              : 
   10586              : static const char *
   10587       854352 : sanitize_spec_function (int argc, const char **argv)
   10588              : {
   10589       854352 :   if (argc != 1)
   10590              :     return NULL;
   10591              : 
   10592       854352 :   if (strcmp (argv[0], "address") == 0)
   10593       377066 :     return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL;
   10594       664496 :   if (strcmp (argv[0], "hwaddress") == 0)
   10595       379466 :     return (flag_sanitize & SANITIZE_USER_HWADDRESS) ? "" : NULL;
   10596       474640 :   if (strcmp (argv[0], "kernel-address") == 0)
   10597            0 :     return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL;
   10598       474640 :   if (strcmp (argv[0], "kernel-hwaddress") == 0)
   10599            0 :     return (flag_sanitize & SANITIZE_KERNEL_HWADDRESS) ? "" : NULL;
   10600       474640 :   if (strcmp (argv[0], "memtag-stack") == 0)
   10601            0 :     return (flag_sanitize & SANITIZE_MEMTAG_STACK) ? "" : NULL;
   10602       474640 :   if (strcmp (argv[0], "thread") == 0)
   10603       379264 :     return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
   10604       284784 :   if (strcmp (argv[0], "undefined") == 0)
   10605        94928 :     return ((flag_sanitize
   10606        94928 :              & ~flag_sanitize_trap
   10607        94928 :              & (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)))
   10608       187935 :            ? "" : NULL;
   10609       189856 :   if (strcmp (argv[0], "leak") == 0)
   10610       189856 :     return ((flag_sanitize
   10611       189856 :              & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
   10612       379712 :             == SANITIZE_LEAK) ? "" : NULL;
   10613              :   return NULL;
   10614              : }
   10615              : 
   10616              : /* replace-outfile built-in spec function.
   10617              : 
   10618              :    This looks for the first argument in the outfiles array's name and
   10619              :    replaces it with the second argument.  */
   10620              : 
   10621              : static const char *
   10622            0 : replace_outfile_spec_function (int argc, const char **argv)
   10623              : {
   10624            0 :   int i;
   10625              :   /* Must have exactly two arguments.  */
   10626            0 :   if (argc != 2)
   10627            0 :     abort ();
   10628              : 
   10629            0 :   for (i = 0; i < n_infiles; i++)
   10630              :     {
   10631            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10632            0 :         outfiles[i] = xstrdup (argv[1]);
   10633              :     }
   10634            0 :   return NULL;
   10635              : }
   10636              : 
   10637              : /* remove-outfile built-in spec function.
   10638              :  *
   10639              :  *    This looks for the first argument in the outfiles array's name and
   10640              :  *       removes it.  */
   10641              : 
   10642              : static const char *
   10643            0 : remove_outfile_spec_function (int argc, const char **argv)
   10644              : {
   10645            0 :   int i;
   10646              :   /* Must have exactly one argument.  */
   10647            0 :   if (argc != 1)
   10648            0 :     abort ();
   10649              : 
   10650            0 :   for (i = 0; i < n_infiles; i++)
   10651              :     {
   10652            0 :       if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
   10653            0 :         outfiles[i] = NULL;
   10654              :     }
   10655            0 :   return NULL;
   10656              : }
   10657              : 
   10658              : /* Given two version numbers, compares the two numbers.
   10659              :    A version number must match the regular expression
   10660              :    ([1-9][0-9]*|0)(\.([1-9][0-9]*|0))*
   10661              : */
   10662              : static int
   10663            0 : compare_version_strings (const char *v1, const char *v2)
   10664              : {
   10665            0 :   int rresult;
   10666            0 :   regex_t r;
   10667              : 
   10668            0 :   if (regcomp (&r, "^([1-9][0-9]*|0)(\\.([1-9][0-9]*|0))*$",
   10669              :                REG_EXTENDED | REG_NOSUB) != 0)
   10670            0 :     abort ();
   10671            0 :   rresult = regexec (&r, v1, 0, NULL, 0);
   10672            0 :   if (rresult == REG_NOMATCH)
   10673            0 :     fatal_error (input_location, "invalid version number %qs", v1);
   10674            0 :   else if (rresult != 0)
   10675            0 :     abort ();
   10676            0 :   rresult = regexec (&r, v2, 0, NULL, 0);
   10677            0 :   if (rresult == REG_NOMATCH)
   10678            0 :     fatal_error (input_location, "invalid version number %qs", v2);
   10679            0 :   else if (rresult != 0)
   10680            0 :     abort ();
   10681              : 
   10682            0 :   return strverscmp (v1, v2);
   10683              : }
   10684              : 
   10685              : 
   10686              : /* version_compare built-in spec function.
   10687              : 
   10688              :    This takes an argument of the following form:
   10689              : 
   10690              :    <comparison-op> <arg1> [<arg2>] <switch> <result>
   10691              : 
   10692              :    and produces "result" if the comparison evaluates to true,
   10693              :    and nothing if it doesn't.
   10694              : 
   10695              :    The supported <comparison-op> values are:
   10696              : 
   10697              :    >=  true if switch is a later (or same) version than arg1
   10698              :    !>  opposite of >=
   10699              :    <   true if switch is an earlier version than arg1
   10700              :    !<  opposite of <
   10701              :    ><  true if switch is arg1 or later, and earlier than arg2
   10702              :    <>  true if switch is earlier than arg1 or is arg2 or later
   10703              : 
   10704              :    If the switch is not present, the condition is false unless
   10705              :    the first character of the <comparison-op> is '!'.
   10706              : 
   10707              :    For example,
   10708              :    %:version-compare(>= 10.3 mmacosx-version-min= -lmx)
   10709              :    adds -lmx if -mmacosx-version-min=10.3.9 was passed.  */
   10710              : 
   10711              : static const char *
   10712            0 : version_compare_spec_function (int argc, const char **argv)
   10713              : {
   10714            0 :   int comp1, comp2;
   10715            0 :   size_t switch_len;
   10716            0 :   const char *switch_value = NULL;
   10717            0 :   int nargs = 1, i;
   10718            0 :   bool result;
   10719              : 
   10720            0 :   if (argc < 3)
   10721            0 :     fatal_error (input_location, "too few arguments to %%:version-compare");
   10722            0 :   if (argv[0][0] == '\0')
   10723            0 :     abort ();
   10724            0 :   if ((argv[0][1] == '<' || argv[0][1] == '>') && argv[0][0] != '!')
   10725            0 :     nargs = 2;
   10726            0 :   if (argc != nargs + 3)
   10727            0 :     fatal_error (input_location, "too many arguments to %%:version-compare");
   10728              : 
   10729            0 :   switch_len = strlen (argv[nargs + 1]);
   10730            0 :   for (i = 0; i < n_switches; i++)
   10731            0 :     if (!strncmp (switches[i].part1, argv[nargs + 1], switch_len)
   10732            0 :         && check_live_switch (i, switch_len))
   10733            0 :       switch_value = switches[i].part1 + switch_len;
   10734              : 
   10735            0 :   if (switch_value == NULL)
   10736              :     comp1 = comp2 = -1;
   10737              :   else
   10738              :     {
   10739            0 :       comp1 = compare_version_strings (switch_value, argv[1]);
   10740            0 :       if (nargs == 2)
   10741            0 :         comp2 = compare_version_strings (switch_value, argv[2]);
   10742              :       else
   10743              :         comp2 = -1;  /* This value unused.  */
   10744              :     }
   10745              : 
   10746            0 :   switch (argv[0][0] << 8 | argv[0][1])
   10747              :     {
   10748            0 :     case '>' << 8 | '=':
   10749            0 :       result = comp1 >= 0;
   10750            0 :       break;
   10751            0 :     case '!' << 8 | '<':
   10752            0 :       result = comp1 >= 0 || switch_value == NULL;
   10753            0 :       break;
   10754            0 :     case '<' << 8:
   10755            0 :       result = comp1 < 0;
   10756            0 :       break;
   10757            0 :     case '!' << 8 | '>':
   10758            0 :       result = comp1 < 0 || switch_value == NULL;
   10759            0 :       break;
   10760            0 :     case '>' << 8 | '<':
   10761            0 :       result = comp1 >= 0 && comp2 < 0;
   10762            0 :       break;
   10763            0 :     case '<' << 8 | '>':
   10764            0 :       result = comp1 < 0 || comp2 >= 0;
   10765            0 :       break;
   10766              : 
   10767            0 :     default:
   10768            0 :       fatal_error (input_location,
   10769              :                    "unknown operator %qs in %%:version-compare", argv[0]);
   10770              :     }
   10771            0 :   if (! result)
   10772              :     return NULL;
   10773              : 
   10774            0 :   return argv[nargs + 2];
   10775              : }
   10776              : 
   10777              : /* %:include builtin spec function.  This differs from %include in that it
   10778              :    can be nested inside a spec, and thus be conditionalized.  It takes
   10779              :    one argument, the filename, and looks for it in the startfile path.
   10780              :    The result is always NULL, i.e. an empty expansion.  */
   10781              : 
   10782              : static const char *
   10783        31176 : include_spec_function (int argc, const char **argv)
   10784              : {
   10785        31176 :   char *file;
   10786              : 
   10787        31176 :   if (argc != 1)
   10788            0 :     abort ();
   10789              : 
   10790        31176 :   file = find_a_file (&startfile_prefixes, argv[0], R_OK, true);
   10791        31176 :   read_specs (file ? file : argv[0], false, false);
   10792              : 
   10793        31176 :   return NULL;
   10794              : }
   10795              : 
   10796              : /* %:find-file spec function.  This function replaces its argument by
   10797              :     the file found through find_file, that is the -print-file-name gcc
   10798              :     program option. */
   10799              : static const char *
   10800            0 : find_file_spec_function (int argc, const char **argv)
   10801              : {
   10802            0 :   const char *file;
   10803              : 
   10804            0 :   if (argc != 1)
   10805            0 :     abort ();
   10806              : 
   10807            0 :   file = find_file (argv[0]);
   10808            0 :   return file;
   10809              : }
   10810              : 
   10811              : 
   10812              : /* %:find-plugindir spec function.  This function replaces its argument
   10813              :     by the -iplugindir=<dir> option.  `dir' is found through find_file, that
   10814              :     is the -print-file-name gcc program option. */
   10815              : static const char *
   10816          400 : find_plugindir_spec_function (int argc, const char **argv ATTRIBUTE_UNUSED)
   10817              : {
   10818          400 :   const char *option;
   10819              : 
   10820          400 :   if (argc != 0)
   10821            0 :     abort ();
   10822              : 
   10823          400 :   option = concat ("-iplugindir=", find_file ("plugin"), NULL);
   10824          400 :   return option;
   10825              : }
   10826              : 
   10827              : 
   10828              : /* %:print-asm-header spec function.  Print a banner to say that the
   10829              :    following output is from the assembler.  */
   10830              : 
   10831              : static const char *
   10832            0 : print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
   10833              :                                 const char **argv ATTRIBUTE_UNUSED)
   10834              : {
   10835            0 :   printf (_("Assembler options\n=================\n\n"));
   10836            0 :   printf (_("Use \"-Wa,OPTION\" to pass \"OPTION\" to the assembler.\n\n"));
   10837            0 :   fflush (stdout);
   10838            0 :   return NULL;
   10839              : }
   10840              : 
   10841              : /* Get a random number for -frandom-seed */
   10842              : 
   10843              : static unsigned HOST_WIDE_INT
   10844          620 : get_random_number (void)
   10845              : {
   10846          620 :   unsigned HOST_WIDE_INT ret = 0;
   10847          620 :   int fd;
   10848              : 
   10849          620 :   fd = open ("/dev/urandom", O_RDONLY);
   10850          620 :   if (fd >= 0)
   10851              :     {
   10852          620 :       read (fd, &ret, sizeof (HOST_WIDE_INT));
   10853          620 :       close (fd);
   10854          620 :       if (ret)
   10855              :         return ret;
   10856              :     }
   10857              : 
   10858              :   /* Get some more or less random data.  */
   10859              : #ifdef HAVE_GETTIMEOFDAY
   10860            0 :   {
   10861            0 :     struct timeval tv;
   10862              : 
   10863            0 :     gettimeofday (&tv, NULL);
   10864            0 :     ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
   10865              :   }
   10866              : #else
   10867              :   {
   10868              :     time_t now = time (NULL);
   10869              : 
   10870              :     if (now != (time_t)-1)
   10871              :       ret = (unsigned) now;
   10872              :   }
   10873              : #endif
   10874              : 
   10875            0 :   return ret ^ getpid ();
   10876              : }
   10877              : 
   10878              : /* %:compare-debug-dump-opt spec function.  Save the last argument,
   10879              :    expected to be the last -fdump-final-insns option, or generate a
   10880              :    temporary.  */
   10881              : 
   10882              : static const char *
   10883         1233 : compare_debug_dump_opt_spec_function (int arg,
   10884              :                                       const char **argv ATTRIBUTE_UNUSED)
   10885              : {
   10886         1233 :   char *ret;
   10887         1233 :   char *name;
   10888         1233 :   int which;
   10889         1233 :   static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
   10890              : 
   10891         1233 :   if (arg != 0)
   10892            0 :     fatal_error (input_location,
   10893              :                  "too many arguments to %%:compare-debug-dump-opt");
   10894              : 
   10895         1233 :   do_spec_2 ("%{fdump-final-insns=*:%*}", NULL);
   10896         1233 :   do_spec_1 (" ", 0, NULL);
   10897              : 
   10898         1233 :   if (argbuf.length () > 0
   10899         1233 :       && strcmp (argv[argbuf.length () - 1], ".") != 0)
   10900              :     {
   10901            0 :       if (!compare_debug)
   10902              :         return NULL;
   10903              : 
   10904            0 :       name = xstrdup (argv[argbuf.length () - 1]);
   10905            0 :       ret = NULL;
   10906              :     }
   10907              :   else
   10908              :     {
   10909         1233 :       if (argbuf.length () > 0)
   10910            6 :         do_spec_2 ("%B.gkd", NULL);
   10911         1227 :       else if (!compare_debug)
   10912              :         return NULL;
   10913              :       else
   10914         1227 :         do_spec_2 ("%{!save-temps*:%g.gkd}%{save-temps*:%B.gkd}", NULL);
   10915              : 
   10916         1233 :       do_spec_1 (" ", 0, NULL);
   10917              : 
   10918         1233 :       gcc_assert (argbuf.length () > 0);
   10919              : 
   10920         1233 :       name = xstrdup (argbuf.last ());
   10921              : 
   10922         1233 :       char *arg = quote_spec (xstrdup (name));
   10923         1233 :       ret = concat ("-fdump-final-insns=", arg, NULL);
   10924         1233 :       free (arg);
   10925              :     }
   10926              : 
   10927         1233 :   which = compare_debug < 0;
   10928         1233 :   debug_check_temp_file[which] = name;
   10929              : 
   10930         1233 :   if (!which)
   10931              :     {
   10932          620 :       unsigned HOST_WIDE_INT value = get_random_number ();
   10933              : 
   10934          620 :       sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
   10935              :     }
   10936              : 
   10937         1233 :   if (*random_seed)
   10938              :     {
   10939         1233 :       char *tmp = ret;
   10940         1233 :       ret = concat ("%{!frandom-seed=*:-frandom-seed=", random_seed, "} ",
   10941              :                     ret, NULL);
   10942         1233 :       free (tmp);
   10943              :     }
   10944              : 
   10945         1233 :   if (which)
   10946          613 :     *random_seed = 0;
   10947              : 
   10948              :   return ret;
   10949              : }
   10950              : 
   10951              : /* %:compare-debug-self-opt spec function.  Expands to the options
   10952              :     that are to be passed in the second compilation of
   10953              :     compare-debug.  */
   10954              : 
   10955              : static const char *
   10956         1238 : compare_debug_self_opt_spec_function (int arg,
   10957              :                                       const char **argv ATTRIBUTE_UNUSED)
   10958              : {
   10959         1238 :   if (arg != 0)
   10960            0 :     fatal_error (input_location,
   10961              :                  "too many arguments to %%:compare-debug-self-opt");
   10962              : 
   10963         1238 :   if (compare_debug >= 0)
   10964              :     return NULL;
   10965              : 
   10966          619 :   return concat ("\
   10967              : %<o %<MD %<MMD %<MF* %<MG %<MP %<MQ* %<MT* \
   10968              : %<fdump-final-insns=* -w -S -o %j \
   10969              : %{!fcompare-debug-second:-fcompare-debug-second} \
   10970          619 : ", compare_debug_opt, NULL);
   10971              : }
   10972              : 
   10973              : /* %:pass-through-libs spec function.  Finds all -l options and input
   10974              :    file names in the lib spec passed to it, and makes a list of them
   10975              :    prepended with the plugin option to cause them to be passed through
   10976              :    to the final link after all the new object files have been added.  */
   10977              : 
   10978              : const char *
   10979        89435 : pass_through_libs_spec_func (int argc, const char **argv)
   10980              : {
   10981        89435 :   char *prepended = xstrdup (" ");
   10982        89435 :   int n;
   10983              :   /* Shlemiel the painter's algorithm.  Innately horrible, but at least
   10984              :      we know that there will never be more than a handful of strings to
   10985              :      concat, and it's only once per run, so it's not worth optimising.  */
   10986       717913 :   for (n = 0; n < argc; n++)
   10987              :     {
   10988       628478 :       char *old = prepended;
   10989              :       /* Anything that isn't an option is a full path to an output
   10990              :          file; pass it through if it ends in '.a'.  Among options,
   10991              :          pass only -l.  */
   10992       628478 :       if (argv[n][0] == '-' && argv[n][1] == 'l')
   10993              :         {
   10994       585522 :           const char *lopt = argv[n] + 2;
   10995              :           /* Handle both joined and non-joined -l options.  If for any
   10996              :              reason there's a trailing -l with no joined or following
   10997              :              arg just discard it.  */
   10998       585522 :           if (!*lopt && ++n >= argc)
   10999              :             break;
   11000       585522 :           else if (!*lopt)
   11001            0 :             lopt = argv[n];
   11002       585522 :           prepended = concat (prepended, "-plugin-opt=-pass-through=-l",
   11003              :                 lopt, " ", NULL);
   11004       585522 :         }
   11005        42956 :       else if (!strcmp (".a", argv[n] + strlen (argv[n]) - 2))
   11006              :         {
   11007            0 :           prepended = concat (prepended, "-plugin-opt=-pass-through=",
   11008              :                 argv[n], " ", NULL);
   11009              :         }
   11010       628478 :       if (prepended != old)
   11011       585522 :         free (old);
   11012              :     }
   11013        89435 :   return prepended;
   11014              : }
   11015              : 
   11016              : static bool
   11017       518593 : not_actual_file_p (const char *name)
   11018              : {
   11019       518593 :   return (strcmp (name, "-") == 0
   11020       518593 :           || strcmp (name, HOST_BIT_BUCKET) == 0);
   11021              : }
   11022              : 
   11023              : /* %:dumps spec function.  Take an optional argument that overrides
   11024              :    the default extension for -dumpbase and -dumpbase-ext.
   11025              :    Return -dumpdir, -dumpbase and -dumpbase-ext, if needed.  */
   11026              : const char *
   11027       282863 : dumps_spec_func (int argc, const char **argv ATTRIBUTE_UNUSED)
   11028              : {
   11029       282863 :   const char *ext = dumpbase_ext;
   11030       282863 :   char *p;
   11031              : 
   11032       282863 :   char *args[3] = { NULL, NULL, NULL };
   11033       282863 :   int nargs = 0;
   11034              : 
   11035              :   /* Do not compute a default for -dumpbase-ext when -dumpbase was
   11036              :      given explicitly.  */
   11037       282863 :   if (dumpbase && *dumpbase && !ext)
   11038       282863 :     ext = "";
   11039              : 
   11040       282863 :   if (argc == 1)
   11041              :     {
   11042              :       /* Do not override the explicitly-specified -dumpbase-ext with
   11043              :          the specs-provided overrider.  */
   11044            0 :       if (!ext)
   11045            0 :         ext = argv[0];
   11046              :     }
   11047       282863 :   else if (argc != 0)
   11048            0 :     fatal_error (input_location, "too many arguments for %%:dumps");
   11049              : 
   11050       282863 :   if (dumpdir)
   11051              :     {
   11052       106007 :       p = quote_spec_arg (xstrdup (dumpdir));
   11053       106007 :       args[nargs++] = concat (" -dumpdir ", p, NULL);
   11054       106007 :       free (p);
   11055              :     }
   11056              : 
   11057       282863 :   if (!ext)
   11058       262611 :     ext = input_basename + basename_length;
   11059              : 
   11060              :   /* Use the precomputed outbase, or compute dumpbase from
   11061              :      input_basename, just like %b would.  */
   11062       282863 :   char *base;
   11063              : 
   11064       282863 :   if (dumpbase && *dumpbase)
   11065              :     {
   11066        20252 :       base = xstrdup (dumpbase);
   11067        20252 :       p = base + outbase_length;
   11068        20252 :       gcc_checking_assert (strncmp (base, outbase, outbase_length) == 0);
   11069        20252 :       gcc_checking_assert (strcmp (p, ext) == 0);
   11070              :     }
   11071       262611 :   else if (outbase_length)
   11072              :     {
   11073       162970 :       base = xstrndup (outbase, outbase_length);
   11074       162970 :       p = NULL;
   11075              :     }
   11076              :   else
   11077              :     {
   11078        99641 :       base = xstrndup (input_basename, suffixed_basename_length);
   11079        99641 :       p = base + basename_length;
   11080              :     }
   11081              : 
   11082       282863 :   if (compare_debug < 0 || !p || strcmp (p, ext) != 0)
   11083              :     {
   11084          613 :       if (p)
   11085            9 :         *p = '\0';
   11086              : 
   11087       162979 :       const char *gk;
   11088       162979 :       if (compare_debug < 0)
   11089              :         gk = ".gk";
   11090              :       else
   11091       162366 :         gk = "";
   11092              : 
   11093       162979 :       p = concat (base, gk, ext, NULL);
   11094              : 
   11095       162979 :       free (base);
   11096       162979 :       base = p;
   11097              :     }
   11098              : 
   11099       282863 :   base = quote_spec_arg (base);
   11100       282863 :   args[nargs++] = concat (" -dumpbase ", base, NULL);
   11101       282863 :   free (base);
   11102              : 
   11103       282863 :   if (*ext)
   11104              :     {
   11105       261570 :       p = quote_spec_arg (xstrdup (ext));
   11106       261570 :       args[nargs++] = concat (" -dumpbase-ext ", p, NULL);
   11107       261570 :       free (p);
   11108              :     }
   11109              : 
   11110       282863 :   const char *ret = concat (args[0], args[1], args[2], NULL);
   11111      1216166 :   while (nargs > 0)
   11112       650440 :     free (args[--nargs]);
   11113              : 
   11114       282863 :   return ret;
   11115              : }
   11116              : 
   11117              : /* Returns "" if ARGV[ARGC - 2] is greater than ARGV[ARGC-1].
   11118              :    Otherwise, return NULL.  */
   11119              : 
   11120              : static const char *
   11121       399871 : greater_than_spec_func (int argc, const char **argv)
   11122              : {
   11123       399871 :   char *converted;
   11124              : 
   11125       399871 :   if (argc == 1)
   11126              :     return NULL;
   11127              : 
   11128          252 :   gcc_assert (argc >= 2);
   11129              : 
   11130          252 :   long arg = strtol (argv[argc - 2], &converted, 10);
   11131          252 :   gcc_assert (converted != argv[argc - 2]);
   11132              : 
   11133          252 :   long lim = strtol (argv[argc - 1], &converted, 10);
   11134          252 :   gcc_assert (converted != argv[argc - 1]);
   11135              : 
   11136          252 :   if (arg > lim)
   11137              :     return "";
   11138              : 
   11139              :   return NULL;
   11140              : }
   11141              : 
   11142              : /* Returns "" if debug_info_level is greater than ARGV[ARGC-1].
   11143              :    Otherwise, return NULL.  */
   11144              : 
   11145              : static const char *
   11146       251511 : debug_level_greater_than_spec_func (int argc, const char **argv)
   11147              : {
   11148       251511 :   char *converted;
   11149              : 
   11150       251511 :   if (argc != 1)
   11151            0 :     fatal_error (input_location,
   11152              :                  "wrong number of arguments to %%:debug-level-gt");
   11153              : 
   11154       251511 :   long arg = strtol (argv[0], &converted, 10);
   11155       251511 :   gcc_assert (converted != argv[0]);
   11156              : 
   11157       251511 :   if (debug_info_level > arg)
   11158        45137 :     return "";
   11159              : 
   11160              :   return NULL;
   11161              : }
   11162              : 
   11163              : /* Returns "" if dwarf_version is greater than ARGV[ARGC-1].
   11164              :    Otherwise, return NULL.  */
   11165              : 
   11166              : static const char *
   11167       127959 : dwarf_version_greater_than_spec_func (int argc, const char **argv)
   11168              : {
   11169       127959 :   char *converted;
   11170              : 
   11171       127959 :   if (argc != 1)
   11172            0 :     fatal_error (input_location,
   11173              :                  "wrong number of arguments to %%:dwarf-version-gt");
   11174              : 
   11175       127959 :   long arg = strtol (argv[0], &converted, 10);
   11176       127959 :   gcc_assert (converted != argv[0]);
   11177              : 
   11178       127959 :   if (dwarf_version > arg)
   11179       127088 :     return "";
   11180              : 
   11181              :   return NULL;
   11182              : }
   11183              : 
   11184              : static void
   11185        34760 : path_prefix_reset (path_prefix *prefix)
   11186              : {
   11187        34760 :   struct prefix_list *iter, *next;
   11188        34760 :   iter = prefix->plist;
   11189       137906 :   while (iter)
   11190              :     {
   11191       103146 :       next = iter->next;
   11192       103146 :       free (const_cast <char *> (iter->prefix));
   11193       103146 :       XDELETE (iter);
   11194       103146 :       iter = next;
   11195              :     }
   11196        34760 :   prefix->plist = 0;
   11197        34760 :   prefix->max_len = 0;
   11198        34760 : }
   11199              : 
   11200              : /* The function takes 3 arguments: OPTION name, file name and location
   11201              :    where we search for Fortran modules.
   11202              :    When the FILE is found by find_file, return OPTION=path_to_file.  */
   11203              : 
   11204              : static const char *
   11205        31358 : find_fortran_preinclude_file (int argc, const char **argv)
   11206              : {
   11207        31358 :   char *result = NULL;
   11208        31358 :   if (argc != 3)
   11209              :     return NULL;
   11210              : 
   11211        31358 :   struct path_prefix prefixes = { 0, 0, "preinclude" };
   11212              : 
   11213              :   /* Search first for 'finclude' folder location for a header file
   11214              :      installed by the compiler (similar to omp_lib.h).  */
   11215        31358 :   add_prefix (&prefixes, argv[2], NULL, 0, 0, 0);
   11216              : #ifdef TOOL_INCLUDE_DIR
   11217              :   /* Then search: <prefix>/<target>/<include>/finclude */
   11218        31358 :   add_prefix (&prefixes, TOOL_INCLUDE_DIR "/finclude/",
   11219              :               NULL, 0, 0, 0);
   11220              : #endif
   11221              : #ifdef NATIVE_SYSTEM_HEADER_DIR
   11222              :   /* Then search: <sysroot>/usr/include/finclude/<multilib> */
   11223        31358 :   add_sysrooted_hdrs_prefix (&prefixes, NATIVE_SYSTEM_HEADER_DIR "/finclude/",
   11224              :                              NULL, 0, 0, 0);
   11225              : #endif
   11226              : 
   11227        31358 :   const char *path = find_a_file (&include_prefixes, argv[1], R_OK, false);
   11228        31358 :   if (path != NULL)
   11229            0 :     result = concat (argv[0], path, NULL);
   11230              :   else
   11231              :     {
   11232        31358 :       path = find_a_file (&prefixes, argv[1], R_OK, false);
   11233        31358 :       if (path != NULL)
   11234        31358 :         result = concat (argv[0], path, NULL);
   11235              :     }
   11236              : 
   11237        31358 :   path_prefix_reset (&prefixes);
   11238        31358 :   return result;
   11239              : }
   11240              : 
   11241              : /* The function takes any number of arguments and joins them together,
   11242              :    escaping any special characters.
   11243              : 
   11244              :    This seems to be necessary to build "-fjoined=foo.b" from "-fseparate foo.a"
   11245              :    with a %{fseparate*:-fjoined=%.b$*} rule without adding undesired spaces:
   11246              :    when doing $* replacement we first replace $* with the rest of the switch
   11247              :    (in this case ""), and then add any arguments as arguments after the result,
   11248              :    resulting in "-fjoined= foo.b".  Using this function with e.g.
   11249              :    %{fseparate*:-fjoined=%:join(%.b$*)} gets multiple words as separate argv
   11250              :    elements instead of separated by spaces, and we paste them together.  */
   11251              : 
   11252              : static const char *
   11253           39 : join_spec_func (int argc, const char **argv)
   11254              : {
   11255           39 :   const char *result = argv[0];
   11256           39 :   if (argc != 1)
   11257              :     {
   11258          117 :       for (int i = 0; i < argc; ++i)
   11259           78 :         obstack_grow (&obstack, argv[i], strlen (argv[i]));
   11260           39 :       obstack_1grow (&obstack, '\0');
   11261           39 :       result = XOBFINISH (&obstack, const char *);
   11262              :     }
   11263           39 :   return quote_spec (xstrdup (result));
   11264              : }
   11265              : 
   11266              : /* If any character in ORIG fits QUOTE_P (_, P), reallocate the string
   11267              :    so as to precede every one of them with a backslash.  Return the
   11268              :    original string or the reallocated one.  */
   11269              : 
   11270              : static inline char *
   11271       855469 : quote_string (char *orig, bool (*quote_p)(char, void *), void *p)
   11272              : {
   11273       855469 :   int len, number_of_space = 0;
   11274              : 
   11275     19710244 :   for (len = 0; orig[len]; len++)
   11276     18854775 :     if (quote_p (orig[len], p))
   11277            0 :       number_of_space++;
   11278              : 
   11279       855469 :   if (number_of_space)
   11280              :     {
   11281            0 :       char *new_spec = (char *) xmalloc (len + number_of_space + 1);
   11282            0 :       int j, k;
   11283            0 :       for (j = 0, k = 0; j <= len; j++, k++)
   11284              :         {
   11285            0 :           if (quote_p (orig[j], p))
   11286            0 :             new_spec[k++] = '\\';
   11287            0 :           new_spec[k] = orig[j];
   11288              :         }
   11289            0 :       free (orig);
   11290            0 :       return new_spec;
   11291              :     }
   11292              :   else
   11293              :     return orig;
   11294              : }
   11295              : 
   11296              : /* Return true iff C is any of the characters convert_white_space
   11297              :    should quote.  */
   11298              : 
   11299              : static inline bool
   11300     12675380 : whitespace_to_convert_p (char c, void *)
   11301              : {
   11302     12675380 :   return (c == ' ' || c == '\t');
   11303              : }
   11304              : 
   11305              : /* Insert backslash before spaces in ORIG (usually a file path), to
   11306              :    avoid being broken by spec parser.
   11307              : 
   11308              :    This function is needed as do_spec_1 treats white space (' ' and '\t')
   11309              :    as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
   11310              :    the file name should be treated as a single argument rather than being
   11311              :    broken into multiple. Solution is to insert '\\' before the space in a
   11312              :    file name.
   11313              : 
   11314              :    This function converts and only converts all occurrence of ' '
   11315              :    to '\\' + ' ' and '\t' to '\\' + '\t'.  For example:
   11316              :    "a b"  -> "a\\ b"
   11317              :    "a  b" -> "a\\ \\ b"
   11318              :    "a\tb" -> "a\\\tb"
   11319              :    "a\\ b" -> "a\\\\ b"
   11320              : 
   11321              :    orig: input null-terminating string that was allocated by xalloc. The
   11322              :    memory it points to might be freed in this function. Behavior undefined
   11323              :    if ORIG wasn't xalloced or was freed already at entry.
   11324              : 
   11325              :    Return: ORIG if no conversion needed. Otherwise a newly allocated string
   11326              :    that was converted from ORIG.  */
   11327              : 
   11328              : static char *
   11329       203766 : convert_white_space (char *orig)
   11330              : {
   11331       203766 :   return quote_string (orig, whitespace_to_convert_p, NULL);
   11332              : }
   11333              : 
   11334              : /* Return true iff C matches any of the spec active characters.  */
   11335              : static inline bool
   11336      6179395 : quote_spec_char_p (char c, void *)
   11337              : {
   11338      6179395 :   switch (c)
   11339              :     {
   11340              :     case ' ':
   11341              :     case '\t':
   11342              :     case '\n':
   11343              :     case '|':
   11344              :     case '%':
   11345              :     case '\\':
   11346              :       return true;
   11347              : 
   11348      6179395 :     default:
   11349      6179395 :       return false;
   11350              :     }
   11351              : }
   11352              : 
   11353              : /* Like convert_white_space, but deactivate all active spec chars by
   11354              :    quoting them.  */
   11355              : 
   11356              : static inline char *
   11357       651703 : quote_spec (char *orig)
   11358              : {
   11359         1272 :   return quote_string (orig, quote_spec_char_p, NULL);
   11360              : }
   11361              : 
   11362              : /* Like quote_spec, but also turn an empty string into the spec for an
   11363              :    empty argument.  */
   11364              : 
   11365              : static inline char *
   11366       650440 : quote_spec_arg (char *orig)
   11367              : {
   11368       650440 :   if (!*orig)
   11369              :     {
   11370            9 :       free (orig);
   11371            9 :       return xstrdup ("%\"");
   11372              :     }
   11373              : 
   11374       650431 :   return quote_spec (orig);
   11375              : }
   11376              : 
   11377              : /* Restore all state within gcc.cc to the initial state, so that the driver
   11378              :    code can be safely re-run in-process.
   11379              : 
   11380              :    Many const char * variables are referenced by static specs (see
   11381              :    INIT_STATIC_SPEC above).  These variables are restored to their default
   11382              :    values by a simple loop over the static specs.
   11383              : 
   11384              :    For other variables, we directly restore them all to their initial
   11385              :    values (often implicitly 0).
   11386              : 
   11387              :    Free the various obstacks in this file, along with "opts_obstack"
   11388              :    from opts.cc.
   11389              : 
   11390              :    This function also restores any environment variables that were changed.  */
   11391              : 
   11392              : void
   11393         1134 : driver::finalize ()
   11394              : {
   11395         1134 :   env.restore ();
   11396         1134 :   diagnostic_finish (global_dc);
   11397              : 
   11398         1134 :   is_cpp_driver = 0;
   11399         1134 :   at_file_supplied = 0;
   11400         1134 :   print_help_list = 0;
   11401         1134 :   print_version = 0;
   11402         1134 :   verbose_only_flag = 0;
   11403         1134 :   print_subprocess_help = 0;
   11404         1134 :   use_ld = NULL;
   11405         1134 :   report_times_to_file = NULL;
   11406         1134 :   target_system_root = DEFAULT_TARGET_SYSTEM_ROOT;
   11407         1134 :   target_system_root_changed = 0;
   11408         1134 :   target_sysroot_suffix = 0;
   11409         1134 :   target_sysroot_hdrs_suffix = 0;
   11410         1134 :   save_temps_flag = SAVE_TEMPS_NONE;
   11411         1134 :   save_temps_overrides_dumpdir = false;
   11412         1134 :   dumpdir_trailing_dash_added = false;
   11413         1134 :   free (dumpdir);
   11414         1134 :   free (dumpbase);
   11415         1134 :   free (dumpbase_ext);
   11416         1134 :   free (outbase);
   11417         1134 :   dumpdir = dumpbase = dumpbase_ext = outbase = NULL;
   11418         1134 :   dumpdir_length = outbase_length = 0;
   11419         1134 :   spec_machine = DEFAULT_TARGET_MACHINE;
   11420         1134 :   greatest_status = 1;
   11421              : 
   11422         1134 :   obstack_free (&obstack, NULL);
   11423         1134 :   obstack_free (&opts_obstack, NULL); /* in opts.cc */
   11424         1134 :   obstack_free (&collect_obstack, NULL);
   11425              : 
   11426         1134 :   link_command_spec = LINK_COMMAND_SPEC;
   11427              : 
   11428         1134 :   obstack_free (&multilib_obstack, NULL);
   11429              : 
   11430         1134 :   user_specs_head = NULL;
   11431         1134 :   user_specs_tail = NULL;
   11432              : 
   11433              :   /* Within the "compilers" vec, the fields "suffix" and "spec" were
   11434              :      statically allocated for the default compilers, but dynamically
   11435              :      allocated for additional compilers.  Delete them for the latter. */
   11436         1134 :   for (int i = n_default_compilers; i < n_compilers; i++)
   11437              :     {
   11438            0 :       free (const_cast <char *> (compilers[i].suffix));
   11439            0 :       free (const_cast <char *> (compilers[i].spec));
   11440              :     }
   11441         1134 :   XDELETEVEC (compilers);
   11442         1134 :   compilers = NULL;
   11443         1134 :   n_compilers = 0;
   11444              : 
   11445         1134 :   linker_options.truncate (0);
   11446         1134 :   assembler_options.truncate (0);
   11447         1134 :   preprocessor_options.truncate (0);
   11448              : 
   11449         1134 :   path_prefix_reset (&exec_prefixes);
   11450         1134 :   path_prefix_reset (&startfile_prefixes);
   11451         1134 :   path_prefix_reset (&include_prefixes);
   11452              : 
   11453         1134 :   machine_suffix = 0;
   11454         1134 :   just_machine_suffix = 0;
   11455         1134 :   gcc_exec_prefix = 0;
   11456         1134 :   gcc_libexec_prefix = 0;
   11457         1134 :   set_static_spec_shared (&md_exec_prefix, MD_EXEC_PREFIX);
   11458         1134 :   set_static_spec_shared (&md_startfile_prefix, MD_STARTFILE_PREFIX);
   11459         1134 :   set_static_spec_shared (&md_startfile_prefix_1, MD_STARTFILE_PREFIX_1);
   11460         1134 :   multilib_dir = 0;
   11461         1134 :   multilib_os_dir = 0;
   11462         1134 :   multiarch_dir = 0;
   11463              : 
   11464              :   /* Free any specs dynamically-allocated by set_spec.
   11465              :      These will be at the head of the list, before the
   11466              :      statically-allocated ones.  */
   11467         1134 :   if (specs)
   11468              :     {
   11469         2268 :       while (specs != static_specs)
   11470              :         {
   11471         1134 :           spec_list *next = specs->next;
   11472         1134 :           free (const_cast <char *> (specs->name));
   11473         1134 :           XDELETE (specs);
   11474         1134 :           specs = next;
   11475              :         }
   11476         1134 :       specs = 0;
   11477              :     }
   11478        52164 :   for (unsigned i = 0; i < ARRAY_SIZE (static_specs); i++)
   11479              :     {
   11480        51030 :       spec_list *sl = &static_specs[i];
   11481        51030 :       if (sl->alloc_p)
   11482              :         {
   11483        45370 :           free (const_cast <char *> (*(sl->ptr_spec)));
   11484        45370 :           sl->alloc_p = false;
   11485              :         }
   11486        51030 :       *(sl->ptr_spec) = sl->default_ptr;
   11487              :     }
   11488              : #ifdef EXTRA_SPECS
   11489         1134 :   extra_specs = NULL;
   11490              : #endif
   11491              : 
   11492         1134 :   processing_spec_function = 0;
   11493              : 
   11494         1134 :   clear_args ();
   11495              : 
   11496         1134 :   have_c = 0;
   11497         1134 :   have_o = 0;
   11498              : 
   11499         1134 :   temp_names = NULL;
   11500         1134 :   execution_count = 0;
   11501         1134 :   signal_count = 0;
   11502              : 
   11503         1134 :   temp_filename = NULL;
   11504         1134 :   temp_filename_length = 0;
   11505         1134 :   always_delete_queue = NULL;
   11506         1134 :   failure_delete_queue = NULL;
   11507              : 
   11508         1134 :   XDELETEVEC (switches);
   11509         1134 :   switches = NULL;
   11510         1134 :   n_switches = 0;
   11511         1134 :   n_switches_alloc = 0;
   11512              : 
   11513         1134 :   compare_debug = 0;
   11514         1134 :   compare_debug_second = 0;
   11515         1134 :   compare_debug_opt = NULL;
   11516         3402 :   for (int i = 0; i < 2; i++)
   11517              :     {
   11518         2268 :       switches_debug_check[i] = NULL;
   11519         2268 :       n_switches_debug_check[i] = 0;
   11520         2268 :       n_switches_alloc_debug_check[i] = 0;
   11521         2268 :       debug_check_temp_file[i] = NULL;
   11522              :     }
   11523              : 
   11524         1134 :   XDELETEVEC (infiles);
   11525         1134 :   infiles = NULL;
   11526         1134 :   n_infiles = 0;
   11527         1134 :   n_infiles_alloc = 0;
   11528              : 
   11529         1134 :   combine_inputs = false;
   11530         1134 :   added_libraries = 0;
   11531         1134 :   XDELETEVEC (outfiles);
   11532         1134 :   outfiles = NULL;
   11533         1134 :   spec_lang = 0;
   11534         1134 :   last_language_n_infiles = 0;
   11535         1134 :   gcc_input_filename = NULL;
   11536         1134 :   input_file_number = 0;
   11537         1134 :   input_filename_length = 0;
   11538         1134 :   basename_length = 0;
   11539         1134 :   suffixed_basename_length = 0;
   11540         1134 :   input_basename = NULL;
   11541         1134 :   input_suffix = NULL;
   11542              :   /* We don't need to purge "input_stat", just to unset "input_stat_set".  */
   11543         1134 :   input_stat_set = 0;
   11544         1134 :   input_file_compiler = NULL;
   11545         1134 :   arg_going = 0;
   11546         1134 :   delete_this_arg = 0;
   11547         1134 :   this_is_output_file = 0;
   11548         1134 :   this_is_library_file = 0;
   11549         1134 :   this_is_linker_script = 0;
   11550         1134 :   input_from_pipe = 0;
   11551         1134 :   suffix_subst = NULL;
   11552              : 
   11553         1134 :   XDELETEVEC (mdswitches);
   11554         1134 :   mdswitches = NULL;
   11555         1134 :   n_mdswitches = 0;
   11556              : 
   11557         1134 :   used_arg.finalize ();
   11558         1134 : }
   11559              : 
   11560              : /* PR jit/64810.
   11561              :    Targets can provide configure-time default options in
   11562              :    OPTION_DEFAULT_SPECS.  The jit needs to access these, but
   11563              :    they are expressed in the spec language.
   11564              : 
   11565              :    Run just enough of the driver to be able to expand these
   11566              :    specs, and then call the callback CB on each
   11567              :    such option.  The options strings are *without* a leading
   11568              :    '-' character e.g. ("march=x86-64").  Finally, clean up.  */
   11569              : 
   11570              : void
   11571          131 : driver_get_configure_time_options (void (*cb) (const char *option,
   11572              :                                                void *user_data),
   11573              :                                    void *user_data)
   11574              : {
   11575          131 :   size_t i;
   11576              : 
   11577          131 :   obstack_init (&obstack);
   11578          131 :   init_opts_obstack ();
   11579          131 :   n_switches = 0;
   11580              : 
   11581         1441 :   for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
   11582         1310 :     do_option_spec (option_default_specs[i].name,
   11583         1310 :                     option_default_specs[i].spec);
   11584              : 
   11585          393 :   for (i = 0; (int) i < n_switches; i++)
   11586              :     {
   11587          262 :       gcc_assert (switches[i].part1);
   11588          262 :       (*cb) (switches[i].part1, user_data);
   11589              :     }
   11590              : 
   11591          131 :   obstack_free (&opts_obstack, NULL);
   11592          131 :   obstack_free (&obstack, NULL);
   11593          131 :   n_switches = 0;
   11594          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.