LCOV - code coverage report
Current view: top level - gcc - gcc-ar.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 62.9 % 116 73
Test Date: 2025-11-22 14:42:49 Functions: 100.0 % 2 2
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Wrapper for ar/ranlib/nm to pass the LTO plugin.
       2                 :             :    Copyright (C) 2011-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by Andi Kleen.
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it under
       8                 :             : the terms of the GNU General Public License as published by the Free
       9                 :             : Software Foundation; either version 3, or (at your option) any later
      10                 :             : version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :             : for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "libiberty.h"
      24                 :             : #include "file-find.h"
      25                 :             : 
      26                 :             : #ifndef PERSONALITY
      27                 :             : #error "Please set personality"
      28                 :             : #endif
      29                 :             : 
      30                 :             : /* The exec prefix as derived at compile-time from --prefix.  */
      31                 :             : 
      32                 :             : static const char standard_exec_prefix[] = STANDARD_EXEC_PREFIX;
      33                 :             : 
      34                 :             : /* The libexec prefix as derived at compile-time from --prefix.  */
      35                 :             : 
      36                 :             : static const char standard_libexec_prefix[] = STANDARD_LIBEXEC_PREFIX;
      37                 :             : 
      38                 :             : /* The bindir prefix as derived at compile-time from --prefix.  */
      39                 :             : 
      40                 :             : static const char standard_bin_prefix[] = STANDARD_BINDIR_PREFIX;
      41                 :             : 
      42                 :             : /* A relative path to be used in finding the location of tools
      43                 :             :    relative to this program.  */
      44                 :             : 
      45                 :             : static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
      46                 :             : 
      47                 :             : /* The exec prefix as relocated from the location of this program.  */
      48                 :             : 
      49                 :             : static const char *self_exec_prefix;
      50                 :             : 
      51                 :             : /* The libexec prefix as relocated from the location of this program.  */
      52                 :             : 
      53                 :             : static const char *self_libexec_prefix;
      54                 :             : 
      55                 :             : /* The tools prefix as relocated from the location of this program.  */
      56                 :             : 
      57                 :             : static const char *self_tooldir_prefix;
      58                 :             : 
      59                 :             : /* The name of the machine that is being targeted.  */
      60                 :             : 
      61                 :             : static const char *const target_machine = DEFAULT_TARGET_MACHINE;
      62                 :             : 
      63                 :             : /* The target version.  */
      64                 :             : 
      65                 :             : static const char *const target_version = DEFAULT_TARGET_VERSION;
      66                 :             : 
      67                 :             : /* The collection of target specific path prefixes.  */
      68                 :             : 
      69                 :             : static struct path_prefix target_path;
      70                 :             : 
      71                 :             : /* The collection path prefixes.  */
      72                 :             : 
      73                 :             : static struct path_prefix path;
      74                 :             : 
      75                 :             : /* The directory separator.  */
      76                 :             : 
      77                 :             : static const char dir_separator[] = { DIR_SEPARATOR, 0 };
      78                 :             : 
      79                 :             : static void
      80                 :           1 : setup_prefixes (const char *exec_path)
      81                 :             : {
      82                 :           1 :   const char *self;
      83                 :             : 
      84                 :           1 :   self = getenv ("GCC_EXEC_PREFIX");
      85                 :           1 :   if (!self)
      86                 :             :     self = exec_path;
      87                 :             :   else
      88                 :           1 :     self = concat (self, "gcc-" PERSONALITY, NULL);
      89                 :             : 
      90                 :             :   /* Relocate the exec prefix.  */
      91                 :           1 :   self_exec_prefix = make_relative_prefix (self,
      92                 :             :                                            standard_bin_prefix,
      93                 :             :                                            standard_exec_prefix);
      94                 :           1 :   if (self_exec_prefix == NULL)
      95                 :           0 :     self_exec_prefix = standard_exec_prefix;
      96                 :             : 
      97                 :             :   /* Relocate libexec prefix.  */
      98                 :           1 :   self_libexec_prefix = make_relative_prefix (self,
      99                 :             :                                               standard_bin_prefix,
     100                 :             :                                               standard_libexec_prefix);
     101                 :           1 :   if (self_libexec_prefix == NULL)
     102                 :           0 :     self_libexec_prefix = standard_libexec_prefix;
     103                 :             : 
     104                 :             : 
     105                 :             :   /* Build the relative path to the target-specific tool directory.  */
     106                 :           1 :   self_tooldir_prefix = concat (tooldir_base_prefix, target_machine,
     107                 :             :                                 dir_separator, NULL);
     108                 :           1 :   self_tooldir_prefix = concat (self_exec_prefix, target_machine,
     109                 :             :                                 dir_separator, target_version, dir_separator,
     110                 :             :                                 self_tooldir_prefix, NULL);
     111                 :             : 
     112                 :             :   /* Add the target-specific tool bin prefix.  */
     113                 :           1 :   prefix_from_string (concat (self_tooldir_prefix, "bin", NULL), &target_path);
     114                 :             : 
     115                 :             :   /* Add the target-specific libexec prefix.  */
     116                 :           1 :   self_libexec_prefix = concat (self_libexec_prefix, target_machine,
     117                 :             :                                 dir_separator, target_version,
     118                 :             :                                 dir_separator, NULL);
     119                 :           1 :   prefix_from_string (self_libexec_prefix, &target_path);
     120                 :             : 
     121                 :             :   /* Add path as a last resort.  */
     122                 :           1 :   prefix_from_env ("PATH", &path);
     123                 :           1 : }
     124                 :             : 
     125                 :             : int
     126                 :           1 : main (int ac, char **av)
     127                 :             : {
     128                 :           1 :   const char *exe_name;
     129                 :             : #if HAVE_LTO_PLUGIN > 0
     130                 :           1 :   char *plugin;
     131                 :           1 :   const int j = 2; /* Two extra args, --plugin <plugin>  */
     132                 :             : #else
     133                 :             :   const int j = 0; /* No extra args.  */
     134                 :             : #endif
     135                 :           1 :   int k, status, err;
     136                 :           1 :   const char *err_msg;
     137                 :           1 :   const char **nargv;
     138                 :           1 :   char **old_argv;
     139                 :           1 :   const char *rsp_file = NULL;
     140                 :           1 :   const char *rsp_arg = NULL;
     141                 :           1 :   const char *rsp_argv[3];
     142                 :           1 :   bool is_ar = !strcmp (PERSONALITY, "ar");
     143                 :           1 :   int exit_code = FATAL_EXIT_CODE;
     144                 :           1 :   int i;
     145                 :             : 
     146                 :           1 :   setup_prefixes (av[0]);
     147                 :             : 
     148                 :             :   /* Not using getopt for now.  */
     149                 :           2 :   for (i = 0; i < ac; i++)
     150                 :           2 :       if (startswith (av[i], "-B"))
     151                 :             :         {
     152                 :           1 :           const char *arg = av[i] + 2;
     153                 :           1 :           const char *end;
     154                 :           1 :           size_t len;
     155                 :             : 
     156                 :           1 :           memmove (av + i, av + i + 1, sizeof (char *) * ((ac + 1) - i));
     157                 :           1 :           ac--;
     158                 :           1 :           if (*arg == 0)
     159                 :             :             {
     160                 :           0 :               arg = av[i];
     161                 :           0 :               if (!arg)
     162                 :             :                 {
     163                 :           0 :                   fprintf (stderr, "Usage: gcc-ar [-B prefix] ar arguments ...\n");
     164                 :           0 :                   exit (EXIT_FAILURE);
     165                 :             :                 }
     166                 :           0 :               memmove (av + i, av + i + 1, sizeof (char *) * ((ac + 1) - i));
     167                 :           0 :               ac--;
     168                 :           0 :               i++;
     169                 :             :             }
     170                 :             :           /* else it's a joined argument  */
     171                 :             : 
     172                 :           1 :           len = strlen (arg);
     173                 :           1 :           if (len > 0)
     174                 :           1 :             len--;
     175                 :           1 :           end = arg + len;
     176                 :             : 
     177                 :             :           /* Always add a dir separator for the prefix list.  */
     178                 :           1 :           if (end > arg && !IS_DIR_SEPARATOR (*end))
     179                 :             :             {
     180                 :           0 :               static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
     181                 :           0 :               arg = concat (arg, dir_separator_str, NULL);
     182                 :             :             }
     183                 :             : 
     184                 :           1 :           add_prefix_begin (&path, arg);
     185                 :           1 :           add_prefix_begin (&target_path, arg);
     186                 :           1 :           break;
     187                 :             :         }
     188                 :             : 
     189                 :             : #if HAVE_LTO_PLUGIN > 0
     190                 :             :   /* Find the GCC LTO plugin */
     191                 :           1 :   plugin = find_a_file (&target_path, LTOPLUGINSONAME, R_OK);
     192                 :           1 :   if (!plugin)
     193                 :             :     {
     194                 :           0 :       fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME);
     195                 :           0 :       exit (1);
     196                 :             :     }
     197                 :             : #endif
     198                 :             : 
     199                 :             :   /* Find the wrapped binutils program.  */
     200                 :           1 :   exe_name = find_a_file (&target_path, PERSONALITY, X_OK);
     201                 :           1 :   if (!exe_name)
     202                 :             :     {
     203                 :           1 :       const char *real_exe_name = PERSONALITY;
     204                 :             : #ifdef CROSS_DIRECTORY_STRUCTURE
     205                 :             :       real_exe_name = concat (target_machine, "-", PERSONALITY, NULL);
     206                 :             : #endif
     207                 :           1 :       exe_name = find_a_file (&path, real_exe_name, X_OK);
     208                 :           1 :       if (!exe_name)
     209                 :             :         {
     210                 :           0 :           fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0],
     211                 :             :                    real_exe_name);
     212                 :           0 :           exit (1);
     213                 :             :         }
     214                 :             :     }
     215                 :             : 
     216                 :             :   /* Expand any @files before modifying the command line
     217                 :             :      and use a temporary response file if there were any.  */
     218                 :           1 :   old_argv = av;
     219                 :           1 :   expandargv (&ac, &av);
     220                 :           1 :   if (av != old_argv)
     221                 :           0 :     rsp_file = make_temp_file ("");
     222                 :             : 
     223                 :             :   /* Prepend - if necessary.  */
     224                 :           1 :   if (is_ar && av[1] && av[1][0] != '-')
     225                 :           1 :     av[1] = concat ("-", av[1], NULL);
     226                 :             : 
     227                 :             :   /* Create new command line with plugin - if we have one, otherwise just
     228                 :             :      copy the command through.  */
     229                 :           1 :   nargv = XCNEWVEC (const char *, ac + j + 1); /* +j plugin args +1 for NULL.  */
     230                 :           1 :   nargv[0] = exe_name;
     231                 :             : #if HAVE_LTO_PLUGIN > 0
     232                 :           1 :   nargv[1] = "--plugin";
     233                 :           1 :   nargv[2] = plugin;
     234                 :             : #endif
     235                 :          12 :   for (k = 1; k < ac; k++)
     236                 :          11 :     nargv[j + k] = av[k];
     237                 :           1 :   nargv[j + k] = NULL;
     238                 :             : 
     239                 :             :   /* If @file was passed, put nargv into the temporary response
     240                 :             :      file and then change it to a single @FILE argument, where
     241                 :             :      FILE is the temporary filename.  */
     242                 :           1 :   if (rsp_file)
     243                 :             :     {
     244                 :           0 :       FILE *f;
     245                 :           0 :       int status;
     246                 :           0 :       f = fopen (rsp_file, "w");
     247                 :           0 :       if (f == NULL)
     248                 :             :         {
     249                 :           0 :           fprintf (stderr, "Cannot open temporary file %s\n", rsp_file);
     250                 :           0 :           exit (1);
     251                 :             :         }
     252                 :           0 :       status = writeargv (
     253                 :             :           CONST_CAST2 (char * const *, const char **, nargv) + 1, f);
     254                 :           0 :       if (status)
     255                 :             :         {
     256                 :           0 :           fprintf (stderr, "Cannot write to temporary file %s\n", rsp_file);
     257                 :           0 :           exit (1);
     258                 :             :         }
     259                 :           0 :       status = fclose (f);
     260                 :           0 :       if (EOF == status)
     261                 :             :         {
     262                 :           0 :           fprintf (stderr, "Cannot close temporary file %s\n", rsp_file);
     263                 :           0 :           exit (1);
     264                 :             :         }
     265                 :           0 :       rsp_arg = concat ("@", rsp_file, NULL);
     266                 :           0 :       rsp_argv[0] = nargv[0];
     267                 :           0 :       rsp_argv[1] = rsp_arg;
     268                 :           0 :       rsp_argv[2] = NULL;
     269                 :           0 :       nargv = rsp_argv;
     270                 :             :     }
     271                 :             : 
     272                 :             :   /* Run utility */
     273                 :             :   /* ??? the const is misplaced in pex_one's argv? */
     274                 :           1 :   err_msg = pex_one (PEX_LAST|PEX_SEARCH,
     275                 :             :                      exe_name,
     276                 :             :                      CONST_CAST2 (char * const *, const char **, nargv),
     277                 :           1 :                      concat ("gcc-", exe_name, NULL),
     278                 :             :                      NULL,NULL,  &status, &err);
     279                 :           1 :   if (err_msg)
     280                 :           0 :     fprintf (stderr, "Error running %s: %s\n", exe_name, err_msg);
     281                 :           1 :   else if (status)
     282                 :             :     {
     283                 :           0 :       if (WIFSIGNALED (status))
     284                 :             :         {
     285                 :           0 :           int sig = WTERMSIG (status);
     286                 :           0 :           fprintf (stderr, "%s terminated with signal %d [%s]%s\n",
     287                 :             :                    exe_name, sig, strsignal (sig),
     288                 :           0 :                    WCOREDUMP (status) ? ", core dumped" : "");
     289                 :             :         }
     290                 :           0 :       else if (WIFEXITED (status))
     291                 :           0 :         exit_code = WEXITSTATUS (status);
     292                 :             :     }
     293                 :             :   else
     294                 :             :     exit_code = SUCCESS_EXIT_CODE;
     295                 :             : 
     296                 :           1 :   if (rsp_file)
     297                 :           0 :     unlink (rsp_file);
     298                 :             : 
     299                 :           1 :   return exit_code;
     300                 :             : }
        

Generated by: LCOV version 2.1-beta

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