LCOV - code coverage report
Current view: top level - ccache - ccache.c (source / functions) Hit Total Coverage
Test: ccache.lcov.info Lines: 671 1534 43.7 %
Date: 2015-06-29 Functions: 31 38 81.6 %
Branches: 291 923 31.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * ccache -- a fast C/C++ compiler cache
       3                 :            :  *
       4                 :            :  * Copyright (C) 2002-2007 Andrew Tridgell
       5                 :            :  * Copyright (C) 2009-2015 Joel Rosdahl
       6                 :            :  *
       7                 :            :  * This program is free software; you can redistribute it and/or modify it
       8                 :            :  * under the terms of the GNU General Public License as published by the Free
       9                 :            :  * Software Foundation; either version 3 of the License, or (at your option)
      10                 :            :  * any later version.
      11                 :            :  *
      12                 :            :  * This program is distributed in the hope that it will be useful, but WITHOUT
      13                 :            :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :            :  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
      15                 :            :  * more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License along with
      18                 :            :  * this program; if not, write to the Free Software Foundation, Inc., 51
      19                 :            :  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20                 :            :  */
      21                 :            : 
      22                 :            : #include "ccache.h"
      23                 :            : #include "compopt.h"
      24                 :            : #ifdef HAVE_GETOPT_LONG
      25                 :            : #include <getopt.h>
      26                 :            : #else
      27                 :            : #include "getopt_long.h"
      28                 :            : #endif
      29                 :            : #include "hashtable.h"
      30                 :            : #include "hashtable_itr.h"
      31                 :            : #include "hashutil.h"
      32                 :            : #include "language.h"
      33                 :            : #include "manifest.h"
      34                 :            : 
      35                 :            : #define STRINGIFY(x) #x
      36                 :            : #define TO_STRING(x) STRINGIFY(x)
      37                 :            : 
      38                 :            : static const char VERSION_TEXT[] =
      39                 :            : MYNAME " version %s\n"
      40                 :            : "\n"
      41                 :            : "Copyright (C) 2002-2007 Andrew Tridgell\n"
      42                 :            : "Copyright (C) 2009-2015 Joel Rosdahl\n"
      43                 :            : "\n"
      44                 :            : "This program is free software; you can redistribute it and/or modify it under\n"
      45                 :            : "the terms of the GNU General Public License as published by the Free Software\n"
      46                 :            : "Foundation; either version 3 of the License, or (at your option) any later\n"
      47                 :            : "version.\n";
      48                 :            : 
      49                 :            : static const char USAGE_TEXT[] =
      50                 :            : "Usage:\n"
      51                 :            : "    " MYNAME " [options]\n"
      52                 :            : "    " MYNAME " compiler [compiler options]\n"
      53                 :            : "    compiler [compiler options]          (via symbolic link)\n"
      54                 :            : "\n"
      55                 :            : "Options:\n"
      56                 :            : "    -c, --cleanup         delete old files and recalculate size counters\n"
      57                 :            : "                          (normally not needed as this is done automatically)\n"
      58                 :            : "    -C, --clear           clear the cache completely (except configuration)\n"
      59                 :            : "    -F, --max-files=N     set maximum number of files in cache to N (use 0 for\n"
      60                 :            : "                          no limit)\n"
      61                 :            : "    -M, --max-size=SIZE   set maximum size of cache to SIZE (use 0 for no\n"
      62                 :            : "                          limit); available suffixes: k, M, G, T (decimal) and\n"
      63                 :            : "                          Ki, Mi, Gi, Ti (binary); default suffix: G\n"
      64                 :            : "    -o, --set-config=K=V  set configuration key K to value V\n"
      65                 :            : "    -p, --print-config    print current configuration options\n"
      66                 :            : "    -s, --show-stats      show statistics summary\n"
      67                 :            : "    -z, --zero-stats      zero statistics counters\n"
      68                 :            : "\n"
      69                 :            : "    -h, --help            print this help text\n"
      70                 :            : "    -V, --version         print version and copyright information\n"
      71                 :            : "\n"
      72                 :            : "See also <http://ccache.samba.org>.\n";
      73                 :            : 
      74                 :            : /* Global configuration data. */
      75                 :            : struct conf *conf = NULL;
      76                 :            : 
      77                 :            : /* Where to write configuration changes. */
      78                 :            : char *primary_config_path = NULL;
      79                 :            : 
      80                 :            : /* Secondary, read-only configuration file (if any). */
      81                 :            : char *secondary_config_path = NULL;
      82                 :            : 
      83                 :            : /* current working directory taken from $PWD, or getcwd() if $PWD is bad */
      84                 :            : char *current_working_dir = NULL;
      85                 :            : 
      86                 :            : /* the original argument list */
      87                 :            : static struct args *orig_args;
      88                 :            : 
      89                 :            : /* the source file */
      90                 :            : static char *input_file;
      91                 :            : 
      92                 :            : /* The output file being compiled to. */
      93                 :            : static char *output_obj;
      94                 :            : 
      95                 :            : /* The path to the dependency file (implicit or specified with -MF). */
      96                 :            : static char *output_dep;
      97                 :            : 
      98                 :            : /* The path to the coverage file (implicit when using -ftest-coverage). */
      99                 :            : static char *output_cov;
     100                 :            : 
     101                 :            : /* Diagnostic generation information (clang). Contains pathname if not
     102                 :            :    NULL. */
     103                 :            : static char *output_dia = NULL;
     104                 :            : 
     105                 :            : /* -gsplit-dwarf support: Split dwarf information (GCC 4.8 and
     106                 :            :     up). Contains pathname if not NULL. */
     107                 :            : static char *output_dwo = NULL;
     108                 :            : 
     109                 :            : /*
     110                 :            :  * Name (represented as a struct file_hash) of the file containing the cached
     111                 :            :  * object code.
     112                 :            :  */
     113                 :            : static struct file_hash *cached_obj_hash;
     114                 :            : 
     115                 :            : /*
     116                 :            :  * Full path to the file containing the cached object code
     117                 :            :  * (cachedir/a/b/cdef[...]-size.o).
     118                 :            :  */
     119                 :            : static char *cached_obj;
     120                 :            : 
     121                 :            : /*
     122                 :            :  * Full path to the file containing the standard error output
     123                 :            :  * (cachedir/a/b/cdef[...]-size.stderr).
     124                 :            :  */
     125                 :            : static char *cached_stderr;
     126                 :            : 
     127                 :            : /*
     128                 :            :  * Full path to the file containing the dependency information
     129                 :            :  * (cachedir/a/b/cdef[...]-size.d).
     130                 :            :  */
     131                 :            : static char *cached_dep;
     132                 :            : 
     133                 :            : /*
     134                 :            :  * Full path to the file containing the coverage information
     135                 :            :  * (cachedir/a/b/cdef[...]-size.gcno).
     136                 :            :  */
     137                 :            : static char *cached_cov;
     138                 :            : 
     139                 :            : /*
     140                 :            :  * Full path to the file containing the diagnostic information (for clang)
     141                 :            :  * (cachedir/a/b/cdef[...]-size.dia).
     142                 :            :  */
     143                 :            : static char *cached_dia;
     144                 :            : 
     145                 :            : /*
     146                 :            :  * -gsplit-dwarf support:
     147                 :            :  * Full path to the file containing the split dwarf (for GCC 4.8 and
     148                 :            :  * above)
     149                 :            :  * (cachedir/a/b/cdef[...]-size.dwo).
     150                 :            :  *
     151                 :            :  * contains NULL if -gsplit-dwarf is not given.
     152                 :            :  */
     153                 :            : static char *cached_dwo;
     154                 :            : 
     155                 :            : /*
     156                 :            :  * -gsplit-dwarf support:
     157                 :            :  * using_split_dwarf is true if "-gsplit-dwarf" is given to the
     158                 :            :  * compiler (GCC 4.8 and up).
     159                 :            :  */
     160                 :            : bool using_split_dwarf = false;
     161                 :            : 
     162                 :            : /*
     163                 :            :  * Full path to the file containing the manifest
     164                 :            :  * (cachedir/a/b/cdef[...]-size.manifest).
     165                 :            :  */
     166                 :            : static char *manifest_path;
     167                 :            : 
     168                 :            : /*
     169                 :            :  * Time of compilation. Used to see if include files have changed after
     170                 :            :  * compilation.
     171                 :            :  */
     172                 :            : time_t time_of_compilation;
     173                 :            : 
     174                 :            : /*
     175                 :            :  * Files included by the preprocessor and their hashes/sizes. Key: file path.
     176                 :            :  * Value: struct file_hash.
     177                 :            :  */
     178                 :            : static struct hashtable *included_files;
     179                 :            : 
     180                 :            : /* is gcc being asked to output dependencies? */
     181                 :            : static bool generating_dependencies;
     182                 :            : 
     183                 :            : /* is gcc being asked to output coverage? */
     184                 :            : static bool generating_coverage;
     185                 :            : 
     186                 :            : /* is gcc being asked to output coverage data (.gcda) at runtime? */
     187                 :            : static bool profile_arcs;
     188                 :            : 
     189                 :            : /* name of the custom profile directory (default: object dirname) */
     190                 :            : static char *profile_dir;
     191                 :            : 
     192                 :            : /* the name of the temporary pre-processor file */
     193                 :            : static char *i_tmpfile;
     194                 :            : 
     195                 :            : /* are we compiling a .i or .ii file directly? */
     196                 :            : static bool direct_i_file;
     197                 :            : 
     198                 :            : /* the name of the cpp stderr file */
     199                 :            : static char *cpp_stderr;
     200                 :            : 
     201                 :            : /*
     202                 :            :  * Full path to the statistics file in the subdirectory where the cached result
     203                 :            :  * belongs (<cache_dir>/<x>/stats).
     204                 :            :  */
     205                 :            : char *stats_file = NULL;
     206                 :            : 
     207                 :            : /* Whether the output is a precompiled header */
     208                 :            : static bool output_is_precompiled_header = false;
     209                 :            : 
     210                 :            : /* Profile generation / usage information */
     211                 :            : static char *profile_dir = NULL;
     212                 :            : static bool profile_use = false;
     213                 :            : static bool profile_generate = false;
     214                 :            : 
     215                 :            : /*
     216                 :            :  * Whether we are using a precompiled header (either via -include, #include or
     217                 :            :  * clang's -include-pch or -include-pth).
     218                 :            :  */
     219                 :            : static bool using_precompiled_header = false;
     220                 :            : 
     221                 :            : /*
     222                 :            :  * The .gch/.pch/.pth file used for compilation.
     223                 :            :  */
     224                 :            : static char *included_pch_file = NULL;
     225                 :            : 
     226                 :            : /* How long (in microseconds) to wait before breaking a stale lock. */
     227                 :            : unsigned lock_staleness_limit = 2000000;
     228                 :            : 
     229                 :            : enum fromcache_call_mode {
     230                 :            :         FROMCACHE_DIRECT_MODE,
     231                 :            :         FROMCACHE_CPP_MODE
     232                 :            : };
     233                 :            : 
     234                 :            : struct pending_tmp_file {
     235                 :            :         char *path;
     236                 :            :         struct pending_tmp_file *next;
     237                 :            : };
     238                 :            : 
     239                 :            : /* Temporary files to remove at program exit. */
     240                 :            : static struct pending_tmp_file *pending_tmp_files = NULL;
     241                 :            : 
     242                 :            : /*
     243                 :            :  * This is a string that identifies the current "version" of the hash sum
     244                 :            :  * computed by ccache. If, for any reason, we want to force the hash sum to be
     245                 :            :  * different for the same input in a new ccache version, we can just change
     246                 :            :  * this string. A typical example would be if the format of one of the files
     247                 :            :  * stored in the cache changes in a backwards-incompatible way.
     248                 :            :  */
     249                 :            : static const char HASH_PREFIX[] = "3";
     250                 :            : 
     251                 :            : static void
     252                 :          1 : add_prefix(struct args *args)
     253                 :            : {
     254                 :            :         char *e;
     255                 :          1 :         char *tok, *saveptr = NULL;
     256                 :            :         struct args *prefix;
     257                 :            :         int i;
     258                 :            : 
     259         [ +  - ]:          1 :         if (str_eq(conf->prefix_command, "")) {
     260                 :          1 :                 return;
     261                 :            :         }
     262                 :            : 
     263                 :          0 :         prefix = args_init(0, NULL);
     264                 :          0 :         e = x_strdup(conf->prefix_command);
     265         [ #  # ]:          0 :         for (tok = strtok_r(e, " ", &saveptr);
     266                 :            :              tok;
     267                 :          0 :              tok = strtok_r(NULL, " ", &saveptr)) {
     268                 :            :                 char *p;
     269                 :            : 
     270                 :          0 :                 p = find_executable(tok, MYNAME);
     271         [ #  # ]:          0 :                 if (!p) {
     272                 :          0 :                         fatal("%s: %s", tok, strerror(errno));
     273                 :            :                 }
     274                 :            : 
     275                 :          0 :                 args_add(prefix, p);
     276                 :          0 :                 free(p);
     277                 :            :         }
     278                 :          0 :         free(e);
     279                 :            : 
     280                 :          0 :         cc_log("Using command-line prefix %s", conf->prefix_command);
     281         [ #  # ]:          0 :         for (i = prefix->argc; i != 0; i--) {
     282                 :          0 :                 args_add_prefix(args, prefix->argv[i-1]);
     283                 :            :         }
     284                 :          1 :         args_free(prefix);
     285                 :            : }
     286                 :            : 
     287                 :            : /* Something went badly wrong - just execute the real compiler. */
     288                 :            : static void
     289                 :          0 : failed(void)
     290                 :            : {
     291         [ #  # ]:          0 :         assert(orig_args);
     292                 :            : 
     293                 :          0 :         args_strip(orig_args, "--ccache-");
     294                 :          0 :         add_prefix(orig_args);
     295                 :            : 
     296                 :          0 :         cc_log("Failed; falling back to running the real compiler");
     297                 :          0 :         cc_log_argv("Executing ", orig_args->argv);
     298                 :          0 :         exitfn_call();
     299                 :          0 :         execv(orig_args->argv[0], orig_args->argv);
     300                 :          0 :         fatal("execv of %s failed: %s", orig_args->argv[0], strerror(errno));
     301                 :            : }
     302                 :            : 
     303                 :            : static const char *
     304                 :          2 : temp_dir()
     305                 :            : {
     306                 :            :         static char *path = NULL;
     307         [ +  + ]:          2 :         if (path) {
     308                 :          1 :                 return path; /* Memoize */
     309                 :            :         }
     310                 :          1 :         path = conf->temporary_dir;
     311         [ +  - ]:          1 :         if (str_eq(path, "")) {
     312                 :          1 :                 path = format("%s/tmp", conf->cache_dir);
     313                 :            :         }
     314                 :          2 :         return path;
     315                 :            : }
     316                 :            : 
     317                 :            : static void
     318                 :          3 : add_pending_tmp_file(const char *path)
     319                 :            : {
     320                 :          3 :         struct pending_tmp_file *e = x_malloc(sizeof(*e));
     321                 :          3 :         e->path = x_strdup(path);
     322                 :          3 :         e->next = pending_tmp_files;
     323                 :          3 :         pending_tmp_files = e;
     324                 :          3 : }
     325                 :            : 
     326                 :            : static void
     327                 :          7 : clean_up_pending_tmp_files(void)
     328                 :            : {
     329                 :          7 :         struct pending_tmp_file *p = pending_tmp_files;
     330         [ +  + ]:         10 :         while (p) {
     331                 :            :                 /* Can't call tmp_unlink here since its cc_log calls aren't signal safe. */
     332                 :          3 :                 unlink(p->path);
     333                 :          3 :                 p = p->next;
     334                 :            :                 /* Leak p->path and p here because clean_up_pending_tmp_files needs to be
     335                 :            :                  * signal safe. */
     336                 :            :         }
     337                 :          7 : }
     338                 :            : 
     339                 :            : static void
     340                 :          0 : signal_handler(int signo)
     341                 :            : {
     342                 :            :         (void)signo;
     343                 :          0 :         clean_up_pending_tmp_files();
     344                 :          0 : }
     345                 :            : 
     346                 :            : static void
     347                 :          1 : clean_up_internal_tempdir(void)
     348                 :            : {
     349                 :            :         DIR *dir;
     350                 :            :         struct dirent *entry;
     351                 :            :         struct stat st;
     352                 :          1 :         time_t now = time(NULL);
     353                 :            : 
     354 [ +  - ][ +  - ]:          1 :         if (x_stat(conf->cache_dir, &st) != 0 || st.st_mtime + 3600 >= now) {
     355                 :            :                 /* No cleanup needed. */
     356                 :          1 :                 return;
     357                 :            :         }
     358                 :            : 
     359                 :          0 :         update_mtime(conf->cache_dir);
     360                 :            : 
     361                 :          0 :         dir = opendir(temp_dir());
     362         [ #  # ]:          0 :         if (!dir) {
     363                 :          0 :                 return;
     364                 :            :         }
     365                 :            : 
     366         [ #  # ]:          0 :         while ((entry = readdir(dir))) {
     367                 :            :                 char *path;
     368                 :            : 
     369 [ #  # ][ #  # ]:          0 :                 if (str_eq(entry->d_name, ".") || str_eq(entry->d_name, "..")) {
     370                 :          0 :                         continue;
     371                 :            :                 }
     372                 :            : 
     373                 :          0 :                 path = format("%s/%s", temp_dir(), entry->d_name);
     374 [ #  # ][ #  # ]:          0 :                 if (x_lstat(path, &st) == 0 && st.st_mtime + 3600 < now) {
     375                 :          0 :                         tmp_unlink(path);
     376                 :            :                 }
     377                 :          0 :                 free(path);
     378                 :            :         }
     379                 :            : 
     380                 :          1 :         closedir(dir);
     381                 :            : }
     382                 :            : 
     383                 :            : static char *
     384                 :          2 : get_current_working_dir(void)
     385                 :            : {
     386         [ +  + ]:          2 :         if (!current_working_dir) {
     387                 :          1 :                 char *cwd = get_cwd();
     388         [ +  - ]:          1 :                 if (cwd) {
     389                 :          1 :                         current_working_dir = x_realpath(cwd);
     390                 :          1 :                         free(cwd);
     391                 :            :                 }
     392         [ -  + ]:          1 :                 if (!current_working_dir) {
     393                 :          0 :                         cc_log("Unable to determine current working directory: %s",
     394                 :            :                                strerror(errno));
     395                 :          0 :                         failed();
     396                 :            :                 }
     397                 :            :         }
     398                 :          2 :         return current_working_dir;
     399                 :            : }
     400                 :            : 
     401                 :            : /*
     402                 :            :  * Transform a name to a full path into the cache directory, creating needed
     403                 :            :  * sublevels if needed. Caller frees.
     404                 :            :  */
     405                 :            : static char *
     406                 :          5 : get_path_in_cache(const char *name, const char *suffix)
     407                 :            : {
     408                 :            :         unsigned i;
     409                 :            :         char *path;
     410                 :            :         char *result;
     411                 :            : 
     412                 :          5 :         path = x_strdup(conf->cache_dir);
     413         [ +  + ]:         15 :         for (i = 0; i < conf->cache_dir_levels; ++i) {
     414                 :         10 :                 char *p = format("%s/%c", path, name[i]);
     415                 :         10 :                 free(path);
     416                 :         10 :                 path = p;
     417                 :            :         }
     418                 :            : 
     419                 :          5 :         result = format("%s/%s%s", path, name + conf->cache_dir_levels, suffix);
     420                 :          5 :         free(path);
     421                 :          5 :         return result;
     422                 :            : }
     423                 :            : 
     424                 :            : /*
     425                 :            :  * This function hashes an include file and stores the path and hash in the
     426                 :            :  * global included_files variable. If the include file is a PCH, cpp_hash is
     427                 :            :  * also updated. Takes over ownership of path.
     428                 :            :  */
     429                 :            : static void
     430                 :          4 : remember_include_file(char *path, struct mdfour *cpp_hash)
     431                 :            : {
     432                 :            : #ifdef _WIN32
     433                 :            :         DWORD attributes;
     434                 :            : #endif
     435                 :            :         struct mdfour fhash;
     436                 :            :         struct stat st;
     437                 :          4 :         char *source = NULL;
     438                 :            :         size_t size;
     439                 :            :         bool is_pch;
     440                 :          4 :         size_t path_len = strlen(path);
     441                 :            : 
     442 [ +  - ][ +  + ]:          4 :         if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) {
                 [ +  - ]
     443                 :            :                 /* Typically <built-in> or <command-line>. */
     444                 :          2 :                 goto ignore;
     445                 :            :         }
     446                 :            : 
     447         [ +  - ]:          2 :         if (str_eq(path, input_file)) {
     448                 :            :                 /* Don't remember the input file. */
     449                 :          2 :                 goto ignore;
     450                 :            :         }
     451                 :            : 
     452         [ #  # ]:          0 :         if (hashtable_search(included_files, path)) {
     453                 :            :                 /* Already known include file. */
     454                 :          0 :                 goto ignore;
     455                 :            :         }
     456                 :            : 
     457                 :            : #ifdef _WIN32
     458                 :            :         /* stat fails on directories on win32 */
     459                 :            :         attributes = GetFileAttributes(path);
     460                 :            :         if (attributes != INVALID_FILE_ATTRIBUTES &&
     461                 :            :             attributes & FILE_ATTRIBUTE_DIRECTORY)
     462                 :            :                 goto ignore;
     463                 :            : #endif
     464                 :            : 
     465         [ #  # ]:          0 :         if (x_stat(path, &st) != 0) {
     466                 :          0 :                 goto failure;
     467                 :            :         }
     468         [ #  # ]:          0 :         if (S_ISDIR(st.st_mode)) {
     469                 :            :                 /* Ignore directory, typically $PWD. */
     470                 :          0 :                 goto ignore;
     471                 :            :         }
     472         [ #  # ]:          0 :         if (!S_ISREG(st.st_mode)) {
     473                 :            :                 /* Device, pipe, socket or other strange creature. */
     474                 :          0 :                 cc_log("Non-regular include file %s", path);
     475                 :          0 :                 goto failure;
     476                 :            :         }
     477                 :            : 
     478                 :            :         /* Let's hash the include file. */
     479 [ #  # ][ #  # ]:          0 :         if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
     480                 :          0 :             && st.st_mtime >= time_of_compilation) {
     481                 :          0 :                 cc_log("Include file %s too new", path);
     482                 :          0 :                 goto failure;
     483                 :            :         }
     484                 :            : 
     485 [ #  # ][ #  # ]:          0 :         if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_CTIME)
     486                 :          0 :             && st.st_ctime >= time_of_compilation) {
     487                 :          0 :                 cc_log("Include file %s ctime too new", path);
     488                 :          0 :                 goto failure;
     489                 :            :         }
     490                 :            : 
     491                 :          0 :         hash_start(&fhash);
     492                 :            : 
     493                 :          0 :         is_pch = is_precompiled_header(path);
     494         [ #  # ]:          0 :         if (is_pch) {
     495                 :            :                 struct file_hash pch_hash;
     496         [ #  # ]:          0 :                 if (!hash_file(&fhash, path)) {
     497                 :          0 :                         goto failure;
     498                 :            :                 }
     499                 :          0 :                 hash_result_as_bytes(&fhash, pch_hash.hash);
     500                 :          0 :                 pch_hash.size = fhash.totalN;
     501                 :          0 :                 hash_delimiter(cpp_hash, "pch_hash");
     502                 :          0 :                 hash_buffer(cpp_hash, pch_hash.hash, sizeof(pch_hash.hash));
     503                 :            :         }
     504         [ #  # ]:          0 :         if (conf->direct_mode) {
     505                 :            :                 struct file_hash *h;
     506                 :            : 
     507         [ #  # ]:          0 :                 if (!is_pch) { /* else: the file has already been hashed. */
     508                 :            :                         int result;
     509                 :            : 
     510         [ #  # ]:          0 :                         if (st.st_size > 0) {
     511         [ #  # ]:          0 :                                 if (!read_file(path, st.st_size, &source, &size)) {
     512                 :          0 :                                         goto failure;
     513                 :            :                                 }
     514                 :            :                         } else {
     515                 :          0 :                                 source = x_strdup("");
     516                 :          0 :                                 size = 0;
     517                 :            :                         }
     518                 :            : 
     519                 :          0 :                         result = hash_source_code_string(conf, &fhash, source, size, path);
     520 [ #  # ][ #  # ]:          0 :                         if (result & HASH_SOURCE_CODE_ERROR
     521                 :          0 :                             || result & HASH_SOURCE_CODE_FOUND_TIME) {
     522                 :            :                                 goto failure;
     523                 :            :                         }
     524                 :            :                 }
     525                 :            : 
     526                 :          0 :                 h = x_malloc(sizeof(*h));
     527                 :          0 :                 hash_result_as_bytes(&fhash, h->hash);
     528                 :          0 :                 h->size = fhash.totalN;
     529                 :          0 :                 hashtable_insert(included_files, path, h);
     530                 :            :         } else {
     531                 :          0 :                 free(path);
     532                 :            :         }
     533                 :            : 
     534                 :          0 :         free(source);
     535                 :          0 :         return;
     536                 :            : 
     537                 :            : failure:
     538                 :          0 :         cc_log("Disabling direct mode");
     539                 :          0 :         conf->direct_mode = false;
     540                 :            :         /* Fall through. */
     541                 :            : ignore:
     542                 :          4 :         free(path);
     543                 :          4 :         free(source);
     544                 :            : }
     545                 :            : 
     546                 :            : /*
     547                 :            :  * Make a relative path from current working directory to path if path is under
     548                 :            :  * the base directory. Takes over ownership of path. Caller frees.
     549                 :            :  */
     550                 :            : static char *
     551                 :         74 : make_relative_path(char *path)
     552                 :            : {
     553                 :         74 :         char *relpath, *canon_path, *path_suffix = NULL;
     554                 :            :         struct stat st;
     555                 :            : 
     556 [ +  + ][ +  + ]:         74 :         if (str_eq(conf->base_dir, "") || !str_startswith(path, conf->base_dir)) {
     557                 :         73 :                 return path;
     558                 :            :         }
     559                 :            : 
     560                 :            :         /* x_realpath only works for existing paths, so if path doesn't exist, try
     561                 :            :          * dirname(path) and assemble the path afterwards. We only bother to try
     562                 :            :          * canonicalizing one of these two paths since a compiler path argument
     563                 :            :          * typically only makes sense if path or dirname(path) exists. */
     564         [ +  - ]:          1 :         if (stat(path, &st) != 0) {
     565                 :            :                 /* path doesn't exist. */
     566                 :            :                 char *dir, *p;
     567                 :          1 :                 dir = dirname(path);
     568         [ -  + ]:          1 :                 if (stat(dir, &st) != 0) {
     569                 :            :                         /* And neither does its parent directory, so no action to take. */
     570                 :          0 :                         free(dir);
     571                 :          0 :                         return path;
     572                 :            :                 }
     573                 :          1 :                 path_suffix = basename(path);
     574                 :          1 :                 p = path;
     575                 :          1 :                 path = dirname(path);
     576                 :          1 :                 free(p);
     577                 :            :         }
     578                 :            : 
     579                 :          1 :         canon_path = x_realpath(path);
     580         [ +  - ]:          1 :         if (canon_path) {
     581                 :          1 :                 free(path);
     582                 :          1 :                 relpath = get_relative_path(get_current_working_dir(), canon_path);
     583                 :          1 :                 free(canon_path);
     584         [ +  - ]:          1 :                 if (path_suffix) {
     585                 :          1 :                         path = format("%s/%s", relpath, path_suffix);
     586                 :          1 :                         free(relpath);
     587                 :          1 :                         free(path_suffix);
     588                 :          1 :                         return path;
     589                 :            :                 } else {
     590                 :          0 :                         return relpath;
     591                 :            :                 }
     592                 :            :         } else {
     593                 :            :                 /* path doesn't exist, so leave it as it is. */
     594                 :          0 :                 free(path_suffix);
     595                 :         74 :                 return path;
     596                 :            :         }
     597                 :            : }
     598                 :            : 
     599                 :            : /*
     600                 :            :  * This function reads and hashes a file. While doing this, it also does these
     601                 :            :  * things:
     602                 :            :  *
     603                 :            :  * - Makes include file paths for which the base directory is a prefix relative
     604                 :            :  *   when computing the hash sum.
     605                 :            :  * - Stores the paths and hashes of included files in the global variable
     606                 :            :  *   included_files.
     607                 :            :  */
     608                 :            : static bool
     609                 :          1 : process_preprocessed_file(struct mdfour *hash, const char *path)
     610                 :            : {
     611                 :            :         char *data;
     612                 :            :         char *p, *q, *end;
     613                 :            :         size_t size;
     614                 :            : 
     615         [ -  + ]:          1 :         if (!read_file(path, 0, &data, &size)) {
     616                 :          0 :                 return false;
     617                 :            :         }
     618                 :            : 
     619                 :          1 :         included_files = create_hashtable(1000, hash_from_string, strings_equal);
     620                 :            : 
     621                 :            :         /* Bytes between p and q are pending to be hashed. */
     622                 :          1 :         end = data + size;
     623                 :          1 :         p = data;
     624                 :          1 :         q = data;
     625         [ +  + ]:         37 :         while (q < end - 7) { /* There must be at least 7 characters (# 1 "x") left
     626                 :            :                                  to potentially find an include file path. */
     627                 :            :                 /*
     628                 :            :                  * Check if we look at a line containing the file name of an included file.
     629                 :            :                  * At least the following formats exist (where N is a positive integer):
     630                 :            :                  *
     631                 :            :                  * GCC:
     632                 :            :                  *
     633                 :            :                  *   # N "file"
     634                 :            :                  *   # N "file" N
     635                 :            :                  *   #pragma GCC pch_preprocess "file"
     636                 :            :                  *
     637                 :            :                  * HP's compiler:
     638                 :            :                  *
     639                 :            :                  *   #line N "file"
     640                 :            :                  *
     641                 :            :                  * AIX's compiler:
     642                 :            :                  *
     643                 :            :                  *   #line N "file"
     644                 :            :                  *   #line N
     645                 :            :                  *
     646                 :            :                  * Note that there may be other lines starting with '#' left after
     647                 :            :                  * preprocessing as well, for instance "#    pragma".
     648                 :            :                  */
     649 [ +  + ][ +  - ]:         40 :                 if (q[0] == '#'
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  + ]
                 [ +  - ]
     650                 :            :                         /* GCC: */
     651                 :         12 :                     && ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9')
     652                 :            :                         /* GCC precompiled header: */
     653                 :          0 :                         || (q[1] == 'p'
     654                 :          0 :                             && str_startswith(&q[2], "ragma GCC pch_preprocess "))
     655                 :            :                         /* HP/AIX: */
     656                 :          0 :                         || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e'
     657                 :          0 :                             && q[5] == ' '))
     658                 :          7 :                     && (q == data || q[-1] == '\n')) {
     659                 :            :                         char *path;
     660                 :            : 
     661 [ +  - ][ +  + ]:         20 :                         while (q < end && *q != '"' && *q != '\n') {
                 [ +  - ]
     662                 :         16 :                                 q++;
     663                 :            :                         }
     664 [ +  - ][ -  + ]:          4 :                         if (q < end && *q == '\n') {
     665                 :            :                                 /* A newline before the quotation mark -> no match. */
     666                 :          0 :                                 continue;
     667                 :            :                         }
     668                 :          4 :                         q++;
     669         [ -  + ]:          4 :                         if (q >= end) {
     670                 :          0 :                                 cc_log("Failed to parse included file path");
     671                 :          0 :                                 free(data);
     672                 :          0 :                                 return false;
     673                 :            :                         }
     674                 :            :                         /* q points to the beginning of an include file path */
     675                 :          4 :                         hash_buffer(hash, p, q - p);
     676                 :          4 :                         p = q;
     677 [ +  - ][ +  + ]:         42 :                         while (q < end && *q != '"') {
     678                 :         38 :                                 q++;
     679                 :            :                         }
     680                 :            :                         /* p and q span the include file path */
     681                 :          4 :                         path = x_strndup(p, q - p);
     682                 :          4 :                         path = make_relative_path(path);
     683                 :          4 :                         hash_string(hash, path);
     684                 :          4 :                         remember_include_file(path, hash);
     685                 :          4 :                         p = q;
     686                 :            :                 } else {
     687                 :         32 :                         q++;
     688                 :            :                 }
     689                 :            :         }
     690                 :            : 
     691                 :          1 :         hash_buffer(hash, p, (end - p));
     692                 :          1 :         free(data);
     693                 :            : 
     694                 :            :         /* Explicitly check the .gch/.pch/.pth file, Clang does not include any
     695                 :            :          * mention of it in the preprocessed output. */
     696         [ -  + ]:          1 :         if (included_pch_file) {
     697                 :          0 :                 char *path = x_strdup(included_pch_file);
     698                 :          0 :                 path = make_relative_path(path);
     699                 :          0 :                 hash_string(hash, path);
     700                 :          0 :                 remember_include_file(path, hash);
     701                 :            :         }
     702                 :            : 
     703                 :          1 :         return true;
     704                 :            : }
     705                 :            : 
     706                 :            : /* Copy or link a file to the cache. */
     707                 :            : static void
     708                 :          1 : put_file_in_cache(const char *source, const char *dest)
     709                 :            : {
     710                 :            :         int ret;
     711                 :            :         struct stat st;
     712 [ -  + ][ #  # ]:          1 :         bool do_link = conf->hard_link && !conf->compression;
     713                 :            : 
     714         [ -  + ]:          1 :         if (do_link) {
     715                 :          0 :                 x_unlink(dest);
     716                 :          0 :                 ret = link(source, dest);
     717                 :            :         } else {
     718                 :          1 :                 ret = copy_file(source, dest, conf->compression);
     719                 :            :         }
     720         [ -  + ]:          1 :         if (ret != 0) {
     721         [ #  # ]:          0 :                 cc_log("Failed to %s %s to %s: %s",
     722                 :            :                        do_link ? "link" : "copy",
     723                 :            :                        source,
     724                 :            :                        dest,
     725                 :            :                        strerror(errno));
     726                 :          0 :                 stats_update(STATS_ERROR);
     727                 :          0 :                 failed();
     728                 :            :         }
     729                 :          1 :         cc_log("Stored in cache: %s -> %s", source, dest);
     730         [ -  + ]:          1 :         if (x_stat(dest, &st) != 0) {
     731                 :          0 :                 stats_update(STATS_ERROR);
     732                 :          0 :                 failed();
     733                 :            :         }
     734                 :          1 :         stats_update_size(file_size(&st), 1);
     735                 :          1 : }
     736                 :            : 
     737                 :            : /* Copy or link a file from the cache. */
     738                 :            : static void
     739                 :          0 : get_file_from_cache(const char *source, const char *dest)
     740                 :            : {
     741                 :            :         int ret;
     742 [ #  # ][ #  # ]:          0 :         bool do_link = conf->hard_link && !file_is_compressed(source);
     743                 :            : 
     744         [ #  # ]:          0 :         if (do_link) {
     745                 :          0 :                 x_unlink(dest);
     746                 :          0 :                 ret = link(source, dest);
     747                 :            :         } else {
     748                 :          0 :                 ret = copy_file(source, dest, 0);
     749                 :            :         }
     750                 :            : 
     751         [ #  # ]:          0 :         if (ret == -1) {
     752         [ #  # ]:          0 :                 if (errno == ENOENT) {
     753                 :            :                         /* Someone removed the file just before we began copying? */
     754                 :          0 :                         cc_log("Cache file %s just disappeared from cache", source);
     755                 :          0 :                         stats_update(STATS_MISSING);
     756                 :            :                 } else {
     757         [ #  # ]:          0 :                         cc_log("Failed to %s %s to %s: %s",
     758                 :            :                                do_link ? "link" : "copy",
     759                 :            :                                source,
     760                 :            :                                dest,
     761                 :            :                                strerror(errno));
     762                 :          0 :                         stats_update(STATS_ERROR);
     763                 :            :                 }
     764                 :            : 
     765                 :            :                 /* If there was trouble getting a file from the cached result, wipe the
     766                 :            :                  * whole cached result for consistency. */
     767                 :          0 :                 x_unlink(cached_stderr);
     768                 :          0 :                 x_unlink(cached_obj);
     769                 :          0 :                 x_unlink(cached_dep);
     770                 :          0 :                 x_unlink(cached_dia);
     771                 :            : 
     772                 :          0 :                 failed();
     773                 :            :         }
     774                 :            : 
     775                 :          0 :         cc_log("Created from cache: %s -> %s", source, dest);
     776                 :          0 : }
     777                 :            : 
     778                 :            : /* Send cached stderr, if any, to stderr. */
     779                 :            : static void
     780                 :          1 : send_cached_stderr(void)
     781                 :            : {
     782                 :          1 :         int fd_stderr = open(cached_stderr, O_RDONLY | O_BINARY);
     783         [ +  - ]:          1 :         if (fd_stderr != -1) {
     784                 :          1 :                 copy_fd(fd_stderr, 2);
     785                 :          1 :                 close(fd_stderr);
     786                 :            :         }
     787                 :          1 : }
     788                 :            : 
     789                 :            : /* Create or update the manifest file. */
     790                 :          1 : void update_manifest_file(void)
     791                 :            : {
     792                 :            :         struct stat st;
     793                 :          1 :         size_t old_size = 0; /* in bytes */
     794                 :            : 
     795 [ -  + ][ #  # ]:          1 :         if (!conf->direct_mode
         [ #  # ][ #  # ]
     796                 :          0 :             || !included_files
     797                 :          0 :             || conf->read_only
     798                 :          0 :             || conf->read_only_direct) {
     799                 :          1 :                 return;
     800                 :            :         }
     801                 :            : 
     802         [ #  # ]:          0 :         if (stat(manifest_path, &st) == 0) {
     803                 :          0 :                 old_size = file_size(&st);
     804                 :            :         }
     805         [ #  # ]:          0 :         if (manifest_put(manifest_path, cached_obj_hash, included_files)) {
     806                 :          0 :                 cc_log("Added object file hash to %s", manifest_path);
     807                 :          0 :                 update_mtime(manifest_path);
     808         [ #  # ]:          0 :                 if (x_stat(manifest_path, &st) == 0) {
     809                 :          0 :                         stats_update_size(file_size(&st) - old_size, old_size == 0 ? 1 : 0);
     810                 :            :                 }
     811                 :            :         } else {
     812                 :          1 :                 cc_log("Failed to add object file hash to %s", manifest_path);
     813                 :            :         }
     814                 :            : }
     815                 :            : 
     816                 :            : /* run the real compiler and put the result in cache */
     817                 :            : static void
     818                 :          1 : to_cache(struct args *args)
     819                 :            : {
     820                 :            :         char *tmp_stdout, *tmp_stderr, *tmp_aux, *tmp_cov;
     821                 :          1 :         char *tmp_dwo = NULL;
     822                 :            :         struct stat st;
     823                 :            :         int status, tmp_stdout_fd, tmp_stderr_fd;
     824                 :            :         FILE *f;
     825                 :            : 
     826                 :          1 :         tmp_stdout = format("%s.tmp.stdout", cached_obj);
     827                 :          1 :         tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
     828                 :          1 :         tmp_stderr = format("%s.tmp.stderr", cached_obj);
     829                 :          1 :         tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
     830                 :            : 
     831         [ -  + ]:          1 :         if (generating_coverage) {
     832                 :            :                 /* gcc has some funny rule about max extension length */
     833         [ #  # ]:          0 :                 if (strlen(get_extension(output_obj)) < 6) {
     834                 :          0 :                         tmp_aux = remove_extension(output_obj);
     835                 :            :                 } else {
     836                 :          0 :                         tmp_aux = x_strdup(output_obj);
     837                 :            :                 }
     838                 :          0 :                 tmp_cov = format("%s.gcno", tmp_aux);
     839                 :          0 :                 free(tmp_aux);
     840                 :            :         } else {
     841                 :          1 :                 tmp_cov = NULL;
     842                 :            :         }
     843                 :            : 
     844                 :            :         /* GCC (at least 4.8 and 4.9) forms the .dwo file name by removing everything
     845                 :            :          * after (and including) the last "." from the object file name and then
     846                 :            :          * appending ".dwo".
     847                 :            :          */
     848         [ -  + ]:          1 :         if (using_split_dwarf) {
     849                 :          0 :                 char *base_name = remove_extension(output_obj);
     850                 :          0 :                 tmp_dwo = format("%s.dwo", base_name);
     851                 :          0 :                 free(base_name);
     852                 :            :         }
     853                 :            : 
     854                 :          1 :         args_add(args, "-o");
     855                 :          1 :         args_add(args, output_obj);
     856                 :            : 
     857         [ -  + ]:          1 :         if (output_dia) {
     858                 :          0 :                 args_add(args, "--serialize-diagnostics");
     859                 :          0 :                 args_add(args, output_dia);
     860                 :            :         }
     861                 :            : 
     862                 :            :         /* Turn off DEPENDENCIES_OUTPUT when running cc1, because
     863                 :            :          * otherwise it will emit a line like
     864                 :            :          *
     865                 :            :          *  tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
     866                 :            :          */
     867                 :          1 :         x_unsetenv("DEPENDENCIES_OUTPUT");
     868                 :            : 
     869         [ -  + ]:          1 :         if (conf->run_second_cpp) {
     870                 :          0 :                 args_add(args, input_file);
     871                 :            :         } else {
     872                 :          1 :                 args_add(args, i_tmpfile);
     873                 :            :         }
     874                 :            : 
     875                 :          1 :         cc_log("Running real compiler");
     876                 :          1 :         status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd);
     877                 :          1 :         args_pop(args, 3);
     878                 :            : 
     879         [ -  + ]:          1 :         if (x_stat(tmp_stdout, &st) != 0) {
     880                 :            :                 /* The stdout file was removed - cleanup in progress? Better bail out. */
     881                 :          0 :                 stats_update(STATS_MISSING);
     882                 :          0 :                 tmp_unlink(tmp_stdout);
     883                 :          0 :                 tmp_unlink(tmp_stderr);
     884         [ #  # ]:          0 :                 if (tmp_cov) {
     885                 :          0 :                         tmp_unlink(tmp_cov);
     886                 :            :                 }
     887                 :          0 :                 tmp_unlink(tmp_dwo);
     888                 :          0 :                 failed();
     889                 :            :         }
     890         [ -  + ]:          1 :         if (st.st_size != 0) {
     891                 :          0 :                 cc_log("Compiler produced stdout");
     892                 :          0 :                 stats_update(STATS_STDOUT);
     893                 :          0 :                 tmp_unlink(tmp_stdout);
     894                 :          0 :                 tmp_unlink(tmp_stderr);
     895         [ #  # ]:          0 :                 if (tmp_cov) {
     896                 :          0 :                         tmp_unlink(tmp_cov);
     897                 :            :                 }
     898                 :          0 :                 tmp_unlink(tmp_dwo);
     899                 :          0 :                 failed();
     900                 :            :         }
     901                 :          1 :         tmp_unlink(tmp_stdout);
     902                 :            : 
     903                 :            :         /*
     904                 :            :          * Merge stderr from the preprocessor (if any) and stderr from the real
     905                 :            :          * compiler into tmp_stderr.
     906                 :            :          */
     907         [ +  - ]:          1 :         if (cpp_stderr) {
     908                 :            :                 int fd_cpp_stderr;
     909                 :            :                 int fd_real_stderr;
     910                 :            :                 int fd_result;
     911                 :            :                 char *tmp_stderr2;
     912                 :            : 
     913                 :          1 :                 tmp_stderr2 = format("%s.2", tmp_stderr);
     914         [ -  + ]:          1 :                 if (x_rename(tmp_stderr, tmp_stderr2)) {
     915                 :          0 :                         cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2,
     916                 :            :                                strerror(errno));
     917                 :          0 :                         failed();
     918                 :            :                 }
     919                 :          1 :                 fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
     920         [ -  + ]:          1 :                 if (fd_cpp_stderr == -1) {
     921                 :          0 :                         cc_log("Failed opening %s: %s", cpp_stderr, strerror(errno));
     922                 :          0 :                         failed();
     923                 :            :                 }
     924                 :          1 :                 fd_real_stderr = open(tmp_stderr2, O_RDONLY | O_BINARY);
     925         [ -  + ]:          1 :                 if (fd_real_stderr == -1) {
     926                 :          0 :                         cc_log("Failed opening %s: %s", tmp_stderr2, strerror(errno));
     927                 :          0 :                         failed();
     928                 :            :                 }
     929                 :          1 :                 fd_result = open(tmp_stderr, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
     930         [ -  + ]:          1 :                 if (fd_result == -1) {
     931                 :          0 :                         cc_log("Failed opening %s: %s", tmp_stderr, strerror(errno));
     932                 :          0 :                         failed();
     933                 :            :                 }
     934                 :          1 :                 copy_fd(fd_cpp_stderr, fd_result);
     935                 :          1 :                 copy_fd(fd_real_stderr, fd_result);
     936                 :          1 :                 close(fd_cpp_stderr);
     937                 :          1 :                 close(fd_real_stderr);
     938                 :          1 :                 close(fd_result);
     939                 :          1 :                 tmp_unlink(tmp_stderr2);
     940                 :          1 :                 free(tmp_stderr2);
     941                 :            :         }
     942                 :            : 
     943         [ -  + ]:          1 :         if (status != 0) {
     944                 :            :                 int fd;
     945                 :          0 :                 cc_log("Compiler gave exit status %d", status);
     946                 :          0 :                 stats_update(STATS_STATUS);
     947                 :            : 
     948                 :          0 :                 fd = open(tmp_stderr, O_RDONLY | O_BINARY);
     949         [ #  # ]:          0 :                 if (fd != -1) {
     950                 :            :                         /* We can output stderr immediately instead of rerunning the compiler. */
     951                 :          0 :                         copy_fd(fd, 2);
     952                 :          0 :                         close(fd);
     953                 :          0 :                         tmp_unlink(tmp_stderr);
     954                 :            : 
     955                 :          0 :                         x_exit(status);
     956                 :            :                 }
     957                 :            : 
     958                 :          0 :                 tmp_unlink(tmp_stderr);
     959         [ #  # ]:          0 :                 if (tmp_cov) {
     960                 :          0 :                         tmp_unlink(tmp_cov);
     961                 :            :                 }
     962                 :          0 :                 tmp_unlink(tmp_dwo);
     963                 :            : 
     964                 :          0 :                 failed();
     965                 :            :         }
     966                 :            : 
     967         [ -  + ]:          1 :         if (stat(output_obj, &st) != 0) {
     968                 :          0 :                 cc_log("Compiler didn't produce an object file");
     969                 :          0 :                 stats_update(STATS_NOOUTPUT);
     970                 :          0 :                 failed();
     971                 :            :         }
     972         [ -  + ]:          1 :         if (st.st_size == 0) {
     973                 :          0 :                 cc_log("Compiler produced an empty object file");
     974                 :          0 :                 stats_update(STATS_EMPTYOUTPUT);
     975                 :          0 :                 failed();
     976                 :            :         }
     977                 :            : 
     978         [ -  + ]:          1 :         if (using_split_dwarf) {
     979         [ #  # ]:          0 :                 if (stat(tmp_dwo, &st) != 0) {
     980                 :          0 :                         cc_log("Compiler didn't produce a split dwarf file");
     981                 :          0 :                         stats_update(STATS_NOOUTPUT);
     982                 :          0 :                         failed();
     983                 :            :                 }
     984         [ #  # ]:          0 :                 if (st.st_size == 0) {
     985                 :          0 :                         cc_log("Compiler produced an empty split dwarf file");
     986                 :          0 :                         stats_update(STATS_EMPTYOUTPUT);
     987                 :          0 :                         failed();
     988                 :            :                 }
     989                 :            :         }
     990                 :            : 
     991         [ -  + ]:          1 :         if (x_stat(tmp_stderr, &st) != 0) {
     992                 :          0 :                 stats_update(STATS_ERROR);
     993                 :          0 :                 failed();
     994                 :            :         }
     995         [ +  - ]:          1 :         if (st.st_size > 0) {
     996 [ -  + ][ -  + ]:          1 :                 if (move_uncompressed_file(
     997                 :            :                             tmp_stderr, cached_stderr,
     998                 :          1 :                             conf->compression ? conf->compression_level : 0) != 0) {
     999                 :          0 :                         cc_log("Failed to move %s to %s: %s", tmp_stderr, cached_stderr,
    1000                 :            :                                strerror(errno));
    1001                 :          0 :                         stats_update(STATS_ERROR);
    1002                 :          0 :                         failed();
    1003                 :            :                 }
    1004                 :          1 :                 cc_log("Stored in cache: %s", cached_stderr);
    1005         [ -  + ]:          1 :                 if (!conf->compression
           [ #  #  #  # ]
    1006                 :            :                     /* If the file was compressed, obtain the size again: */
    1007                 :          0 :                     || (conf->compression && x_stat(cached_stderr, &st) == 0)) {
    1008                 :          1 :                         stats_update_size(file_size(&st), 1);
    1009                 :            :                 }
    1010                 :            :         } else {
    1011                 :          0 :                 tmp_unlink(tmp_stderr);
    1012         [ #  # ]:          0 :                 if (conf->recache) {
    1013                 :            :                         /* If recaching, we need to remove any previous .stderr. */
    1014                 :          0 :                         x_unlink(cached_stderr);
    1015                 :            :                 }
    1016                 :            :         }
    1017                 :            : 
    1018         [ -  + ]:          1 :         if (generating_coverage) {
    1019                 :            :                 /* gcc won't generate notes if there is no code */
    1020 [ #  # ][ #  # ]:          0 :                 if (stat(tmp_cov, &st) != 0 && errno == ENOENT) {
    1021                 :          0 :                         cc_log("Creating placeholder: %s", cached_cov);
    1022                 :            : 
    1023                 :          0 :                         f = fopen(cached_cov, "wb");
    1024         [ #  # ]:          0 :                         if (!f) {
    1025                 :          0 :                                 cc_log("Failed to create %s: %s", cached_cov, strerror(errno));
    1026                 :          0 :                                 stats_update(STATS_ERROR);
    1027                 :          0 :                                 failed();
    1028                 :            :                         }
    1029                 :          0 :                         fclose(f);
    1030                 :          0 :                         stats_update_size(0, 1);
    1031                 :            :                 } else {
    1032                 :          0 :                         put_file_in_cache(tmp_cov, cached_cov);
    1033                 :            :                 }
    1034                 :            :         }
    1035                 :            : 
    1036         [ -  + ]:          1 :         if (output_dia) {
    1037         [ #  # ]:          0 :                 if (x_stat(output_dia, &st) != 0) {
    1038                 :          0 :                         stats_update(STATS_ERROR);
    1039                 :          0 :                         failed();
    1040                 :            :                 }
    1041         [ #  # ]:          0 :                 if (st.st_size > 0) {
    1042                 :          0 :                         put_file_in_cache(output_dia, cached_dia);
    1043                 :            :                 }
    1044                 :            :         }
    1045                 :            : 
    1046                 :          1 :         put_file_in_cache(output_obj, cached_obj);
    1047                 :            : 
    1048         [ -  + ]:          1 :         if (using_split_dwarf) {
    1049         [ #  # ]:          0 :                 assert(tmp_dwo);
    1050         [ #  # ]:          0 :                 assert(cached_dwo);
    1051                 :          0 :                 put_file_in_cache(tmp_dwo, cached_dwo);
    1052                 :            :         }
    1053                 :            : 
    1054         [ -  + ]:          1 :         if (generating_dependencies) {
    1055                 :          0 :                 put_file_in_cache(output_dep, cached_dep);
    1056                 :            :         }
    1057                 :          1 :         stats_update(STATS_TOCACHE);
    1058                 :            : 
    1059                 :            :         /* Make sure we have a CACHEDIR.TAG in the cache part of cache_dir. This can
    1060                 :            :          * be done almost anywhere, but we might as well do it near the end as we
    1061                 :            :          * save the stat call if we exit early.
    1062                 :            :          */
    1063                 :            :         {
    1064                 :          1 :                 char *first_level_dir = dirname(stats_file);
    1065         [ -  + ]:          1 :                 if (create_cachedirtag(first_level_dir) != 0) {
    1066                 :          0 :                         cc_log("Failed to create %s/CACHEDIR.TAG (%s)\n",
    1067                 :            :                                first_level_dir, strerror(errno));
    1068                 :          0 :                         stats_update(STATS_ERROR);
    1069                 :          0 :                         failed();
    1070                 :            :                 }
    1071                 :          1 :                 free(first_level_dir);
    1072                 :            : 
    1073                 :            :                 /* Remove any CACHEDIR.TAG on the cache_dir level where it was located in
    1074                 :            :                  * previous ccache versions. */
    1075         [ -  + ]:          1 :                 if (getpid() % 1000 == 0) {
    1076                 :          0 :                         char *path = format("%s/CACHEDIR.TAG", conf->cache_dir);
    1077                 :          0 :                         x_unlink(path);
    1078                 :          0 :                         free(path);
    1079                 :            :                 }
    1080                 :            :         }
    1081                 :            : 
    1082                 :            :         /* Everything OK. */
    1083                 :          1 :         send_cached_stderr();
    1084                 :          1 :         update_manifest_file();
    1085                 :            : 
    1086                 :          1 :         free(tmp_stderr);
    1087                 :          1 :         free(tmp_stdout);
    1088                 :          1 :         free(tmp_cov);
    1089                 :          1 :         free(tmp_dwo);
    1090                 :          1 : }
    1091                 :            : 
    1092                 :            : /*
    1093                 :            :  * Find the object file name by running the compiler in preprocessor mode.
    1094                 :            :  * Returns the hash as a heap-allocated hex string.
    1095                 :            :  */
    1096                 :            : static struct file_hash *
    1097                 :          1 : get_object_name_from_cpp(struct args *args, struct mdfour *hash)
    1098                 :            : {
    1099                 :            :         char *input_base;
    1100                 :            :         char *tmp;
    1101                 :            :         char *path_stdout, *path_stderr;
    1102                 :            :         int status, path_stderr_fd;
    1103                 :            :         struct file_hash *result;
    1104                 :            : 
    1105                 :            :         /* ~/hello.c -> tmp.hello.123.i
    1106                 :            :            limit the basename to 10
    1107                 :            :            characters in order to cope with filesystem with small
    1108                 :            :            maximum filename length limits */
    1109                 :          1 :         input_base = basename(input_file);
    1110                 :          1 :         tmp = strchr(input_base, '.');
    1111         [ +  - ]:          1 :         if (tmp) {
    1112                 :          1 :                 *tmp = 0;
    1113                 :            :         }
    1114         [ -  + ]:          1 :         if (strlen(input_base) > 10) {
    1115                 :          0 :                 input_base[10] = 0;
    1116                 :            :         }
    1117                 :            : 
    1118                 :          1 :         path_stderr = format("%s/tmp.cpp_stderr", temp_dir());
    1119                 :          1 :         path_stderr_fd = create_tmp_fd(&path_stderr);
    1120                 :          1 :         add_pending_tmp_file(path_stderr);
    1121                 :            : 
    1122                 :          1 :         time_of_compilation = time(NULL);
    1123                 :            : 
    1124         [ -  + ]:          1 :         if (direct_i_file) {
    1125                 :            :                 /* We are compiling a .i or .ii file - that means we can skip the cpp stage
    1126                 :            :                  * and directly form the correct i_tmpfile. */
    1127                 :          0 :                 path_stdout = input_file;
    1128                 :          0 :                 status = 0;
    1129                 :            :         } else {
    1130                 :            :                 /* Run cpp on the input file to obtain the .i. */
    1131                 :            :                 int path_stdout_fd;
    1132                 :          1 :                 path_stdout = format("%s/%s.stdout", temp_dir(), input_base);
    1133                 :          1 :                 path_stdout_fd = create_tmp_fd(&path_stdout);
    1134                 :          1 :                 add_pending_tmp_file(path_stdout);
    1135                 :            : 
    1136                 :          1 :                 args_add(args, "-E");
    1137                 :          1 :                 args_add(args, input_file);
    1138                 :          1 :                 cc_log("Running preprocessor");
    1139                 :          1 :                 status = execute(args->argv, path_stdout_fd, path_stderr_fd);
    1140                 :          1 :                 args_pop(args, 2);
    1141                 :            :         }
    1142                 :            : 
    1143         [ -  + ]:          1 :         if (status != 0) {
    1144                 :          0 :                 cc_log("Preprocessor gave exit status %d", status);
    1145                 :          0 :                 stats_update(STATS_PREPROCESSOR);
    1146                 :          0 :                 failed();
    1147                 :            :         }
    1148                 :            : 
    1149         [ -  + ]:          1 :         if (conf->unify) {
    1150                 :            :                 /* When we are doing the unifying tricks we need to include the input file
    1151                 :            :                  * name in the hash to get the warnings right. */
    1152                 :          0 :                 hash_delimiter(hash, "unifyfilename");
    1153                 :          0 :                 hash_string(hash, input_file);
    1154                 :            : 
    1155                 :          0 :                 hash_delimiter(hash, "unifycpp");
    1156         [ #  # ]:          0 :                 if (unify_hash(hash, path_stdout) != 0) {
    1157                 :          0 :                         stats_update(STATS_ERROR);
    1158                 :          0 :                         cc_log("Failed to unify %s", path_stdout);
    1159                 :          0 :                         failed();
    1160                 :            :                 }
    1161                 :            :         } else {
    1162                 :          1 :                 hash_delimiter(hash, "cpp");
    1163         [ -  + ]:          1 :                 if (!process_preprocessed_file(hash, path_stdout)) {
    1164                 :          0 :                         stats_update(STATS_ERROR);
    1165                 :          0 :                         failed();
    1166                 :            :                 }
    1167                 :            :         }
    1168                 :            : 
    1169                 :          1 :         hash_delimiter(hash, "cppstderr");
    1170         [ -  + ]:          1 :         if (!hash_file(hash, path_stderr)) {
    1171                 :          0 :                 fatal("Failed to open %s: %s", path_stderr, strerror(errno));
    1172                 :            :         }
    1173                 :            : 
    1174         [ -  + ]:          1 :         if (direct_i_file) {
    1175                 :          0 :                 i_tmpfile = input_file;
    1176                 :            :         } else {
    1177                 :            :                 /* i_tmpfile needs the proper cpp_extension for the compiler to do its
    1178                 :            :                  * thing correctly. */
    1179                 :          1 :                 i_tmpfile = format("%s.%s", path_stdout, conf->cpp_extension);
    1180                 :          1 :                 x_rename(path_stdout, i_tmpfile);
    1181                 :          1 :                 add_pending_tmp_file(i_tmpfile);
    1182                 :            :         }
    1183                 :            : 
    1184         [ -  + ]:          1 :         if (conf->run_second_cpp) {
    1185                 :          0 :                 free(path_stderr);
    1186                 :            :         } else {
    1187                 :            :                 /*
    1188                 :            :                  * If we are using the CPP trick, we need to remember this
    1189                 :            :                  * stderr data and output it just before the main stderr from
    1190                 :            :                  * the compiler pass.
    1191                 :            :                  */
    1192                 :          1 :                 cpp_stderr = path_stderr;
    1193                 :          1 :                 hash_delimiter(hash, "runsecondcpp");
    1194                 :          1 :                 hash_string(hash, "false");
    1195                 :            :         }
    1196                 :            : 
    1197                 :          1 :         result = x_malloc(sizeof(*result));
    1198                 :          1 :         hash_result_as_bytes(hash, result->hash);
    1199                 :          1 :         result->size = hash->totalN;
    1200                 :          1 :         return result;
    1201                 :            : }
    1202                 :            : 
    1203                 :            : static void
    1204                 :          1 : update_cached_result_globals(struct file_hash *hash)
    1205                 :            : {
    1206                 :            :         char *object_name;
    1207                 :          1 :         object_name = format_hash_as_string(hash->hash, hash->size);
    1208                 :          1 :         cached_obj_hash = hash;
    1209                 :          1 :         cached_obj = get_path_in_cache(object_name, ".o");
    1210                 :          1 :         cached_stderr = get_path_in_cache(object_name, ".stderr");
    1211                 :          1 :         cached_dep = get_path_in_cache(object_name, ".d");
    1212                 :          1 :         cached_cov = get_path_in_cache(object_name, ".gcno");
    1213                 :          1 :         cached_dia = get_path_in_cache(object_name, ".dia");
    1214                 :            : 
    1215         [ -  + ]:          1 :         if (using_split_dwarf) {
    1216                 :          0 :                 cached_dwo = get_path_in_cache(object_name, ".dwo");
    1217                 :            :         } else {
    1218                 :          1 :                 cached_dwo = NULL;
    1219                 :            :         }
    1220                 :            : 
    1221                 :          1 :         stats_file = format("%s/%c/stats", conf->cache_dir, object_name[0]);
    1222                 :          1 :         free(object_name);
    1223                 :          1 : }
    1224                 :            : 
    1225                 :            : /*
    1226                 :            :  * Hash mtime or content of a file, or the output of a command, according to
    1227                 :            :  * the CCACHE_COMPILERCHECK setting.
    1228                 :            :  */
    1229                 :            : static void
    1230                 :          1 : hash_compiler(struct mdfour *hash, struct stat *st, const char *path,
    1231                 :            :               bool allow_command)
    1232                 :            : {
    1233         [ -  + ]:          1 :         if (str_eq(conf->compiler_check, "none")) {
    1234                 :            :                 /* Do nothing. */
    1235         [ +  - ]:          1 :         } else if (str_eq(conf->compiler_check, "mtime")) {
    1236                 :          1 :                 hash_delimiter(hash, "cc_mtime");
    1237                 :          1 :                 hash_int(hash, st->st_size);
    1238                 :          1 :                 hash_int(hash, st->st_mtime);
    1239         [ #  # ]:          0 :         } else if (str_startswith(conf->compiler_check, "string:")) {
    1240                 :          0 :                 hash_delimiter(hash, "cc_hash");
    1241                 :          0 :                 hash_string(hash, conf->compiler_check + strlen("string:"));
    1242 [ #  # ][ #  # ]:          0 :         } else if (str_eq(conf->compiler_check, "content") || !allow_command) {
    1243                 :          0 :                 hash_delimiter(hash, "cc_content");
    1244                 :          0 :                 hash_file(hash, path);
    1245                 :            :         } else { /* command string */
    1246         [ #  # ]:          0 :                 if (!hash_multicommand_output(
    1247                 :          0 :                             hash, conf->compiler_check, orig_args->argv[0])) {
    1248                 :          0 :                         fatal("Failure running compiler check command: %s", conf->compiler_check);
    1249                 :            :                 }
    1250                 :            :         }
    1251                 :          1 : }
    1252                 :            : 
    1253                 :            : /*
    1254                 :            :  * Note that these compiler checks are unreliable, so nothing should
    1255                 :            :  * hard-depend on them.
    1256                 :            :  */
    1257                 :            : 
    1258                 :            : static bool
    1259                 :          0 : compiler_is_clang(struct args *args)
    1260                 :            : {
    1261                 :          0 :         char *name = basename(args->argv[0]);
    1262                 :          0 :         bool is = strstr(name, "clang");
    1263                 :          0 :         free(name);
    1264                 :          0 :         return is;
    1265                 :            : }
    1266                 :            : 
    1267                 :            : static bool
    1268                 :          1 : compiler_is_gcc(struct args *args)
    1269                 :            : {
    1270                 :          1 :         char *name = basename(args->argv[0]);
    1271 [ -  + ][ #  # ]:          1 :         bool is = strstr(name, "gcc") || strstr(name, "g++");
    1272                 :          1 :         free(name);
    1273                 :          1 :         return is;
    1274                 :            : }
    1275                 :            : 
    1276                 :            : /*
    1277                 :            :  * Update a hash sum with information common for the direct and preprocessor
    1278                 :            :  * modes.
    1279                 :            :  */
    1280                 :            : static void
    1281                 :          1 : calculate_common_hash(struct args *args, struct mdfour *hash)
    1282                 :            : {
    1283                 :            :         struct stat st;
    1284                 :            :         char *p;
    1285                 :          1 :         const char *full_path = args->argv[0];
    1286                 :            : #ifdef _WIN32
    1287                 :            :         const char *ext;
    1288                 :            :         char full_path_win_ext[MAX_PATH + 1] = {0};
    1289                 :            : #endif
    1290                 :            : 
    1291                 :          1 :         hash_string(hash, HASH_PREFIX);
    1292                 :            : 
    1293                 :            :         /*
    1294                 :            :          * We have to hash the extension, as a .i file isn't treated the same
    1295                 :            :          * by the compiler as a .ii file.
    1296                 :            :          */
    1297                 :          1 :         hash_delimiter(hash, "ext");
    1298                 :          1 :         hash_string(hash, conf->cpp_extension);
    1299                 :            : 
    1300                 :            : #ifdef _WIN32
    1301                 :            :         ext = strrchr(args->argv[0], '.');
    1302                 :            :         add_exe_ext_if_no_to_fullpath(full_path_win_ext, MAX_PATH, ext,
    1303                 :            :                                       args->argv[0]);
    1304                 :            :         full_path = full_path_win_ext;
    1305                 :            : #endif
    1306                 :            : 
    1307         [ -  + ]:          1 :         if (x_stat(full_path, &st) != 0) {
    1308                 :          0 :                 stats_update(STATS_COMPILER);
    1309                 :          0 :                 failed();
    1310                 :            :         }
    1311                 :            : 
    1312                 :            :         /*
    1313                 :            :          * Hash information about the compiler.
    1314                 :            :          */
    1315                 :          1 :         hash_compiler(hash, &st, args->argv[0], true);
    1316                 :            : 
    1317                 :            :         /*
    1318                 :            :          * Also hash the compiler name as some compilers use hard links and
    1319                 :            :          * behave differently depending on the real name.
    1320                 :            :          */
    1321                 :          1 :         hash_delimiter(hash, "cc_name");
    1322                 :          1 :         p = basename(args->argv[0]);
    1323                 :          1 :         hash_string(hash, p);
    1324                 :          1 :         free(p);
    1325                 :            : 
    1326                 :            :         /* Possibly hash the current working directory. */
    1327         [ -  + ]:          1 :         if (conf->hash_dir) {
    1328                 :          0 :                 char *cwd = gnu_getcwd();
    1329         [ #  # ]:          0 :                 if (cwd) {
    1330                 :          0 :                         hash_delimiter(hash, "cwd");
    1331                 :          0 :                         hash_string(hash, cwd);
    1332                 :          0 :                         free(cwd);
    1333                 :            :                 }
    1334                 :            :         }
    1335                 :            : 
    1336                 :            :         /* Possibly hash the coverage data file path. */
    1337 [ -  + ][ #  # ]:          1 :         if (generating_coverage && profile_arcs) {
    1338                 :            :                 char *gcda_path;
    1339                 :          0 :                 char *dir = dirname(output_obj);
    1340         [ #  # ]:          0 :                 if (profile_dir) {
    1341                 :          0 :                         dir = x_strdup(profile_dir);
    1342                 :            :                 } else {
    1343                 :          0 :                         char *real_dir = x_realpath(dir);
    1344                 :          0 :                         free(dir);
    1345                 :          0 :                         dir = real_dir;
    1346                 :            :                 }
    1347         [ #  # ]:          0 :                 if (dir) {
    1348                 :          0 :                         char *base_name = basename(output_obj);
    1349                 :          0 :                         p = remove_extension(base_name);
    1350                 :          0 :                         free(base_name);
    1351                 :          0 :                         gcda_path = format("%s/%s.gcda", dir, p);
    1352                 :          0 :                         cc_log("Hashing coverage path %s", gcda_path);
    1353                 :          0 :                         free(p);
    1354                 :          0 :                         hash_delimiter(hash, "gcda");
    1355                 :          0 :                         hash_string(hash, gcda_path);
    1356                 :          0 :                         free(dir);
    1357                 :            :                 }
    1358                 :            :         }
    1359                 :            : 
    1360         [ -  + ]:          1 :         if (!str_eq(conf->extra_files_to_hash, "")) {
    1361                 :          0 :                 char *path, *p, *q, *saveptr = NULL;
    1362                 :          0 :                 p = x_strdup(conf->extra_files_to_hash);
    1363                 :          0 :                 q = p;
    1364         [ #  # ]:          0 :                 while ((path = strtok_r(q, PATH_DELIM, &saveptr))) {
    1365                 :          0 :                         cc_log("Hashing extra file %s", path);
    1366                 :          0 :                         hash_delimiter(hash, "extrafile");
    1367         [ #  # ]:          0 :                         if (!hash_file(hash, path)) {
    1368                 :          0 :                                 stats_update(STATS_BADEXTRAFILE);
    1369                 :          0 :                                 failed();
    1370                 :            :                         }
    1371                 :          0 :                         q = NULL;
    1372                 :            :                 }
    1373                 :          0 :                 free(p);
    1374                 :            :         }
    1375                 :            : 
    1376                 :            :         /* Possibly hash GCC_COLORS (for color diagnostics). */
    1377         [ +  - ]:          1 :         if (compiler_is_gcc(args)) {
    1378                 :          1 :                 const char *gcc_colors = getenv("GCC_COLORS");
    1379         [ -  + ]:          1 :                 if (gcc_colors) {
    1380                 :          0 :                         hash_delimiter(hash, "gcccolors");
    1381                 :          0 :                         hash_string(hash, gcc_colors);
    1382                 :            :                 }
    1383                 :            :         }
    1384                 :          1 : }
    1385                 :            : 
    1386                 :            : /*
    1387                 :            :  * Update a hash sum with information specific to the direct and preprocessor
    1388                 :            :  * modes and calculate the object hash. Returns the object hash on success,
    1389                 :            :  * otherwise NULL. Caller frees.
    1390                 :            :  */
    1391                 :            : static struct file_hash *
    1392                 :          1 : calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
    1393                 :            : {
    1394                 :            :         int i;
    1395                 :            :         char *manifest_name;
    1396                 :            :         struct stat st;
    1397                 :            :         int result;
    1398                 :          1 :         struct file_hash *object_hash = NULL;
    1399                 :            :         char *p;
    1400                 :            : 
    1401         [ -  + ]:          1 :         if (direct_mode) {
    1402                 :          0 :                 hash_delimiter(hash, "manifest version");
    1403                 :          0 :                 hash_int(hash, MANIFEST_VERSION);
    1404                 :            :         }
    1405                 :            : 
    1406                 :            :         /* first the arguments */
    1407         [ -  + ]:          1 :         for (i = 1; i < args->argc; i++) {
    1408                 :            :                 /* -L doesn't affect compilation. */
    1409 [ #  # ][ #  # ]:          0 :                 if (i < args->argc-1 && str_eq(args->argv[i], "-L")) {
    1410                 :          0 :                         i++;
    1411                 :          0 :                         continue;
    1412                 :            :                 }
    1413         [ #  # ]:          0 :                 if (str_startswith(args->argv[i], "-L")) {
    1414                 :          0 :                         continue;
    1415                 :            :                 }
    1416                 :            : 
    1417                 :            :                 /* -Wl,... doesn't affect compilation. */
    1418         [ #  # ]:          0 :                 if (str_startswith(args->argv[i], "-Wl,")) {
    1419                 :          0 :                         continue;
    1420                 :            :                 }
    1421                 :            : 
    1422                 :            :                 /* The -fdebug-prefix-map option may be used in combination with
    1423                 :            :                    CCACHE_BASEDIR to reuse results across different directories. Skip it
    1424                 :            :                    from hashing. */
    1425         [ #  # ]:          0 :                 if (str_startswith(args->argv[i], "-fdebug-prefix-map=")) {
    1426                 :          0 :                         continue;
    1427                 :            :                 }
    1428                 :            : 
    1429                 :            :                 /* When using the preprocessor, some arguments don't contribute
    1430                 :            :                    to the hash. The theory is that these arguments will change
    1431                 :            :                    the output of -E if they are going to have any effect at
    1432                 :            :                    all. For precompiled headers this might not be the case. */
    1433 [ #  # ][ #  # ]:          0 :                 if (!direct_mode && !output_is_precompiled_header
                 [ #  # ]
    1434                 :            :                     && !using_precompiled_header) {
    1435         [ #  # ]:          0 :                         if (compopt_affects_cpp(args->argv[i])) {
    1436                 :          0 :                                 i++;
    1437                 :          0 :                                 continue;
    1438                 :            :                         }
    1439         [ #  # ]:          0 :                         if (compopt_short(compopt_affects_cpp, args->argv[i])) {
    1440                 :          0 :                                 continue;
    1441                 :            :                         }
    1442                 :            :                 }
    1443                 :            : 
    1444                 :            :                 /* If we're generating dependencies, we make sure to skip the
    1445                 :            :                  * filename of the dependency file, since it doesn't impact the
    1446                 :            :                  * output.
    1447                 :            :                  */
    1448         [ #  # ]:          0 :                 if (generating_dependencies) {
    1449         [ #  # ]:          0 :                         if (str_startswith(args->argv[i], "-Wp,")) {
    1450 [ #  # ][ #  # ]:          0 :                                 if (str_startswith(args->argv[i], "-Wp,-MD,")
    1451                 :          0 :                                     && !strchr(args->argv[i] + 8, ',')) {
    1452                 :          0 :                                         hash_string_length(hash, args->argv[i], 8);
    1453                 :          0 :                                         continue;
    1454 [ #  # ][ #  # ]:          0 :                                 } else if (str_startswith(args->argv[i], "-Wp,-MMD,")
    1455                 :          0 :                                            && !strchr(args->argv[i] + 9, ',')) {
    1456                 :          0 :                                         hash_string_length(hash, args->argv[i], 9);
    1457                 :          0 :                                         continue;
    1458                 :            :                                 }
    1459         [ #  # ]:          0 :                         } else if (str_startswith(args->argv[i], "-MF")) {
    1460                 :          0 :                                 bool separate_argument = (strlen(args->argv[i]) == 3);
    1461                 :            : 
    1462                 :            :                                 /* In either case, hash the "-MF" part. */
    1463                 :          0 :                                 hash_string_length(hash, args->argv[i], 3);
    1464                 :            : 
    1465         [ #  # ]:          0 :                                 if (separate_argument) {
    1466                 :            :                                         /* Next argument is dependency name, so
    1467                 :            :                                          * skip it. */
    1468                 :          0 :                                         i++;
    1469                 :            :                                 }
    1470                 :          0 :                                 continue;
    1471                 :            :                         }
    1472                 :            :                 }
    1473                 :            : 
    1474                 :          0 :                 p = NULL;
    1475         [ #  # ]:          0 :                 if (str_startswith(args->argv[i], "-specs=")) {
    1476                 :          0 :                         p = args->argv[i] + 7;
    1477         [ #  # ]:          0 :                 } else if (str_startswith(args->argv[i], "--specs=")) {
    1478                 :          0 :                         p = args->argv[i] + 8;
    1479                 :            :                 }
    1480 [ #  # ][ #  # ]:          0 :                 if (p && x_stat(p, &st) == 0) {
    1481                 :            :                         /* If given an explicit specs file, then hash that file,
    1482                 :            :                            but don't include the path to it in the hash. */
    1483                 :          0 :                         hash_delimiter(hash, "specs");
    1484                 :          0 :                         hash_compiler(hash, &st, p, false);
    1485                 :          0 :                         continue;
    1486                 :            :                 }
    1487                 :            : 
    1488   [ #  #  #  # ]:          0 :                 if (str_startswith(args->argv[i], "-fplugin=")
    1489                 :          0 :                     && x_stat(args->argv[i] + 9, &st) == 0) {
    1490                 :          0 :                         hash_delimiter(hash, "plugin");
    1491                 :          0 :                         hash_compiler(hash, &st, args->argv[i] + 9, false);
    1492                 :          0 :                         continue;
    1493                 :            :                 }
    1494                 :            : 
    1495 [ #  # ][ #  # ]:          0 :                 if (str_eq(args->argv[i], "-Xclang")
                 [ #  # ]
           [ #  #  #  # ]
    1496                 :          0 :                     && i + 3 < args->argc
    1497                 :          0 :                     && str_eq(args->argv[i+1], "-load")
    1498                 :          0 :                     && str_eq(args->argv[i+2], "-Xclang")
    1499                 :          0 :                     && x_stat(args->argv[i+3], &st) == 0) {
    1500                 :          0 :                         hash_delimiter(hash, "plugin");
    1501                 :          0 :                         hash_compiler(hash, &st, args->argv[i+3], false);
    1502                 :          0 :                         continue;
    1503                 :            :                 }
    1504                 :            : 
    1505                 :            :                 /* All other arguments are included in the hash. */
    1506                 :          0 :                 hash_delimiter(hash, "arg");
    1507                 :          0 :                 hash_string(hash, args->argv[i]);
    1508                 :            :         }
    1509                 :            : 
    1510                 :            :         /*
    1511                 :            :          * For profile generation (-fprofile-arcs, -fprofile-generate):
    1512                 :            :          * - hash profile directory
    1513                 :            :          * - output to the real file first
    1514                 :            :          *
    1515                 :            :          * For profile usage (-fprofile-use):
    1516                 :            :          * - hash profile data
    1517                 :            :          *
    1518                 :            :          * -fbranch-probabilities and -fvpt usage is covered by
    1519                 :            :          * -fprofile-generate/-fprofile-use.
    1520                 :            :          *
    1521                 :            :          * The profile directory can be specified as an argument to
    1522                 :            :          * -fprofile-generate=, -fprofile-use=, or -fprofile-dir=.
    1523                 :            :          */
    1524                 :            : 
    1525                 :            :         /*
    1526                 :            :          * We need to output to the real object first here, otherwise runtime
    1527                 :            :          * artifacts will be produced in the wrong place.
    1528                 :            :          */
    1529         [ -  + ]:          1 :         if (profile_generate) {
    1530         [ #  # ]:          0 :                 if (!profile_dir) {
    1531                 :          0 :                         profile_dir = get_cwd();
    1532                 :            :                 }
    1533                 :          0 :                 cc_log("Adding profile directory %s to our hash", profile_dir);
    1534                 :          0 :                 hash_delimiter(hash, "-fprofile-dir");
    1535                 :          0 :                 hash_string(hash, profile_dir);
    1536                 :            :         }
    1537                 :            : 
    1538         [ -  + ]:          1 :         if (profile_use) {
    1539                 :            :                 /* Calculate gcda name */
    1540                 :            :                 char *gcda_name;
    1541                 :            :                 char *base_name;
    1542                 :          0 :                 base_name = remove_extension(output_obj);
    1543         [ #  # ]:          0 :                 if (!profile_dir) {
    1544                 :          0 :                         profile_dir = get_cwd();
    1545                 :            :                 }
    1546                 :          0 :                 gcda_name = format("%s/%s.gcda", profile_dir, base_name);
    1547                 :          0 :                 cc_log("Adding profile data %s to our hash", gcda_name);
    1548                 :            :                 /* Add the gcda to our hash */
    1549                 :          0 :                 hash_delimiter(hash, "-fprofile-use");
    1550                 :          0 :                 hash_file(hash, gcda_name);
    1551                 :          0 :                 free(base_name);
    1552                 :          0 :                 free(gcda_name);
    1553                 :            :         }
    1554                 :            : 
    1555         [ -  + ]:          1 :         if (direct_mode) {
    1556                 :            :                 /* Hash environment variables that affect the preprocessor output. */
    1557                 :            :                 const char **p;
    1558                 :            :                 const char *envvars[] = {
    1559                 :            :                         "CPATH",
    1560                 :            :                         "C_INCLUDE_PATH",
    1561                 :            :                         "CPLUS_INCLUDE_PATH",
    1562                 :            :                         "OBJC_INCLUDE_PATH",
    1563                 :            :                         "OBJCPLUS_INCLUDE_PATH", /* clang */
    1564                 :            :                         NULL
    1565                 :          0 :                 };
    1566         [ #  # ]:          0 :                 for (p = envvars; *p; ++p) {
    1567                 :          0 :                         char *v = getenv(*p);
    1568         [ #  # ]:          0 :                         if (v) {
    1569                 :          0 :                                 hash_delimiter(hash, *p);
    1570                 :          0 :                                 hash_string(hash, v);
    1571                 :            :                         }
    1572                 :            :                 }
    1573                 :            : 
    1574         [ #  # ]:          0 :                 if (!(conf->sloppiness & SLOPPY_FILE_MACRO)) {
    1575                 :            :                         /*
    1576                 :            :                          * The source code file or an include file may contain
    1577                 :            :                          * __FILE__, so make sure that the hash is unique for
    1578                 :            :                          * the file name.
    1579                 :            :                          */
    1580                 :          0 :                         hash_delimiter(hash, "inputfile");
    1581                 :          0 :                         hash_string(hash, input_file);
    1582                 :            :                 }
    1583                 :            : 
    1584                 :          0 :                 hash_delimiter(hash, "sourcecode");
    1585                 :          0 :                 result = hash_source_code_file(conf, hash, input_file);
    1586         [ #  # ]:          0 :                 if (result & HASH_SOURCE_CODE_ERROR) {
    1587                 :          0 :                         failed();
    1588                 :            :                 }
    1589         [ #  # ]:          0 :                 if (result & HASH_SOURCE_CODE_FOUND_TIME) {
    1590                 :          0 :                         cc_log("Disabling direct mode");
    1591                 :          0 :                         conf->direct_mode = false;
    1592                 :          0 :                         return NULL;
    1593                 :            :                 }
    1594                 :          0 :                 manifest_name = hash_result(hash);
    1595                 :          0 :                 manifest_path = get_path_in_cache(manifest_name, ".manifest");
    1596                 :          0 :                 free(manifest_name);
    1597                 :          0 :                 cc_log("Looking for object file hash in %s", manifest_path);
    1598                 :          0 :                 object_hash = manifest_get(conf, manifest_path);
    1599         [ #  # ]:          0 :                 if (object_hash) {
    1600                 :          0 :                         cc_log("Got object file hash from manifest");
    1601                 :            :                 } else {
    1602                 :          0 :                         cc_log("Did not find object file hash in manifest");
    1603                 :            :                 }
    1604                 :            :         } else {
    1605                 :          1 :                 object_hash = get_object_name_from_cpp(args, hash);
    1606                 :          1 :                 cc_log("Got object file hash from preprocessor");
    1607         [ -  + ]:          1 :                 if (generating_dependencies) {
    1608                 :          0 :                         cc_log("Preprocessor created %s", output_dep);
    1609                 :            :                 }
    1610                 :            :         }
    1611                 :            : 
    1612                 :          1 :         return object_hash;
    1613                 :            : }
    1614                 :            : 
    1615                 :            : /*
    1616                 :            :  * Try to return the compile result from cache. If we can return from cache
    1617                 :            :  * then this function exits with the correct status code, otherwise it returns.
    1618                 :            :  */
    1619                 :            : static void
    1620                 :          1 : from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
    1621                 :            : {
    1622                 :            :         struct stat st;
    1623                 :          1 :         bool produce_dep_file = false;
    1624                 :            : 
    1625                 :            :         /* the user might be disabling cache hits */
    1626         [ -  + ]:          1 :         if (conf->recache) {
    1627                 :          0 :                 return;
    1628                 :            :         }
    1629                 :            : 
    1630         [ +  - ]:          1 :         if (stat(cached_obj, &st) != 0) {
    1631                 :          1 :                 cc_log("Object file %s not in cache", cached_obj);
    1632                 :          1 :                 return;
    1633                 :            :         }
    1634                 :            : 
    1635                 :            :         /* Check if the diagnostic file is there. */
    1636 [ #  # ][ #  # ]:          0 :         if (output_dia && stat(cached_dia, &st) != 0) {
    1637                 :          0 :                 cc_log("Diagnostic file %s not in cache", cached_dia);
    1638                 :          0 :                 return;
    1639                 :            :         }
    1640                 :            : 
    1641                 :            :         /*
    1642                 :            :          * Occasionally, e.g. on hard reset, our cache ends up as just filesystem
    1643                 :            :          * meta-data with no content. Catch an easy case of this.
    1644                 :            :          */
    1645         [ #  # ]:          0 :         if (st.st_size == 0) {
    1646                 :          0 :                 cc_log("Invalid (empty) object file %s in cache", cached_obj);
    1647                 :          0 :                 x_unlink(cached_obj);
    1648                 :          0 :                 return;
    1649                 :            :         }
    1650                 :            : 
    1651 [ #  # ][ #  # ]:          0 :         if (using_split_dwarf && !generating_dependencies) {
    1652         [ #  # ]:          0 :                 assert(output_dwo);
    1653                 :            :         }
    1654         [ #  # ]:          0 :         if (output_dwo) {
    1655         [ #  # ]:          0 :                 assert(cached_dwo);
    1656         [ #  # ]:          0 :                 if (stat(cached_dwo, &st) != 0) {
    1657                 :          0 :                         cc_log("Split dwarf file %s not in cache", cached_dwo);
    1658                 :          0 :                         return;
    1659                 :            :                 }
    1660         [ #  # ]:          0 :                 if (st.st_size == 0) {
    1661                 :          0 :                         cc_log("Invalid (empty) dwo file %s in cache", cached_dwo);
    1662                 :          0 :                         x_unlink(cached_dwo);
    1663                 :          0 :                         x_unlink(cached_obj); /* to really invalidate */
    1664                 :          0 :                         return;
    1665                 :            :                 }
    1666                 :            :         }
    1667                 :            : 
    1668                 :            :         /*
    1669                 :            :          * (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by
    1670                 :            :          * gcc.)
    1671                 :            :          */
    1672 [ #  # ][ #  # ]:          0 :         produce_dep_file = generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
    1673                 :            : 
    1674                 :            :         /* If the dependency file should be in the cache, check that it is. */
    1675 [ #  # ][ #  # ]:          0 :         if (produce_dep_file && stat(cached_dep, &st) != 0) {
    1676                 :          0 :                 cc_log("Dependency file %s missing in cache", cached_dep);
    1677                 :          0 :                 return;
    1678                 :            :         }
    1679                 :            : 
    1680                 :            :         /*
    1681                 :            :          * Copy object file from cache. Do so also for FissionDwarf file, cached_dwo,
    1682                 :            :          * when -gsplit-dwarf is specified.
    1683                 :            :          */
    1684         [ #  # ]:          0 :         if (!str_eq(output_obj, "/dev/null")) {
    1685                 :          0 :                 get_file_from_cache(cached_obj, output_obj);
    1686         [ #  # ]:          0 :                 if (using_split_dwarf) {
    1687         [ #  # ]:          0 :                         assert(output_dwo);
    1688                 :          0 :                         get_file_from_cache(cached_dwo, output_dwo);
    1689                 :            :                 }
    1690                 :            :         }
    1691         [ #  # ]:          0 :         if (produce_dep_file) {
    1692                 :          0 :                 get_file_from_cache(cached_dep, output_dep);
    1693                 :            :         }
    1694 [ #  # ][ #  # ]:          0 :         if (generating_coverage && stat(cached_cov, &st) == 0 && st.st_size > 0) {
                 [ #  # ]
    1695                 :            :                 /* gcc won't generate notes if there is no code */
    1696                 :          0 :                 get_file_from_cache(cached_cov, output_cov);
    1697                 :            :         }
    1698         [ #  # ]:          0 :         if (output_dia) {
    1699                 :          0 :                 get_file_from_cache(cached_dia, output_dia);
    1700                 :            :         }
    1701                 :            : 
    1702                 :            :         /* Update modification timestamps to save files from LRU cleanup.
    1703                 :            :            Also gives files a sensible mtime when hard-linking. */
    1704                 :          0 :         update_mtime(cached_obj);
    1705                 :          0 :         update_mtime(cached_stderr);
    1706         [ #  # ]:          0 :         if (produce_dep_file) {
    1707                 :          0 :                 update_mtime(cached_dep);
    1708                 :            :         }
    1709         [ #  # ]:          0 :         if (generating_coverage) {
    1710                 :          0 :                 update_mtime(cached_cov);
    1711                 :            :         }
    1712         [ #  # ]:          0 :         if (output_dia) {
    1713                 :          0 :                 update_mtime(cached_dia);
    1714                 :            :         }
    1715         [ #  # ]:          0 :         if (cached_dwo) {
    1716                 :          0 :                 update_mtime(cached_dwo);
    1717                 :            :         }
    1718                 :            : 
    1719 [ #  # ][ #  # ]:          0 :         if (generating_dependencies && mode == FROMCACHE_CPP_MODE) {
    1720                 :          0 :                 put_file_in_cache(output_dep, cached_dep);
    1721                 :            :         }
    1722                 :            : 
    1723                 :          0 :         send_cached_stderr();
    1724                 :            : 
    1725         [ #  # ]:          0 :         if (put_object_in_manifest) {
    1726                 :          0 :                 update_manifest_file();
    1727                 :            :         }
    1728                 :            : 
    1729                 :            :         /* log the cache hit */
    1730      [ #  #  # ]:          0 :         switch (mode) {
    1731                 :            :         case FROMCACHE_DIRECT_MODE:
    1732                 :          0 :                 cc_log("Succeeded getting cached result");
    1733                 :          0 :                 stats_update(STATS_CACHEHIT_DIR);
    1734                 :          0 :                 break;
    1735                 :            : 
    1736                 :            :         case FROMCACHE_CPP_MODE:
    1737                 :          0 :                 cc_log("Succeeded getting cached result");
    1738                 :          0 :                 stats_update(STATS_CACHEHIT_CPP);
    1739                 :            :                 break;
    1740                 :            :         }
    1741                 :            : 
    1742                 :            :         /* and exit with the right status code */
    1743                 :          0 :         x_exit(0);
    1744                 :            : }
    1745                 :            : 
    1746                 :            : /* find the real compiler. We just search the PATH to find a executable of the
    1747                 :            :    same name that isn't a link to ourselves */
    1748                 :            : static void
    1749                 :          1 : find_compiler(char **argv)
    1750                 :            : {
    1751                 :            :         char *base;
    1752                 :            :         char *compiler;
    1753                 :            : 
    1754                 :          1 :         base = basename(argv[0]);
    1755                 :            : 
    1756                 :            :         /* we might be being invoked like "ccache gcc -c foo.c" */
    1757         [ +  - ]:          1 :         if (same_executable_name(base, MYNAME)) {
    1758                 :          1 :                 args_remove_first(orig_args);
    1759                 :          1 :                 free(base);
    1760         [ -  + ]:          1 :                 if (is_full_path(orig_args->argv[0])) {
    1761                 :            :                         /* a full path was given */
    1762                 :          0 :                         return;
    1763                 :            :                 }
    1764                 :          1 :                 base = basename(orig_args->argv[0]);
    1765                 :            :         }
    1766                 :            : 
    1767                 :            :         /* support user override of the compiler */
    1768         [ -  + ]:          1 :         if (!str_eq(conf->compiler, "")) {
    1769                 :          0 :                 base = conf->compiler;
    1770                 :            :         }
    1771                 :            : 
    1772                 :          1 :         compiler = find_executable(base, MYNAME);
    1773                 :            : 
    1774                 :            :         /* can't find the compiler! */
    1775         [ -  + ]:          1 :         if (!compiler) {
    1776                 :          0 :                 stats_update(STATS_COMPILER);
    1777                 :          0 :                 fatal("Could not find compiler \"%s\" in PATH", base);
    1778                 :            :         }
    1779         [ -  + ]:          1 :         if (str_eq(compiler, argv[0])) {
    1780                 :          0 :                 fatal("Recursive invocation (the name of the ccache binary must be \"%s\")",
    1781                 :            :                       MYNAME);
    1782                 :            :         }
    1783                 :          1 :         orig_args->argv[0] = compiler;
    1784                 :            : }
    1785                 :            : 
    1786                 :            : bool
    1787                 :          0 : is_precompiled_header(const char *path)
    1788                 :            : {
    1789   [ #  #  #  #  :          0 :         return str_eq(get_extension(path), ".gch")
                   #  # ]
    1790                 :          0 :                || str_eq(get_extension(path), ".pch")
    1791                 :          0 :                || str_eq(get_extension(path), ".pth");
    1792                 :            : }
    1793                 :            : 
    1794                 :            : static bool
    1795                 :         14 : color_output_possible(void)
    1796                 :            : {
    1797                 :         14 :         const char *term_env = getenv("TERM");
    1798 [ -  + ][ #  # ]:         14 :         return isatty(STDERR_FILENO) && term_env && strcasecmp(term_env, "DUMB") != 0;
                 [ #  # ]
    1799                 :            : }
    1800                 :            : 
    1801                 :            : /*
    1802                 :            :  * Process the compiler options into options suitable for passing to the
    1803                 :            :  * preprocessor and the real compiler. The preprocessor options don't include
    1804                 :            :  * -E; this is added later. Returns true on success, otherwise false.
    1805                 :            :  */
    1806                 :            : bool
    1807                 :         16 : cc_process_args(struct args *args, struct args **preprocessor_args,
    1808                 :            :                 struct args **compiler_args)
    1809                 :            : {
    1810                 :            :         int i;
    1811                 :         16 :         bool found_c_opt = false;
    1812                 :         16 :         bool found_S_opt = false;
    1813                 :         16 :         bool found_arch_opt = false;
    1814                 :         16 :         bool found_pch = false;
    1815                 :         16 :         bool found_fpch_preprocess = false;
    1816                 :         16 :         const char *explicit_language = NULL; /* As specified with -x. */
    1817                 :            :         const char *file_language;            /* As deduced from file extension. */
    1818                 :            :         const char *actual_language;          /* Language to actually use. */
    1819                 :         16 :         const char *input_charset = NULL;
    1820                 :            :         struct stat st;
    1821                 :            :         /* is the dependency makefile name overridden with -MF? */
    1822                 :         16 :         bool dependency_filename_specified = false;
    1823                 :            :         /* is the dependency makefile target name specified with -MT or -MQ? */
    1824                 :         16 :         bool dependency_target_specified = false;
    1825                 :            :         struct args *expanded_args, *stripped_args, *dep_args, *cpp_args;
    1826                 :            :         int argc;
    1827                 :            :         char **argv;
    1828                 :         16 :         bool result = true;
    1829                 :         16 :         bool found_color_diagnostics = false;
    1830                 :            : 
    1831                 :         16 :         expanded_args = args_copy(args);
    1832                 :         16 :         stripped_args = args_init(0, NULL);
    1833                 :         16 :         dep_args = args_init(0, NULL);
    1834                 :         16 :         cpp_args = args_init(0, NULL);
    1835                 :            : 
    1836                 :         16 :         argc = expanded_args->argc;
    1837                 :         16 :         argv = expanded_args->argv;
    1838                 :            : 
    1839                 :         16 :         args_add(stripped_args, argv[0]);
    1840                 :            : 
    1841         [ +  + ]:        128 :         for (i = 1; i < argc; i++) {
    1842                 :            :                 /* The user knows best: just swallow the next arg */
    1843         [ -  + ]:        114 :                 if (str_eq(argv[i], "--ccache-skip")) {
    1844                 :          0 :                         i++;
    1845         [ #  # ]:          0 :                         if (i == argc) {
    1846                 :          0 :                                 cc_log("--ccache-skip lacks an argument");
    1847                 :          0 :                                 result = false;
    1848                 :          0 :                                 goto out;
    1849                 :            :                         }
    1850                 :          0 :                         args_add(stripped_args, argv[i]);
    1851                 :          0 :                         continue;
    1852                 :            :                 }
    1853                 :            : 
    1854                 :            :                 /* Special case for -E. */
    1855         [ +  + ]:        114 :                 if (str_eq(argv[i], "-E")) {
    1856                 :          1 :                         stats_update(STATS_PREPROCESSING);
    1857                 :          1 :                         result = false;
    1858                 :          1 :                         goto out;
    1859                 :            :                 }
    1860                 :            : 
    1861                 :            :                 /* Handle "@file" argument. */
    1862 [ +  - ][ -  + ]:        113 :                 if (str_startswith(argv[i], "@") || str_startswith(argv[i], "-@")) {
    1863                 :          0 :                         char *argpath = argv[i] + 1;
    1864                 :            :                         struct args *file_args;
    1865                 :            : 
    1866         [ #  # ]:          0 :                         if (argpath[-1] == '-') {
    1867                 :          0 :                                 ++argpath;
    1868                 :            :                         }
    1869                 :          0 :                         file_args = args_init_from_gcc_atfile(argpath);
    1870         [ #  # ]:          0 :                         if (!file_args) {
    1871                 :          0 :                                 cc_log("Couldn't read arg file %s", argpath);
    1872                 :          0 :                                 stats_update(STATS_ARGS);
    1873                 :          0 :                                 result = false;
    1874                 :          0 :                                 goto out;
    1875                 :            :                         }
    1876                 :            : 
    1877                 :          0 :                         args_insert(expanded_args, i, file_args, true);
    1878                 :          0 :                         argc = expanded_args->argc;
    1879                 :          0 :                         argv = expanded_args->argv;
    1880                 :          0 :                         i--;
    1881                 :          0 :                         continue;
    1882                 :            :                 }
    1883                 :            : 
    1884                 :            :                 /* These are always too hard. */
    1885 [ +  + ][ -  + ]:        113 :                 if (compopt_too_hard(argv[i])
    1886                 :        112 :                     || str_startswith(argv[i], "-fdump-")) {
    1887                 :          1 :                         cc_log("Compiler option %s is unsupported", argv[i]);
    1888                 :          1 :                         stats_update(STATS_UNSUPPORTED);
    1889                 :          1 :                         result = false;
    1890                 :          1 :                         goto out;
    1891                 :            :                 }
    1892                 :            : 
    1893                 :            :                 /* These are too hard in direct mode. */
    1894         [ +  + ]:        112 :                 if (conf->direct_mode) {
    1895         [ -  + ]:        110 :                         if (compopt_too_hard_for_direct_mode(argv[i])) {
    1896                 :          0 :                                 cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
    1897                 :          0 :                                 conf->direct_mode = false;
    1898                 :            :                         }
    1899                 :            :                 }
    1900                 :            : 
    1901                 :            :                 /* Multiple -arch options are too hard. */
    1902         [ -  + ]:        112 :                 if (str_eq(argv[i], "-arch")) {
    1903         [ #  # ]:          0 :                         if (found_arch_opt) {
    1904                 :          0 :                                 cc_log("More than one -arch compiler option is unsupported");
    1905                 :          0 :                                 stats_update(STATS_UNSUPPORTED);
    1906                 :          0 :                                 result = false;
    1907                 :          0 :                                 goto out;
    1908                 :            :                         } else {
    1909                 :          0 :                                 found_arch_opt = true;
    1910                 :            :                         }
    1911                 :            :                 }
    1912                 :            : 
    1913 [ +  - ][ +  - ]:        112 :                 if (str_eq(argv[i], "-fpch-preprocess")
                 [ -  + ]
    1914                 :        112 :                     || str_eq(argv[i], "-emit-pch")
    1915                 :        112 :                     || str_eq(argv[i], "-emit-pth")) {
    1916                 :          0 :                         found_fpch_preprocess = true;
    1917                 :            :                 }
    1918                 :            : 
    1919                 :            :                 /* we must have -c */
    1920         [ +  + ]:        112 :                 if (str_eq(argv[i], "-c")) {
    1921                 :         16 :                         found_c_opt = true;
    1922                 :         16 :                         continue;
    1923                 :            :                 }
    1924                 :            : 
    1925                 :            :                 /* -S changes the default extension */
    1926         [ -  + ]:         96 :                 if (str_eq(argv[i], "-S")) {
    1927                 :          0 :                         args_add(stripped_args, argv[i]);
    1928                 :          0 :                         found_S_opt = true;
    1929                 :          0 :                         continue;
    1930                 :            :                 }
    1931                 :            : 
    1932                 :            :                 /*
    1933                 :            :                  * Special handling for -x: remember the last specified language before the
    1934                 :            :                  * input file and strip all -x options from the arguments.
    1935                 :            :                  */
    1936         [ -  + ]:         96 :                 if (str_eq(argv[i], "-x")) {
    1937         [ #  # ]:          0 :                         if (i == argc-1) {
    1938                 :          0 :                                 cc_log("Missing argument to %s", argv[i]);
    1939                 :          0 :                                 stats_update(STATS_ARGS);
    1940                 :          0 :                                 result = false;
    1941                 :          0 :                                 goto out;
    1942                 :            :                         }
    1943         [ #  # ]:          0 :                         if (!input_file) {
    1944                 :          0 :                                 explicit_language = argv[i+1];
    1945                 :            :                         }
    1946                 :          0 :                         i++;
    1947                 :          0 :                         continue;
    1948                 :            :                 }
    1949         [ -  + ]:         96 :                 if (str_startswith(argv[i], "-x")) {
    1950         [ #  # ]:          0 :                         if (!input_file) {
    1951                 :          0 :                                 explicit_language = &argv[i][2];
    1952                 :            :                         }
    1953                 :          0 :                         continue;
    1954                 :            :                 }
    1955                 :            : 
    1956                 :            :                 /* we need to work out where the output was meant to go */
    1957         [ +  + ]:         96 :                 if (str_eq(argv[i], "-o")) {
    1958         [ -  + ]:          6 :                         if (i == argc-1) {
    1959                 :          0 :                                 cc_log("Missing argument to %s", argv[i]);
    1960                 :          0 :                                 stats_update(STATS_ARGS);
    1961                 :          0 :                                 result = false;
    1962                 :          0 :                                 goto out;
    1963                 :            :                         }
    1964                 :          6 :                         output_obj = make_relative_path(x_strdup(argv[i+1]));
    1965                 :          6 :                         i++;
    1966                 :          6 :                         continue;
    1967                 :            :                 }
    1968                 :            : 
    1969                 :            :                 /* alternate form of -o, with no space */
    1970         [ -  + ]:         90 :                 if (str_startswith(argv[i], "-o")) {
    1971                 :          0 :                         output_obj = make_relative_path(x_strdup(&argv[i][2]));
    1972                 :          0 :                         continue;
    1973                 :            :                 }
    1974                 :            : 
    1975         [ -  + ]:         90 :                 if (str_eq(argv[i], "-gsplit-dwarf")) {
    1976                 :          0 :                         cc_log("Enabling caching of dwarf files since -gsplit-dwarf is used");
    1977                 :          0 :                         using_split_dwarf = true;
    1978                 :          0 :                         args_add(stripped_args, argv[i]);
    1979                 :          0 :                         continue;
    1980                 :            :                 }
    1981                 :            : 
    1982                 :            :                 /* debugging is handled specially, so that we know if we
    1983                 :            :                    can strip line number info
    1984                 :            :                 */
    1985         [ -  + ]:         90 :                 if (str_startswith(argv[i], "-g")) {
    1986                 :          0 :                         args_add(stripped_args, argv[i]);
    1987 [ #  # ][ #  # ]:          0 :                         if (conf->unify && !str_eq(argv[i], "-g0")) {
    1988                 :          0 :                                 cc_log("%s used; disabling unify mode", argv[i]);
    1989                 :          0 :                                 conf->unify = false;
    1990                 :            :                         }
    1991         [ #  # ]:          0 :                         if (str_eq(argv[i], "-g3")) {
    1992                 :            :                                 /*
    1993                 :            :                                  * Fix for bug 7190 ("commandline macros (-D)
    1994                 :            :                                  * have non-zero lineno when using -g3").
    1995                 :            :                                  */
    1996                 :          0 :                                 cc_log("%s used; not compiling preprocessed code", argv[i]);
    1997                 :          0 :                                 conf->run_second_cpp = true;
    1998                 :            :                         }
    1999                 :          0 :                         continue;
    2000                 :            :                 }
    2001                 :            : 
    2002                 :            :                 /* These options require special handling, because they
    2003                 :            :                    behave differently with gcc -E, when the output
    2004                 :            :                    file is not specified. */
    2005 [ +  + ][ +  + ]:         90 :                 if (str_eq(argv[i], "-MD") || str_eq(argv[i], "-MMD")) {
    2006                 :         12 :                         generating_dependencies = true;
    2007                 :         12 :                         args_add(dep_args, argv[i]);
    2008                 :         12 :                         continue;
    2009                 :            :                 }
    2010         [ +  + ]:         78 :                 if (str_startswith(argv[i], "-MF")) {
    2011                 :            :                         char *arg;
    2012                 :         10 :                         bool separate_argument = (strlen(argv[i]) == 3);
    2013                 :         10 :                         dependency_filename_specified = true;
    2014                 :         10 :                         free(output_dep);
    2015         [ +  + ]:         10 :                         if (separate_argument) {
    2016                 :            :                                 /* -MF arg */
    2017         [ -  + ]:          2 :                                 if (i >= argc - 1) {
    2018                 :          0 :                                         cc_log("Missing argument to %s", argv[i]);
    2019                 :          0 :                                         stats_update(STATS_ARGS);
    2020                 :          0 :                                         result = false;
    2021                 :          0 :                                         goto out;
    2022                 :            :                                 }
    2023                 :          2 :                                 arg = argv[i + 1];
    2024                 :          2 :                                 i++;
    2025                 :            :                         } else {
    2026                 :            :                                 /* -MFarg */
    2027                 :          8 :                                 arg = &argv[i][3];
    2028                 :            :                         }
    2029                 :         10 :                         output_dep = make_relative_path(x_strdup(arg));
    2030                 :            :                         /* Keep the format of the args the same */
    2031         [ +  + ]:         10 :                         if (separate_argument) {
    2032                 :          2 :                                 args_add(dep_args, "-MF");
    2033                 :          2 :                                 args_add(dep_args, output_dep);
    2034                 :            :                         } else {
    2035                 :          8 :                                 char *option = format("-MF%s", output_dep);
    2036                 :          8 :                                 args_add(dep_args, option);
    2037                 :          8 :                                 free(option);
    2038                 :            :                         }
    2039                 :         10 :                         continue;
    2040                 :            :                 }
    2041 [ +  + ][ +  + ]:         68 :                 if (str_startswith(argv[i], "-MQ") || str_startswith(argv[i], "-MT")) {
    2042                 :            :                         char *relpath;
    2043                 :         20 :                         dependency_target_specified = true;
    2044         [ +  + ]:         20 :                         if (strlen(argv[i]) == 3) {
    2045                 :            :                                 /* -MQ arg or -MT arg */
    2046         [ -  + ]:         14 :                                 if (i >= argc - 1) {
    2047                 :          0 :                                         cc_log("Missing argument to %s", argv[i]);
    2048                 :          0 :                                         stats_update(STATS_ARGS);
    2049                 :          0 :                                         result = false;
    2050                 :          0 :                                         goto out;
    2051                 :            :                                 }
    2052                 :         14 :                                 args_add(dep_args, argv[i]);
    2053                 :         14 :                                 relpath = make_relative_path(x_strdup(argv[i + 1]));
    2054                 :         14 :                                 args_add(dep_args, relpath);
    2055                 :         14 :                                 free(relpath);
    2056                 :         14 :                                 i++;
    2057                 :            :                         } else {
    2058                 :            :                                 char *arg_opt;
    2059                 :            :                                 char *option;
    2060                 :          6 :                                 arg_opt = x_strndup(argv[i], 3);
    2061                 :          6 :                                 relpath = make_relative_path(x_strdup(argv[i] + 3));
    2062                 :          6 :                                 option = format("%s%s", arg_opt, relpath);
    2063                 :          6 :                                 args_add(dep_args, option);
    2064                 :          6 :                                 free(arg_opt);
    2065                 :          6 :                                 free(relpath);
    2066                 :          6 :                                 free(option);
    2067                 :            :                         }
    2068                 :         20 :                         continue;
    2069                 :            :                 }
    2070         [ -  + ]:         48 :                 if (str_eq(argv[i], "-fprofile-arcs")) {
    2071                 :          0 :                         profile_arcs = true;
    2072                 :          0 :                         args_add(stripped_args, argv[i]);
    2073                 :          0 :                         continue;
    2074                 :            :                 }
    2075         [ -  + ]:         48 :                 if (str_eq(argv[i], "-ftest-coverage")) {
    2076                 :          0 :                         generating_coverage = true;
    2077                 :          0 :                         args_add(stripped_args, argv[i]);
    2078                 :          0 :                         continue;
    2079                 :            :                 }
    2080         [ -  + ]:         48 :                 if (str_eq(argv[i], "--coverage")) { /* = -fprofile-arcs -ftest-coverage */
    2081                 :          0 :                         profile_arcs = true;
    2082                 :          0 :                         generating_coverage = true;
    2083                 :          0 :                         args_add(stripped_args, argv[i]);
    2084                 :          0 :                         continue;
    2085                 :            :                 }
    2086         [ -  + ]:         48 :                 if (str_startswith(argv[i], "-fprofile-dir=")) {
    2087                 :          0 :                         profile_dir = x_strdup(argv[i] + 14);
    2088                 :          0 :                         args_add(stripped_args, argv[i]);
    2089                 :          0 :                         continue;
    2090                 :            :                 }
    2091         [ +  + ]:         48 :                 if (str_startswith(argv[i], "--sysroot=")) {
    2092                 :          1 :                         char *relpath = make_relative_path(x_strdup(argv[i] + 10));
    2093                 :          1 :                         char *option = format("--sysroot=%s", relpath);
    2094                 :          1 :                         args_add(stripped_args, option);
    2095                 :          1 :                         free(relpath);
    2096                 :          1 :                         free(option);
    2097                 :          1 :                         continue;
    2098                 :            :                 }
    2099         [ +  + ]:         47 :                 if (str_startswith(argv[i], "-Wp,")) {
    2100 [ +  - ][ -  + ]:          4 :                         if (str_eq(argv[i], "-Wp,-P") || strstr(argv[i], ",-P,")) {
    2101                 :            :                                 /* -P removes preprocessor information in such a way that the object
    2102                 :            :                                  * file from compiling the preprocessed file will not be equal to the
    2103                 :            :                                  * object file produced when compiling without ccache. */
    2104                 :          0 :                                 cc_log("Too hard option -Wp,-P detected");
    2105                 :          0 :                                 stats_update(STATS_UNSUPPORTED);
    2106                 :          0 :                                 failed();
    2107 [ +  + ][ +  - ]:          4 :                         } else if (str_startswith(argv[i], "-Wp,-MD,")
    2108                 :          2 :                                    && !strchr(argv[i] + 8, ',')) {
    2109                 :          2 :                                 generating_dependencies = true;
    2110                 :          2 :                                 dependency_filename_specified = true;
    2111                 :          2 :                                 free(output_dep);
    2112                 :          2 :                                 output_dep = make_relative_path(x_strdup(argv[i] + 8));
    2113                 :          2 :                                 args_add(dep_args, argv[i]);
    2114                 :          2 :                                 continue;
    2115 [ +  - ][ +  - ]:          2 :                         } else if (str_startswith(argv[i], "-Wp,-MMD,")
    2116                 :          2 :                                    && !strchr(argv[i] + 9, ',')) {
    2117                 :          2 :                                 generating_dependencies = true;
    2118                 :          2 :                                 dependency_filename_specified = true;
    2119                 :          2 :                                 free(output_dep);
    2120                 :          2 :                                 output_dep = make_relative_path(x_strdup(argv[i] + 9));
    2121                 :          2 :                                 args_add(dep_args, argv[i]);
    2122                 :          2 :                                 continue;
    2123         [ #  # ]:          0 :                         } else if (conf->direct_mode) {
    2124                 :            :                                 /*
    2125                 :            :                                  * -Wp, can be used to pass too hard options to
    2126                 :            :                                  * the preprocessor. Hence, disable direct
    2127                 :            :                                  * mode.
    2128                 :            :                                  */
    2129                 :          0 :                                 cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
    2130                 :          0 :                                 conf->direct_mode = false;
    2131                 :            :                         }
    2132                 :            :                 }
    2133         [ +  + ]:         43 :                 if (str_eq(argv[i], "-MP")) {
    2134                 :          6 :                         args_add(dep_args, argv[i]);
    2135                 :          6 :                         continue;
    2136                 :            :                 }
    2137                 :            : 
    2138                 :            :                 /* Input charset needs to be handled specially. */
    2139         [ -  + ]:         37 :                 if (str_startswith(argv[i], "-finput-charset=")) {
    2140                 :          0 :                         input_charset = argv[i];
    2141                 :          0 :                         continue;
    2142                 :            :                 }
    2143                 :            : 
    2144         [ -  + ]:         37 :                 if (str_eq(argv[i], "--serialize-diagnostics")) {
    2145         [ #  # ]:          0 :                         if (i >= argc - 1) {
    2146                 :          0 :                                 cc_log("Missing argument to %s", argv[i]);
    2147                 :          0 :                                 stats_update(STATS_ARGS);
    2148                 :          0 :                                 result = false;
    2149                 :          0 :                                 goto out;
    2150                 :            :                         }
    2151                 :          0 :                         output_dia = make_relative_path(x_strdup(argv[i+1]));
    2152                 :          0 :                         i++;
    2153                 :          0 :                         continue;
    2154                 :            :                 }
    2155                 :            : 
    2156         [ +  + ]:         37 :                 if (str_startswith(argv[i], "-fprofile-")) {
    2157                 :          2 :                         const char *arg_profile_dir = strchr(argv[i], '=');
    2158                 :          2 :                         char *arg = x_strdup(argv[i]);
    2159                 :          2 :                         bool supported_profile_option = false;
    2160                 :            : 
    2161         [ +  - ]:          2 :                         if (arg_profile_dir) {
    2162                 :          2 :                                 char *option = x_strndup(argv[i], arg_profile_dir - argv[i]);
    2163                 :            :                                 char *dir;
    2164                 :            : 
    2165                 :            :                                 /* Convert to absolute path. */
    2166                 :          2 :                                 dir = x_realpath(arg_profile_dir + 1);
    2167         [ +  + ]:          2 :                                 if (!dir) {
    2168                 :            :                                         /* Directory doesn't exist. */
    2169                 :          1 :                                         dir = x_strdup(arg_profile_dir + 1);
    2170                 :            :                                 }
    2171                 :            : 
    2172                 :            :                                 /* We can get a better hit rate by using the real path here. */
    2173                 :          2 :                                 free(arg);
    2174                 :          2 :                                 arg = format("%s=%s", option, dir);
    2175                 :          2 :                                 cc_log("Rewriting %s to %s", argv[i], arg);
    2176                 :          2 :                                 free(option);
    2177                 :          2 :                                 free(dir);
    2178                 :            :                         }
    2179                 :            : 
    2180 [ -  + ][ #  # ]:          2 :                         if (str_startswith(argv[i], "-fprofile-generate")
    2181                 :          0 :                             || str_eq(argv[i], "-fprofile-arcs")) {
    2182                 :          2 :                                 profile_generate = true;
    2183                 :          2 :                                 supported_profile_option = true;
    2184 [ #  # ][ #  # ]:          0 :                         } else if (str_startswith(argv[i], "-fprofile-use")
    2185                 :          0 :                                    || str_eq(argv[i], "-fbranch-probabilities")) {
    2186                 :          0 :                                 profile_use = true;
    2187                 :          0 :                                 supported_profile_option = true;
    2188         [ #  # ]:          0 :                         } else if (str_eq(argv[i], "-fprofile-dir")) {
    2189                 :          0 :                                 supported_profile_option = true;
    2190                 :            :                         }
    2191                 :            : 
    2192         [ +  - ]:          2 :                         if (supported_profile_option) {
    2193                 :          2 :                                 args_add(stripped_args, arg);
    2194                 :          2 :                                 free(arg);
    2195                 :            : 
    2196                 :            :                                 /*
    2197                 :            :                                  * If the profile directory has already been set, give up... Hard to
    2198                 :            :                                  * know what the user means, and what the compiler will do.
    2199                 :            :                                  */
    2200 [ +  - ][ -  + ]:          2 :                                 if (arg_profile_dir && profile_dir) {
    2201                 :          0 :                                         cc_log("Profile directory already set; giving up");
    2202                 :          0 :                                         result = false;
    2203                 :          0 :                                         goto out;
    2204         [ +  - ]:          2 :                                 } else if (arg_profile_dir) {
    2205                 :          2 :                                         cc_log("Setting profile directory to %s", profile_dir);
    2206                 :          2 :                                         profile_dir = x_strdup(arg_profile_dir);
    2207                 :            :                                 }
    2208                 :          2 :                                 continue;
    2209                 :            :                         }
    2210                 :          0 :                         cc_log("Unknown profile option: %s", argv[i]);
    2211                 :          0 :                         free(arg);
    2212                 :            :                 }
    2213                 :            : 
    2214 [ +  - ][ +  - ]:         35 :                 if (str_eq(argv[i], "-fcolor-diagnostics")
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
    2215                 :         35 :                     || str_eq(argv[i], "-fno-color-diagnostics")
    2216                 :         35 :                     || str_eq(argv[i], "-fdiagnostics-color")
    2217                 :         35 :                     || str_eq(argv[i], "-fdiagnostics-color=always")
    2218                 :         35 :                     || str_eq(argv[i], "-fno-diagnostics-color")
    2219                 :         35 :                     || str_eq(argv[i], "-fdiagnostics-color=never")) {
    2220                 :          0 :                         args_add(stripped_args, argv[i]);
    2221                 :          0 :                         found_color_diagnostics = true;
    2222                 :          0 :                         continue;
    2223                 :            :                 }
    2224         [ -  + ]:         35 :                 if (str_eq(argv[i], "-fdiagnostics-color=auto")) {
    2225         [ #  # ]:          0 :                         if (color_output_possible()) {
    2226                 :            :                                 /* Output is redirected, so color output must be forced. */
    2227                 :          0 :                                 args_add(stripped_args, "-fdiagnostics-color=always");
    2228                 :          0 :                                 cc_log("Automatically forcing colors");
    2229                 :            :                         } else {
    2230                 :          0 :                                 args_add(stripped_args, argv[i]);
    2231                 :            :                         }
    2232                 :          0 :                         found_color_diagnostics = true;
    2233                 :          0 :                         continue;
    2234                 :            :                 }
    2235                 :            : 
    2236                 :            :                 /*
    2237                 :            :                  * Options taking an argument that we may want to rewrite to relative paths
    2238                 :            :                  * to get better hit rate. A secondary effect is that paths in the standard
    2239                 :            :                  * error output produced by the compiler will be normalized.
    2240                 :            :                  */
    2241         [ +  + ]:         35 :                 if (compopt_takes_path(argv[i])) {
    2242                 :            :                         char *relpath;
    2243                 :         11 :                         char *pch_file = NULL;
    2244         [ -  + ]:         11 :                         if (i == argc-1) {
    2245                 :          0 :                                 cc_log("Missing argument to %s", argv[i]);
    2246                 :          0 :                                 stats_update(STATS_ARGS);
    2247                 :          0 :                                 result = false;
    2248                 :          0 :                                 goto out;
    2249                 :            :                         }
    2250                 :            : 
    2251                 :         11 :                         relpath = make_relative_path(x_strdup(argv[i+1]));
    2252         [ +  - ]:         11 :                         if (compopt_affects_cpp(argv[i])) {
    2253                 :         11 :                                 args_add(cpp_args, argv[i]);
    2254                 :         11 :                                 args_add(cpp_args, relpath);
    2255                 :            :                         } else {
    2256                 :          0 :                                 args_add(stripped_args, argv[i]);
    2257                 :          0 :                                 args_add(stripped_args, relpath);
    2258                 :            :                         }
    2259                 :            : 
    2260                 :            :                         /* Try to be smart about detecting precompiled headers */
    2261 [ +  + ][ -  + ]:         12 :                         if (str_eq(argv[i], "-include-pch")
    2262                 :         10 :                             || str_eq(argv[i], "-include-pth")) {
    2263         [ -  + ]:          1 :                                 if (stat(argv[i+1], &st) == 0) {
    2264                 :          0 :                                         cc_log("Detected use of precompiled header: %s", argv[i+1]);
    2265                 :          0 :                                         found_pch = true;
    2266                 :          0 :                                         pch_file = x_strdup(argv[i+1]);
    2267                 :            :                                 }
    2268                 :            :                         } else {
    2269                 :         10 :                                 char *gchpath = format("%s.gch", argv[i+1]);
    2270         [ -  + ]:         10 :                                 if (stat(gchpath, &st) == 0) {
    2271                 :          0 :                                         cc_log("Detected use of precompiled header: %s", gchpath);
    2272                 :          0 :                                         found_pch = true;
    2273                 :          0 :                                         pch_file = x_strdup(gchpath);
    2274                 :            :                                 } else {
    2275                 :         10 :                                         char *pchpath = format("%s.pch", argv[i+1]);
    2276         [ -  + ]:         10 :                                         if (stat(pchpath, &st) == 0) {
    2277                 :          0 :                                                 cc_log("Detected use of precompiled header: %s", pchpath);
    2278                 :          0 :                                                 found_pch = true;
    2279                 :          0 :                                                 pch_file = x_strdup(pchpath);
    2280                 :            :                                         } else {
    2281                 :            :                                                 /* clang may use pretokenized headers */
    2282                 :         10 :                                                 char *pthpath = format("%s.pth", argv[i+1]);
    2283         [ -  + ]:         10 :                                                 if (stat(pthpath, &st) == 0) {
    2284                 :          0 :                                                         cc_log("Detected use of pretokenized header: %s", pthpath);
    2285                 :          0 :                                                         found_pch = true;
    2286                 :          0 :                                                         pch_file = x_strdup(pthpath);
    2287                 :            :                                                 }
    2288                 :         10 :                                                 free(pthpath);
    2289                 :            :                                         }
    2290                 :         10 :                                         free(pchpath);
    2291                 :            :                                 }
    2292                 :         10 :                                 free(gchpath);
    2293                 :            :                         }
    2294                 :            : 
    2295         [ -  + ]:         11 :                         if (pch_file) {
    2296         [ #  # ]:          0 :                                 if (included_pch_file) {
    2297                 :          0 :                                         cc_log("Multiple precompiled headers used: %s and %s\n",
    2298                 :            :                                                included_pch_file, pch_file);
    2299                 :          0 :                                         stats_update(STATS_ARGS);
    2300                 :          0 :                                         result = false;
    2301                 :          0 :                                         goto out;
    2302                 :            :                                 }
    2303                 :          0 :                                 included_pch_file = pch_file;
    2304                 :            :                         }
    2305                 :            : 
    2306                 :         11 :                         free(relpath);
    2307                 :         11 :                         i++;
    2308                 :         11 :                         continue;
    2309                 :            :                 }
    2310                 :            : 
    2311                 :            :                 /* Same as above but options with concatenated argument. */
    2312         [ +  + ]:         24 :                 if (compopt_short(compopt_takes_path, argv[i])) {
    2313                 :            :                         char *relpath;
    2314                 :            :                         char *option;
    2315                 :          2 :                         relpath = make_relative_path(x_strdup(argv[i] + 2));
    2316                 :          2 :                         option = format("-%c%s", argv[i][1], relpath);
    2317                 :            : 
    2318         [ +  - ]:          2 :                         if (compopt_short(compopt_affects_cpp, argv[i])) {
    2319                 :          2 :                                 args_add(cpp_args, option);
    2320                 :            :                         } else {
    2321                 :          0 :                                 args_add(stripped_args, option);
    2322                 :            :                         }
    2323                 :            : 
    2324                 :          2 :                         free(relpath);
    2325                 :          2 :                         free(option);
    2326                 :          2 :                         continue;
    2327                 :            :                 }
    2328                 :            : 
    2329                 :            :                 /* options that take an argument */
    2330         [ -  + ]:         22 :                 if (compopt_takes_arg(argv[i])) {
    2331         [ #  # ]:          0 :                         if (i == argc-1) {
    2332                 :          0 :                                 cc_log("Missing argument to %s", argv[i]);
    2333                 :          0 :                                 stats_update(STATS_ARGS);
    2334                 :          0 :                                 result = false;
    2335                 :          0 :                                 goto out;
    2336                 :            :                         }
    2337                 :            : 
    2338         [ #  # ]:          0 :                         if (compopt_affects_cpp(argv[i])) {
    2339                 :          0 :                                 args_add(cpp_args, argv[i]);
    2340                 :          0 :                                 args_add(cpp_args, argv[i+1]);
    2341                 :            :                         } else {
    2342                 :          0 :                                 args_add(stripped_args, argv[i]);
    2343                 :          0 :                                 args_add(stripped_args, argv[i+1]);
    2344                 :            :                         }
    2345                 :            : 
    2346                 :          0 :                         i++;
    2347                 :          0 :                         continue;
    2348                 :            :                 }
    2349                 :            : 
    2350                 :            :                 /* other options */
    2351         [ +  + ]:         22 :                 if (argv[i][0] == '-') {
    2352 [ +  + ][ +  - ]:         12 :                         if (compopt_affects_cpp(argv[i])
    2353                 :          3 :                             || compopt_prefix_affects_cpp(argv[i])) {
    2354                 :          6 :                                 args_add(cpp_args, argv[i]);
    2355                 :            :                         } else {
    2356                 :          0 :                                 args_add(stripped_args, argv[i]);
    2357                 :            :                         }
    2358                 :          6 :                         continue;
    2359                 :            :                 }
    2360                 :            : 
    2361                 :            :                 /* if an argument isn't a plain file then assume its
    2362                 :            :                    an option, not an input file. This allows us to
    2363                 :            :                    cope better with unusual compiler options */
    2364 [ +  - ][ -  + ]:         16 :                 if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
    2365                 :          0 :                         cc_log("%s is not a regular file, not considering as input file",
    2366                 :          0 :                                argv[i]);
    2367                 :          0 :                         args_add(stripped_args, argv[i]);
    2368                 :          0 :                         continue;
    2369                 :            :                 }
    2370                 :            : 
    2371         [ -  + ]:         16 :                 if (input_file) {
    2372         [ #  # ]:          0 :                         if (language_for_file(argv[i])) {
    2373                 :          0 :                                 cc_log("Multiple input files: %s and %s", input_file, argv[i]);
    2374                 :          0 :                                 stats_update(STATS_MULTIPLE);
    2375         [ #  # ]:          0 :                         } else if (!found_c_opt) {
    2376                 :          0 :                                 cc_log("Called for link with %s", argv[i]);
    2377         [ #  # ]:          0 :                                 if (strstr(argv[i], "conftest.")) {
    2378                 :          0 :                                         stats_update(STATS_CONFTEST);
    2379                 :            :                                 } else {
    2380                 :          0 :                                         stats_update(STATS_LINK);
    2381                 :            :                                 }
    2382                 :            :                         } else {
    2383                 :          0 :                                 cc_log("Unsupported source extension: %s", argv[i]);
    2384                 :          0 :                                 stats_update(STATS_SOURCELANG);
    2385                 :            :                         }
    2386                 :          0 :                         result = false;
    2387                 :          0 :                         goto out;
    2388                 :            :                 }
    2389                 :            : 
    2390                 :            :                 /* The source code file path gets put into the notes */
    2391         [ -  + ]:         16 :                 if (generating_coverage) {
    2392                 :          0 :                         input_file = x_strdup(argv[i]);
    2393                 :          0 :                         continue;
    2394                 :            :                 }
    2395                 :            : 
    2396                 :            :                 /* Rewrite to relative to increase hit rate. */
    2397                 :         16 :                 input_file = make_relative_path(x_strdup(argv[i]));
    2398                 :            :         } /* for */
    2399                 :            : 
    2400         [ -  + ]:         14 :         if (found_S_opt) {
    2401                 :            :                 /* Even if -gsplit-dwarf is given, the .dwo file is not generated when -S
    2402                 :            :                  * is also given.
    2403                 :            :                  */
    2404                 :          0 :                 using_split_dwarf = false;
    2405                 :          0 :                 cc_log("Disabling caching of dwarf files since -S is used");
    2406                 :            :         }
    2407                 :            : 
    2408         [ -  + ]:         14 :         if (!input_file) {
    2409                 :          0 :                 cc_log("No input file found");
    2410                 :          0 :                 stats_update(STATS_NOINPUT);
    2411                 :          0 :                 result = false;
    2412                 :          0 :                 goto out;
    2413                 :            :         }
    2414                 :            : 
    2415 [ +  - ][ -  + ]:         14 :         if (found_pch || found_fpch_preprocess) {
    2416                 :          0 :                 using_precompiled_header = true;
    2417         [ #  # ]:          0 :                 if (!(conf->sloppiness & SLOPPY_TIME_MACROS)) {
    2418                 :          0 :                         cc_log("You have to specify \"time_macros\" sloppiness when using"
    2419                 :            :                                " precompiled headers to get direct hits");
    2420                 :          0 :                         cc_log("Disabling direct mode");
    2421                 :          0 :                         stats_update(STATS_CANTUSEPCH);
    2422                 :          0 :                         result = false;
    2423                 :          0 :                         goto out;
    2424                 :            :                 }
    2425                 :            :         }
    2426                 :            : 
    2427 [ -  + ][ #  # ]:         14 :         if (explicit_language && str_eq(explicit_language, "none")) {
    2428                 :          0 :                 explicit_language = NULL;
    2429                 :            :         }
    2430                 :         14 :         file_language = language_for_file(input_file);
    2431         [ -  + ]:         14 :         if (explicit_language) {
    2432         [ #  # ]:          0 :                 if (!language_is_supported(explicit_language)) {
    2433                 :          0 :                         cc_log("Unsupported language: %s", explicit_language);
    2434                 :          0 :                         stats_update(STATS_SOURCELANG);
    2435                 :          0 :                         result = false;
    2436                 :          0 :                         goto out;
    2437                 :            :                 }
    2438                 :          0 :                 actual_language = explicit_language;
    2439                 :            :         } else {
    2440                 :         14 :                 actual_language = file_language;
    2441                 :            :         }
    2442                 :            : 
    2443                 :         14 :         output_is_precompiled_header =
    2444 [ +  - ][ -  + ]:         14 :                 actual_language && strstr(actual_language, "-header");
    2445                 :            : 
    2446 [ -  + ][ #  # ]:         14 :         if (output_is_precompiled_header
    2447                 :          0 :             && !(conf->sloppiness & SLOPPY_PCH_DEFINES)) {
    2448                 :          0 :                 cc_log("You have to specify \"pch_defines,time_macros\" sloppiness when"
    2449                 :            :                        " creating precompiled headers");
    2450                 :          0 :                 stats_update(STATS_CANTUSEPCH);
    2451                 :          0 :                 result = false;
    2452                 :          0 :                 goto out;
    2453                 :            :         }
    2454                 :            : 
    2455         [ -  + ]:         14 :         if (!found_c_opt) {
    2456         [ #  # ]:          0 :                 if (output_is_precompiled_header) {
    2457                 :          0 :                         args_add(stripped_args, "-c");
    2458                 :            :                 } else {
    2459                 :          0 :                         cc_log("No -c option found");
    2460                 :            :                         /* I find that having a separate statistic for autoconf tests is useful,
    2461                 :            :                            as they are the dominant form of "called for link" in many cases */
    2462         [ #  # ]:          0 :                         if (strstr(input_file, "conftest.")) {
    2463                 :          0 :                                 stats_update(STATS_CONFTEST);
    2464                 :            :                         } else {
    2465                 :          0 :                                 stats_update(STATS_LINK);
    2466                 :            :                         }
    2467                 :          0 :                         result = false;
    2468                 :          0 :                         goto out;
    2469                 :            :                 }
    2470                 :            :         }
    2471                 :            : 
    2472         [ -  + ]:         14 :         if (!actual_language) {
    2473                 :          0 :                 cc_log("Unsupported source extension: %s", input_file);
    2474                 :          0 :                 stats_update(STATS_SOURCELANG);
    2475                 :          0 :                 result = false;
    2476                 :          0 :                 goto out;
    2477                 :            :         }
    2478                 :            : 
    2479                 :         14 :         direct_i_file = language_is_preprocessed(actual_language);
    2480                 :            : 
    2481         [ -  + ]:         14 :         if (output_is_precompiled_header) {
    2482                 :            :                 /* It doesn't work to create the .gch from preprocessed source. */
    2483                 :          0 :                 cc_log("Creating precompiled header; not compiling preprocessed code");
    2484                 :          0 :                 conf->run_second_cpp = true;
    2485                 :            :         }
    2486                 :            : 
    2487         [ +  - ]:         14 :         if (str_eq(conf->cpp_extension, "")) {
    2488                 :         14 :                 const char *p_language = p_language_for_language(actual_language);
    2489                 :         14 :                 free(conf->cpp_extension);
    2490                 :         14 :                 conf->cpp_extension = x_strdup(extension_for_language(p_language) + 1);
    2491                 :            :         }
    2492                 :            : 
    2493                 :            :         /* don't try to second guess the compilers heuristics for stdout handling */
    2494 [ +  + ][ -  + ]:         14 :         if (output_obj && str_eq(output_obj, "-")) {
    2495                 :          0 :                 stats_update(STATS_OUTSTDOUT);
    2496                 :          0 :                 cc_log("Output file is -");
    2497                 :          0 :                 result = false;
    2498                 :          0 :                 goto out;
    2499                 :            :         }
    2500                 :            : 
    2501         [ +  + ]:         14 :         if (!output_obj) {
    2502         [ -  + ]:          8 :                 if (output_is_precompiled_header) {
    2503                 :          0 :                         output_obj = format("%s.gch", input_file);
    2504                 :            :                 } else {
    2505                 :            :                         char *p;
    2506                 :          8 :                         output_obj = basename(input_file);
    2507                 :          8 :                         p = strrchr(output_obj, '.');
    2508 [ +  - ][ -  + ]:          8 :                         if (!p || !p[1]) {
    2509                 :          0 :                                 cc_log("Badly formed object filename");
    2510                 :          0 :                                 stats_update(STATS_ARGS);
    2511                 :          0 :                                 result = false;
    2512                 :          0 :                                 goto out;
    2513                 :            :                         }
    2514         [ -  + ]:          8 :                         p[1] = found_S_opt ? 's' : 'o';
    2515                 :          8 :                         p[2] = 0;
    2516                 :            :                 }
    2517                 :            :         }
    2518                 :            : 
    2519         [ -  + ]:         14 :         if (using_split_dwarf) {
    2520                 :            :                 char *p;
    2521                 :          0 :                 p = strrchr(output_obj, '.');
    2522 [ #  # ][ #  # ]:          0 :                 if (!p || !p[1]) {
    2523                 :          0 :                         cc_log("Badly formed object filename");
    2524                 :          0 :                         stats_update(STATS_ARGS);
    2525                 :          0 :                         result = false;
    2526                 :          0 :                         goto out;
    2527                 :            :                 }
    2528                 :            :                 {
    2529                 :          0 :                         char *base_name = remove_extension(output_obj);
    2530                 :          0 :                         output_dwo = format("%s.dwo", base_name);
    2531                 :          0 :                         free(base_name);
    2532                 :            :                 }
    2533                 :            :         }
    2534                 :            : 
    2535                 :            :         /* cope with -o /dev/null */
    2536   [ +  -  -  + ]:         28 :         if (!str_eq(output_obj,"/dev/null")
                 [ #  # ]
    2537                 :            :             && stat(output_obj, &st) == 0
    2538                 :         14 :             && !S_ISREG(st.st_mode)) {
    2539                 :          0 :                 cc_log("Not a regular file: %s", output_obj);
    2540                 :          0 :                 stats_update(STATS_DEVICE);
    2541                 :          0 :                 result = false;
    2542                 :          0 :                 goto out;
    2543                 :            :         }
    2544                 :            : 
    2545                 :            :         /*
    2546                 :            :          * Some options shouldn't be passed to the real compiler when it compiles
    2547                 :            :          * preprocessed code:
    2548                 :            :          *
    2549                 :            :          * -finput-charset=XXX (otherwise conversion happens twice)
    2550                 :            :          * -x XXX (otherwise the wrong language is selected)
    2551                 :            :          */
    2552         [ -  + ]:         14 :         if (input_charset) {
    2553                 :          0 :                 args_add(cpp_args, input_charset);
    2554                 :            :         }
    2555         [ -  + ]:         14 :         if (found_pch) {
    2556                 :          0 :                 args_add(cpp_args, "-fpch-preprocess");
    2557                 :            :         }
    2558         [ -  + ]:         14 :         if (explicit_language) {
    2559                 :          0 :                 args_add(cpp_args, "-x");
    2560                 :          0 :                 args_add(cpp_args, explicit_language);
    2561                 :            :         }
    2562                 :            : 
    2563                 :            :         /*
    2564                 :            :          * Since output is redirected, compilers will not color their output by
    2565                 :            :          * default, so force it explicitly if it would be otherwise done.
    2566                 :            :          */
    2567 [ +  - ][ -  + ]:         14 :         if (!found_color_diagnostics && color_output_possible()) {
    2568         [ #  # ]:          0 :                 if (compiler_is_clang(args)) {
    2569                 :          0 :                         args_add(stripped_args, "-fcolor-diagnostics");
    2570                 :          0 :                         cc_log("Automatically enabling colors");
    2571         [ #  # ]:          0 :                 } else if (compiler_is_gcc(args)) {
    2572                 :            :                         /*
    2573                 :            :                          * GCC has it since 4.9, but that'd require detecting what GCC version is
    2574                 :            :                          * used for the actual compile. However it requires also GCC_COLORS to be
    2575                 :            :                          * set (and not empty), so use that for detecting if GCC would use
    2576                 :            :                          * colors.
    2577                 :            :                          */
    2578 [ #  # ][ #  # ]:          0 :                         if (getenv("GCC_COLORS") && getenv("GCC_COLORS")[0] != '\0') {
    2579                 :          0 :                                 args_add(stripped_args, "-fdiagnostics-color");
    2580                 :          0 :                                 cc_log("Automatically enabling colors");
    2581                 :            :                         }
    2582                 :            :                 }
    2583                 :            :         }
    2584                 :            : 
    2585                 :            :         /*
    2586                 :            :          * Add flags for dependency generation only to the preprocessor command line.
    2587                 :            :          */
    2588         [ +  + ]:         14 :         if (generating_dependencies) {
    2589         [ -  + ]:         10 :                 if (!dependency_filename_specified) {
    2590                 :            :                         char *default_depfile_name;
    2591                 :            :                         char *base_name;
    2592                 :            : 
    2593                 :          0 :                         base_name = remove_extension(output_obj);
    2594                 :          0 :                         default_depfile_name = format("%s.d", base_name);
    2595                 :          0 :                         free(base_name);
    2596                 :          0 :                         args_add(dep_args, "-MF");
    2597                 :          0 :                         args_add(dep_args, default_depfile_name);
    2598                 :          0 :                         output_dep = make_relative_path(x_strdup(default_depfile_name));
    2599                 :            :                 }
    2600                 :            : 
    2601         [ -  + ]:         10 :                 if (!dependency_target_specified) {
    2602                 :          0 :                         args_add(dep_args, "-MQ");
    2603                 :          0 :                         args_add(dep_args, output_obj);
    2604                 :            :                 }
    2605                 :            :         }
    2606         [ -  + ]:         14 :         if (generating_coverage) {
    2607                 :            :                 char *default_covfile_name;
    2608                 :            :                 char *base_name;
    2609                 :            : 
    2610                 :          0 :                 base_name = remove_extension(output_obj);
    2611                 :          0 :                 default_covfile_name = format("%s.gcno", base_name);
    2612                 :          0 :                 free(base_name);
    2613                 :          0 :                 output_cov = make_relative_path(x_strdup(default_covfile_name));
    2614                 :            :         }
    2615                 :            : 
    2616                 :         14 :         *compiler_args = args_copy(stripped_args);
    2617         [ -  + ]:         14 :         if (conf->run_second_cpp) {
    2618                 :          0 :                 args_extend(*compiler_args, cpp_args);
    2619                 :            :         } else {
    2620         [ -  + ]:         14 :                 if (explicit_language) {
    2621                 :            :                         /*
    2622                 :            :                          * Workaround for a bug in Apple's patched distcc -- it doesn't properly
    2623                 :            :                          * reset the language specified with -x, so if -x is given, we have to
    2624                 :            :                          * specify the preprocessed language explicitly.
    2625                 :            :                          */
    2626                 :          0 :                         args_add(*compiler_args, "-x");
    2627                 :          0 :                         args_add(*compiler_args, p_language_for_language(explicit_language));
    2628                 :            :                 }
    2629                 :            :         }
    2630                 :            : 
    2631         [ +  - ]:         14 :         if (found_c_opt) {
    2632                 :         14 :                 args_add(*compiler_args, "-c");
    2633                 :            :         }
    2634                 :            : 
    2635                 :            :         /*
    2636                 :            :          * Only pass dependency arguments to the preprocesor since Intel's C++
    2637                 :            :          * compiler doesn't produce a correct .d file when compiling preprocessed
    2638                 :            :          * source.
    2639                 :            :          */
    2640                 :         14 :         args_extend(cpp_args, dep_args);
    2641                 :            : 
    2642                 :         14 :         *preprocessor_args = args_copy(stripped_args);
    2643                 :         14 :         args_extend(*preprocessor_args, cpp_args);
    2644                 :            : 
    2645                 :            : out:
    2646                 :         16 :         args_free(expanded_args);
    2647                 :         16 :         args_free(stripped_args);
    2648                 :         16 :         args_free(dep_args);
    2649                 :         16 :         args_free(cpp_args);
    2650                 :         16 :         return result;
    2651                 :            : }
    2652                 :            : 
    2653                 :            : static void
    2654                 :          0 : create_initial_config_file(struct conf *conf, const char *path)
    2655                 :            : {
    2656                 :            :         unsigned max_files;
    2657                 :            :         uint64_t max_size;
    2658                 :            :         char *stats_dir;
    2659                 :            :         FILE *f;
    2660                 :            :         struct stat st;
    2661                 :            : 
    2662         [ #  # ]:          0 :         if (create_parent_dirs(path) != 0) {
    2663                 :          0 :                 return;
    2664                 :            :         }
    2665                 :            : 
    2666                 :          0 :         stats_dir = format("%s/0", conf->cache_dir);
    2667         [ #  # ]:          0 :         if (stat(stats_dir, &st) == 0) {
    2668                 :          0 :                 stats_get_obsolete_limits(stats_dir, &max_files, &max_size);
    2669                 :            :                 /* STATS_MAXFILES and STATS_MAXSIZE was stored for each top directory. */
    2670                 :          0 :                 max_files *= 16;
    2671                 :          0 :                 max_size *= 16;
    2672                 :            :         } else {
    2673                 :          0 :                 max_files = 0;
    2674                 :          0 :                 max_size = conf->max_size;
    2675                 :            :         }
    2676                 :          0 :         free(stats_dir);
    2677                 :            : 
    2678                 :          0 :         f = fopen(path, "w");
    2679         [ #  # ]:          0 :         if (!f) {
    2680                 :          0 :                 return;
    2681                 :            :         }
    2682         [ #  # ]:          0 :         if (max_files != 0) {
    2683                 :          0 :                 fprintf(f, "max_files = %u\n", max_files);
    2684                 :          0 :                 conf->max_files = max_files;
    2685                 :            :         }
    2686         [ #  # ]:          0 :         if (max_size != 0) {
    2687                 :          0 :                 char *size = format_parsable_size_with_suffix(max_size);
    2688                 :          0 :                 fprintf(f, "max_size = %s\n", size);
    2689                 :          0 :                 free(size);
    2690                 :          0 :                 conf->max_size = max_size;
    2691                 :            :         }
    2692                 :          0 :         fclose(f);
    2693                 :            : }
    2694                 :            : 
    2695                 :            : /*
    2696                 :            :  * Read config file(s), populate variables, create configuration file in cache
    2697                 :            :  * directory if missing, etc.
    2698                 :            :  */
    2699                 :            : static void
    2700                 :          7 : initialize(void)
    2701                 :            : {
    2702                 :            :         char *errmsg;
    2703                 :            :         char *p;
    2704                 :            :         struct stat st;
    2705                 :          7 :         bool should_create_initial_config = false;
    2706                 :            : 
    2707                 :          7 :         conf_free(conf);
    2708                 :          7 :         conf = conf_create();
    2709                 :            : 
    2710                 :          7 :         p = getenv("CCACHE_CONFIGPATH");
    2711         [ +  - ]:          7 :         if (p) {
    2712                 :          7 :                 primary_config_path = x_strdup(p);
    2713                 :            :         } else {
    2714                 :          0 :                 secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
    2715         [ #  # ]:          0 :                 if (!conf_read(conf, secondary_config_path, &errmsg)) {
    2716         [ #  # ]:          0 :                         if (stat(secondary_config_path, &st) == 0) {
    2717                 :          0 :                                 fatal("%s", errmsg);
    2718                 :            :                         }
    2719                 :            :                         /* Missing config file in SYSCONFDIR is OK. */
    2720                 :          0 :                         free(errmsg);
    2721                 :            :                 }
    2722                 :            : 
    2723         [ #  # ]:          0 :                 if (str_eq(conf->cache_dir, "")) {
    2724                 :          0 :                         fatal("configuration setting \"cache_dir\" must not be the empty string");
    2725                 :            :                 }
    2726         [ #  # ]:          0 :                 if ((p = getenv("CCACHE_DIR"))) {
    2727                 :          0 :                         free(conf->cache_dir);
    2728                 :          0 :                         conf->cache_dir = strdup(p);
    2729                 :            :                 }
    2730         [ #  # ]:          0 :                 if (str_eq(conf->cache_dir, "")) {
    2731                 :          0 :                         fatal("CCACHE_DIR must not be the empty string");
    2732                 :            :                 }
    2733                 :            : 
    2734                 :          0 :                 primary_config_path = format("%s/ccache.conf", conf->cache_dir);
    2735                 :            :         }
    2736                 :            : 
    2737         [ -  + ]:          7 :         if (!conf_read(conf, primary_config_path, &errmsg)) {
    2738         [ #  # ]:          0 :                 if (stat(primary_config_path, &st) == 0) {
    2739                 :          0 :                         fatal("%s", errmsg);
    2740                 :            :                 }
    2741                 :          0 :                 should_create_initial_config = true;
    2742                 :            :         }
    2743                 :            : 
    2744         [ -  + ]:          7 :         if (!conf_update_from_environment(conf, &errmsg)) {
    2745                 :          0 :                 fatal("%s", errmsg);
    2746                 :            :         }
    2747                 :            : 
    2748         [ -  + ]:          7 :         if (conf->disable) {
    2749                 :          0 :                 should_create_initial_config = false;
    2750                 :            :         }
    2751                 :            : 
    2752         [ -  + ]:          7 :         if (should_create_initial_config) {
    2753                 :          0 :                 create_initial_config_file(conf, primary_config_path);
    2754                 :            :         }
    2755                 :            : 
    2756                 :          7 :         exitfn_init();
    2757                 :          7 :         exitfn_add_nullary(stats_flush);
    2758                 :          7 :         exitfn_add_nullary(clean_up_pending_tmp_files);
    2759                 :            : 
    2760                 :          7 :         cc_log("=== CCACHE %s STARTED =========================================",
    2761                 :            :                CCACHE_VERSION);
    2762                 :            : 
    2763         [ -  + ]:          7 :         if (conf->umask != UINT_MAX) {
    2764                 :          0 :                 umask(conf->umask);
    2765                 :            :         }
    2766                 :          7 : }
    2767                 :            : 
    2768                 :            : /* Reset the global state. Used by the test suite. */
    2769                 :            : void
    2770                 :         88 : cc_reset(void)
    2771                 :            : {
    2772                 :         88 :         conf_free(conf); conf = NULL;
    2773                 :         88 :         free(primary_config_path); primary_config_path = NULL;
    2774                 :         88 :         free(secondary_config_path); secondary_config_path = NULL;
    2775                 :         88 :         free(current_working_dir); current_working_dir = NULL;
    2776                 :         88 :         free(profile_dir); profile_dir = NULL;
    2777                 :         88 :         free(included_pch_file); included_pch_file = NULL;
    2778                 :         88 :         args_free(orig_args); orig_args = NULL;
    2779                 :         88 :         free(input_file); input_file = NULL;
    2780                 :         88 :         free(output_obj); output_obj = NULL;
    2781                 :         88 :         free(output_dwo); output_dwo = NULL;
    2782                 :         88 :         free(output_dep); output_dep = NULL;
    2783                 :         88 :         free(output_cov); output_cov = NULL;
    2784                 :         88 :         free(output_dia); output_dia = NULL;
    2785                 :         88 :         free(cached_obj_hash); cached_obj_hash = NULL;
    2786                 :         88 :         free(cached_obj); cached_obj = NULL;
    2787                 :         88 :         free(cached_dwo); cached_dwo = NULL;
    2788                 :         88 :         free(cached_stderr); cached_stderr = NULL;
    2789                 :         88 :         free(cached_dep); cached_dep = NULL;
    2790                 :         88 :         free(cached_cov); cached_cov = NULL;
    2791                 :         88 :         free(cached_dia); cached_dia = NULL;
    2792                 :         88 :         free(manifest_path); manifest_path = NULL;
    2793                 :         88 :         time_of_compilation = 0;
    2794         [ -  + ]:         88 :         if (included_files) {
    2795                 :          0 :                 hashtable_destroy(included_files, 1); included_files = NULL;
    2796                 :            :         }
    2797                 :         88 :         generating_dependencies = false;
    2798                 :         88 :         generating_coverage = false;
    2799                 :         88 :         profile_arcs = false;
    2800                 :         88 :         free(profile_dir); profile_dir = NULL;
    2801                 :         88 :         i_tmpfile = NULL;
    2802                 :         88 :         direct_i_file = false;
    2803                 :         88 :         free(cpp_stderr); cpp_stderr = NULL;
    2804                 :         88 :         free(stats_file); stats_file = NULL;
    2805                 :         88 :         output_is_precompiled_header = false;
    2806                 :            : 
    2807                 :         88 :         conf = conf_create();
    2808                 :         88 :         using_split_dwarf = false;
    2809                 :         88 : }
    2810                 :            : 
    2811                 :            : /* Make a copy of stderr that will not be cached, so things like
    2812                 :            :    distcc can send networking errors to it. */
    2813                 :            : static void
    2814                 :          1 : setup_uncached_err(void)
    2815                 :            : {
    2816                 :            :         char *buf;
    2817                 :            :         int uncached_fd;
    2818                 :            : 
    2819                 :          1 :         uncached_fd = dup(2);
    2820         [ -  + ]:          1 :         if (uncached_fd == -1) {
    2821                 :          0 :                 cc_log("dup(2) failed: %s", strerror(errno));
    2822                 :          0 :                 failed();
    2823                 :            :         }
    2824                 :            : 
    2825                 :            :         /* leak a pointer to the environment */
    2826                 :          1 :         buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
    2827                 :            : 
    2828         [ -  + ]:          1 :         if (putenv(buf) == -1) {
    2829                 :          0 :                 cc_log("putenv failed: %s", strerror(errno));
    2830                 :          0 :                 failed();
    2831                 :            :         }
    2832                 :          1 : }
    2833                 :            : 
    2834                 :            : static void
    2835                 :         27 : configuration_logger(const char *descr, const char *origin, void *context)
    2836                 :            : {
    2837                 :            :         (void)context;
    2838                 :         27 :         cc_bulklog("Config: (%s) %s", origin, descr);
    2839                 :         27 : }
    2840                 :            : 
    2841                 :            : /* the main ccache driver function */
    2842                 :            : static void
    2843                 :          1 : ccache(int argc, char *argv[])
    2844                 :            : {
    2845                 :          1 :         bool put_object_in_manifest = false;
    2846                 :            :         struct file_hash *object_hash;
    2847                 :          1 :         struct file_hash *object_hash_from_manifest = NULL;
    2848                 :            :         struct mdfour common_hash;
    2849                 :            :         struct mdfour direct_hash;
    2850                 :            :         struct mdfour cpp_hash;
    2851                 :            : 
    2852                 :            :         /* Arguments (except -E) to send to the preprocessor. */
    2853                 :            :         struct args *preprocessor_args;
    2854                 :            : 
    2855                 :            :         /* Arguments to send to the real compiler. */
    2856                 :            :         struct args *compiler_args;
    2857                 :            : 
    2858                 :          1 :         orig_args = args_init(argc, argv);
    2859                 :            : 
    2860                 :          1 :         initialize();
    2861                 :          1 :         find_compiler(argv);
    2862                 :            : 
    2863                 :            : #ifndef _WIN32
    2864                 :          1 :         signal(SIGHUP, signal_handler);
    2865                 :            : #endif
    2866                 :          1 :         signal(SIGINT, signal_handler);
    2867                 :          1 :         signal(SIGTERM, signal_handler);
    2868                 :            : 
    2869         [ +  - ]:          1 :         if (str_eq(conf->temporary_dir, "")) {
    2870                 :          1 :                 clean_up_internal_tempdir();
    2871                 :            :         }
    2872                 :            : 
    2873         [ +  - ]:          1 :         if (!str_eq(conf->log_file, "")) {
    2874                 :          1 :                 conf_print_items(conf, configuration_logger, NULL);
    2875                 :            :         }
    2876                 :            : 
    2877         [ -  + ]:          1 :         if (conf->disable) {
    2878                 :          0 :                 cc_log("ccache is disabled");
    2879                 :          0 :                 failed();
    2880                 :            :         }
    2881                 :            : 
    2882                 :          1 :         setup_uncached_err();
    2883                 :            : 
    2884                 :          1 :         cc_log_argv("Command line: ", argv);
    2885                 :          1 :         cc_log("Hostname: %s", get_hostname());
    2886                 :          1 :         cc_log("Working directory: %s", get_current_working_dir());
    2887                 :            : 
    2888         [ -  + ]:          1 :         if (conf->unify) {
    2889                 :          0 :                 cc_log("Direct mode disabled because unify mode is enabled");
    2890                 :          0 :                 conf->direct_mode = false;
    2891                 :            :         }
    2892                 :            : 
    2893         [ -  + ]:          1 :         if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
    2894                 :          0 :                 failed();
    2895                 :            :         }
    2896                 :            : 
    2897                 :          1 :         cc_log("Source file: %s", input_file);
    2898         [ -  + ]:          1 :         if (generating_dependencies) {
    2899                 :          0 :                 cc_log("Dependency file: %s", output_dep);
    2900                 :            :         }
    2901         [ -  + ]:          1 :         if (generating_coverage) {
    2902                 :          0 :                 cc_log("Coverage file: %s", output_cov);
    2903                 :            :         }
    2904         [ -  + ]:          1 :         if (output_dia) {
    2905                 :          0 :                 cc_log("Diagnostic file: %s", output_dia);
    2906                 :            :         }
    2907                 :            : 
    2908         [ -  + ]:          1 :         if (using_split_dwarf ) {
    2909         [ #  # ]:          0 :                 if (!generating_dependencies) {
    2910         [ #  # ]:          0 :                         assert(output_dwo);
    2911                 :            :                 }
    2912                 :            :         } else {
    2913         [ -  + ]:          1 :                 assert(!output_dwo);
    2914                 :            :         }
    2915                 :            : 
    2916         [ -  + ]:          1 :         if (output_dwo) {
    2917                 :          0 :                 cc_log("Split dwarf file: %s", output_dwo);
    2918                 :            :         }
    2919                 :            : 
    2920                 :          1 :         cc_log("Object file: %s", output_obj);
    2921                 :            : 
    2922                 :          1 :         hash_start(&common_hash);
    2923                 :          1 :         calculate_common_hash(preprocessor_args, &common_hash);
    2924                 :            : 
    2925                 :            :         /* try to find the hash using the manifest */
    2926                 :          1 :         direct_hash = common_hash;
    2927         [ -  + ]:          1 :         if (conf->direct_mode) {
    2928                 :          0 :                 cc_log("Trying direct lookup");
    2929                 :          0 :                 object_hash = calculate_object_hash(preprocessor_args, &direct_hash, 1);
    2930         [ #  # ]:          0 :                 if (object_hash) {
    2931                 :          0 :                         update_cached_result_globals(object_hash);
    2932                 :            : 
    2933                 :            :                         /*
    2934                 :            :                          * If we can return from cache at this point then do
    2935                 :            :                          * so.
    2936                 :            :                          */
    2937                 :          0 :                         from_cache(FROMCACHE_DIRECT_MODE, 0);
    2938                 :            : 
    2939                 :            :                         /*
    2940                 :            :                          * Wasn't able to return from cache at this point.
    2941                 :            :                          * However, the object was already found in manifest,
    2942                 :            :                          * so don't readd it later.
    2943                 :            :                          */
    2944                 :          0 :                         put_object_in_manifest = false;
    2945                 :            : 
    2946                 :          0 :                         object_hash_from_manifest = object_hash;
    2947                 :            :                 } else {
    2948                 :            :                         /* Add object to manifest later. */
    2949                 :          0 :                         put_object_in_manifest = true;
    2950                 :            :                 }
    2951                 :            :         }
    2952                 :            : 
    2953         [ -  + ]:          1 :         if (conf->read_only_direct) {
    2954                 :          0 :                 cc_log("Read-only direct mode; running real compiler");
    2955                 :          0 :                 failed();
    2956                 :            :         }
    2957                 :            : 
    2958                 :            :         /*
    2959                 :            :          * Find the hash using the preprocessed output. Also updates
    2960                 :            :          * included_files.
    2961                 :            :          */
    2962                 :          1 :         cpp_hash = common_hash;
    2963                 :          1 :         object_hash = calculate_object_hash(preprocessor_args, &cpp_hash, 0);
    2964         [ -  + ]:          1 :         if (!object_hash) {
    2965                 :          0 :                 fatal("internal error: object hash from cpp returned NULL");
    2966                 :            :         }
    2967                 :          1 :         update_cached_result_globals(object_hash);
    2968                 :            : 
    2969   [ -  +  #  # ]:          1 :         if (object_hash_from_manifest
    2970                 :          0 :             && !file_hashes_equal(object_hash_from_manifest, object_hash)) {
    2971                 :            :                 /*
    2972                 :            :                  * The hash from manifest differs from the hash of the
    2973                 :            :                  * preprocessor output. This could be because:
    2974                 :            :                  *
    2975                 :            :                  * - The preprocessor produces different output for the same
    2976                 :            :                  *   input (not likely).
    2977                 :            :                  * - There's a bug in ccache (maybe incorrect handling of
    2978                 :            :                  *   compiler arguments).
    2979                 :            :                  * - The user has used a different CCACHE_BASEDIR (most
    2980                 :            :                  *   likely).
    2981                 :            :                  *
    2982                 :            :                  * The best thing here would probably be to remove the hash
    2983                 :            :                  * entry from the manifest. For now, we use a simpler method:
    2984                 :            :                  * just remove the manifest file.
    2985                 :            :                  */
    2986                 :          0 :                 cc_log("Hash from manifest doesn't match preprocessor output");
    2987                 :          0 :                 cc_log("Likely reason: different CCACHE_BASEDIRs used");
    2988                 :          0 :                 cc_log("Removing manifest as a safety measure");
    2989                 :          0 :                 x_unlink(manifest_path);
    2990                 :            : 
    2991                 :          0 :                 put_object_in_manifest = true;
    2992                 :            :         }
    2993                 :            : 
    2994                 :            :         /* if we can return from cache at this point then do */
    2995                 :          1 :         from_cache(FROMCACHE_CPP_MODE, put_object_in_manifest);
    2996                 :            : 
    2997         [ -  + ]:          1 :         if (conf->read_only) {
    2998                 :          0 :                 cc_log("Read-only mode; running real compiler");
    2999                 :          0 :                 failed();
    3000                 :            :         }
    3001                 :            : 
    3002                 :          1 :         add_prefix(compiler_args);
    3003                 :            : 
    3004                 :            :         /* run real compiler, sending output to cache */
    3005                 :          1 :         to_cache(compiler_args);
    3006                 :            : 
    3007                 :          1 :         x_exit(0);
    3008                 :            : }
    3009                 :            : 
    3010                 :            : static void
    3011                 :          0 : configuration_printer(const char *descr, const char *origin, void *context)
    3012                 :            : {
    3013         [ #  # ]:          0 :         assert(context);
    3014                 :          0 :         fprintf(context, "(%s) %s\n", origin, descr);
    3015                 :          0 : }
    3016                 :            : 
    3017                 :            : /* the main program when not doing a compile */
    3018                 :            : static int
    3019                 :          6 : ccache_main_options(int argc, char *argv[])
    3020                 :            : {
    3021                 :            :         int c;
    3022                 :            :         char *errmsg;
    3023                 :            : 
    3024                 :            :         enum longopts {
    3025                 :            :                 DUMP_MANIFEST
    3026                 :            :         };
    3027                 :            :         static const struct option options[] = {
    3028                 :            :                 {"cleanup",       no_argument,       0, 'c'},
    3029                 :            :                 {"clear",         no_argument,       0, 'C'},
    3030                 :            :                 {"dump-manifest", required_argument, 0, DUMP_MANIFEST},
    3031                 :            :                 {"help",          no_argument,       0, 'h'},
    3032                 :            :                 {"max-files",     required_argument, 0, 'F'},
    3033                 :            :                 {"max-size",      required_argument, 0, 'M'},
    3034                 :            :                 {"set-config",    required_argument, 0, 'o'},
    3035                 :            :                 {"print-config",  no_argument,       0, 'p'},
    3036                 :            :                 {"show-stats",    no_argument,       0, 's'},
    3037                 :            :                 {"version",       no_argument,       0, 'V'},
    3038                 :            :                 {"zero-stats",    no_argument,       0, 'z'},
    3039                 :            :                 {0, 0, 0, 0}
    3040                 :            :         };
    3041                 :            : 
    3042         [ +  + ]:         12 :         while ((c = getopt_long(argc, argv, "cChF:M:o:psVz", options, NULL)) != -1) {
    3043   [ -  -  -  -  :          6 :                 switch (c) {
          -  -  -  -  +  
                -  -  - ]
    3044                 :            :                 case DUMP_MANIFEST:
    3045                 :          0 :                         manifest_dump(optarg, stdout);
    3046                 :          0 :                         break;
    3047                 :            : 
    3048                 :            :                 case 'c': /* --cleanup */
    3049                 :          0 :                         initialize();
    3050                 :          0 :                         cleanup_all(conf);
    3051                 :          0 :                         printf("Cleaned cache\n");
    3052                 :          0 :                         break;
    3053                 :            : 
    3054                 :            :                 case 'C': /* --clear */
    3055                 :          0 :                         initialize();
    3056                 :          0 :                         wipe_all(conf);
    3057                 :          0 :                         printf("Cleared cache\n");
    3058                 :          0 :                         break;
    3059                 :            : 
    3060                 :            :                 case 'h': /* --help */
    3061                 :          0 :                         fputs(USAGE_TEXT, stdout);
    3062                 :          0 :                         x_exit(0);
    3063                 :            : 
    3064                 :            :                 case 'F': /* --max-files */
    3065                 :            :                         {
    3066                 :            :                                 unsigned files;
    3067                 :          0 :                                 initialize();
    3068                 :          0 :                                 files = atoi(optarg);
    3069         [ #  # ]:          0 :                                 if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
    3070                 :            :                                                            &errmsg)) {
    3071         [ #  # ]:          0 :                                         if (files == 0) {
    3072                 :          0 :                                                 printf("Unset cache file limit\n");
    3073                 :            :                                         } else {
    3074                 :          0 :                                                 printf("Set cache file limit to %u\n", files);
    3075                 :            :                                         }
    3076                 :            :                                 } else {
    3077                 :          0 :                                         fatal("could not set cache file limit: %s", errmsg);
    3078                 :            :                                 }
    3079                 :            :                         }
    3080                 :          0 :                         break;
    3081                 :            : 
    3082                 :            :                 case 'M': /* --max-size */
    3083                 :            :                         {
    3084                 :            :                                 uint64_t size;
    3085                 :          0 :                                 initialize();
    3086         [ #  # ]:          0 :                                 if (!parse_size_with_suffix(optarg, &size)) {
    3087                 :          0 :                                         fatal("invalid size: %s", optarg);
    3088                 :            :                                 }
    3089         [ #  # ]:          0 :                                 if (conf_set_value_in_file(primary_config_path, "max_size", optarg,
    3090                 :            :                                                            &errmsg)) {
    3091         [ #  # ]:          0 :                                         if (size == 0) {
    3092                 :          0 :                                                 printf("Unset cache size limit\n");
    3093                 :            :                                         } else {
    3094                 :          0 :                                                 char *s = format_human_readable_size(size);
    3095                 :          0 :                                                 printf("Set cache size limit to %s\n", s);
    3096                 :          0 :                                                 free(s);
    3097                 :            :                                         }
    3098                 :            :                                 } else {
    3099                 :          0 :                                         fatal("could not set cache size limit: %s", errmsg);
    3100                 :            :                                 }
    3101                 :            :                         }
    3102                 :          0 :                         break;
    3103                 :            : 
    3104                 :            :                 case 'o': /* --set-config */
    3105                 :            :                         {
    3106                 :            :                                 char *errmsg, *key, *value, *p;
    3107                 :          0 :                                 initialize();
    3108                 :          0 :                                 p = strchr(optarg, '=');
    3109         [ #  # ]:          0 :                                 if (!p) {
    3110                 :          0 :                                         fatal("missing equal sign in \"%s\"", optarg);
    3111                 :            :                                 }
    3112                 :          0 :                                 key = x_strndup(optarg, p - optarg);
    3113                 :          0 :                                 value = p + 1;
    3114         [ #  # ]:          0 :                                 if (!conf_set_value_in_file(primary_config_path, key, value, &errmsg)) {
    3115                 :          0 :                                         fatal("%s", errmsg);
    3116                 :            :                                 }
    3117                 :          0 :                                 free(key);
    3118                 :            :                         }
    3119                 :          0 :                         break;
    3120                 :            : 
    3121                 :            :                 case 'p': /* --print-config */
    3122                 :          0 :                         initialize();
    3123                 :          0 :                         conf_print_items(conf, configuration_printer, stdout);
    3124                 :          0 :                         break;
    3125                 :            : 
    3126                 :            :                 case 's': /* --show-stats */
    3127                 :          6 :                         initialize();
    3128                 :          6 :                         stats_summary(conf);
    3129                 :          6 :                         break;
    3130                 :            : 
    3131                 :            :                 case 'V': /* --version */
    3132                 :          0 :                         fprintf(stdout, VERSION_TEXT, CCACHE_VERSION);
    3133                 :          0 :                         x_exit(0);
    3134                 :            : 
    3135                 :            :                 case 'z': /* --zero-stats */
    3136                 :          0 :                         initialize();
    3137                 :          0 :                         stats_zero();
    3138                 :          0 :                         printf("Statistics cleared\n");
    3139                 :          0 :                         break;
    3140                 :            : 
    3141                 :            :                 default:
    3142                 :          0 :                         fputs(USAGE_TEXT, stderr);
    3143                 :          0 :                         x_exit(1);
    3144                 :            :                 }
    3145                 :            :         }
    3146                 :            : 
    3147                 :          6 :         return 0;
    3148                 :            : }
    3149                 :            : 
    3150                 :            : int
    3151                 :          7 : ccache_main(int argc, char *argv[])
    3152                 :            : {
    3153                 :            :         /* check if we are being invoked as "ccache" */
    3154                 :          7 :         char *program_name = basename(argv[0]);
    3155         [ +  - ]:          7 :         if (same_executable_name(program_name, MYNAME)) {
    3156         [ -  + ]:          7 :                 if (argc < 2) {
    3157                 :          0 :                         fputs(USAGE_TEXT, stderr);
    3158                 :          0 :                         x_exit(1);
    3159                 :            :                 }
    3160                 :            :                 /* if the first argument isn't an option, then assume we are
    3161                 :            :                    being passed a compiler name and options */
    3162         [ +  + ]:          7 :                 if (argv[1][0] == '-') {
    3163                 :          6 :                         return ccache_main_options(argc, argv);
    3164                 :            :                 }
    3165                 :            :         }
    3166                 :          1 :         free(program_name);
    3167                 :            : 
    3168                 :          1 :         ccache(argc, argv);
    3169                 :          6 :         return 1;
    3170                 :            : }

Generated by: LCOV version 1.9