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: 2026-02-28 14:20:25 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Wrapper for ar/ranlib/nm to pass the LTO plugin.
       2              :    Copyright (C) 2011-2026 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 (const_cast<char * const *> (nargv) + 1, f);
     253            0 :       if (status)
     254              :         {
     255            0 :           fprintf (stderr, "Cannot write to temporary file %s\n", rsp_file);
     256            0 :           exit (1);
     257              :         }
     258            0 :       status = fclose (f);
     259            0 :       if (EOF == status)
     260              :         {
     261            0 :           fprintf (stderr, "Cannot close temporary file %s\n", rsp_file);
     262            0 :           exit (1);
     263              :         }
     264            0 :       rsp_arg = concat ("@", rsp_file, NULL);
     265            0 :       rsp_argv[0] = nargv[0];
     266            0 :       rsp_argv[1] = rsp_arg;
     267            0 :       rsp_argv[2] = NULL;
     268            0 :       nargv = rsp_argv;
     269              :     }
     270              : 
     271              :   /* Run utility */
     272              :   /* ??? the const is misplaced in pex_one's argv? */
     273            1 :   err_msg = pex_one (PEX_LAST|PEX_SEARCH,
     274              :                      exe_name,
     275              :                      const_cast<char * const *> (nargv),
     276            1 :                      concat ("gcc-", exe_name, NULL),
     277              :                      NULL,NULL,  &status, &err);
     278            1 :   if (err_msg)
     279            0 :     fprintf (stderr, "Error running %s: %s\n", exe_name, err_msg);
     280            1 :   else if (status)
     281              :     {
     282            0 :       if (WIFSIGNALED (status))
     283              :         {
     284            0 :           int sig = WTERMSIG (status);
     285            0 :           fprintf (stderr, "%s terminated with signal %d [%s]%s\n",
     286              :                    exe_name, sig, strsignal (sig),
     287            0 :                    WCOREDUMP (status) ? ", core dumped" : "");
     288              :         }
     289            0 :       else if (WIFEXITED (status))
     290            0 :         exit_code = WEXITSTATUS (status);
     291              :     }
     292              :   else
     293              :     exit_code = SUCCESS_EXIT_CODE;
     294              : 
     295            1 :   if (rsp_file)
     296            0 :     unlink (rsp_file);
     297              : 
     298            1 :   return exit_code;
     299              : }
        

Generated by: LCOV version 2.4-beta

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