LCOV - code coverage report
Current view: top level - gcc - file-prefix-map.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 79.4 % 68 54
Test Date: 2026-02-28 14:20:25 Functions: 88.9 % 9 8
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Implementation of file prefix remapping support (-f*-prefix-map options).
       2              :    Copyright (C) 2017-2026 Free Software Foundation, Inc.
       3              : 
       4              :    This program is free software; you can redistribute it and/or modify it
       5              :    under the terms of the GNU General Public License as published by the
       6              :    Free Software Foundation; either version 3, or (at your option) any
       7              :    later version.
       8              : 
       9              :    This program is distributed in the hope that it will be useful,
      10              :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12              :    GNU General Public License for more details.
      13              : 
      14              :    You should have received a copy of the GNU General Public License
      15              :    along with this program; see the file COPYING3.  If not see
      16              :    <http://www.gnu.org/licenses/>.  */
      17              : 
      18              : #include "config.h"
      19              : #include "system.h"
      20              : #include "coretypes.h"
      21              : #include "diagnostic.h"
      22              : #include "file-prefix-map.h"
      23              : 
      24              : /* Structure recording the mapping from source file and directory names at
      25              :    compile time to those to be embedded in the compilation result (debug
      26              :    information, the __FILE__ macro expansion, etc).  */
      27              : struct file_prefix_map
      28              : {
      29              :   const char *old_prefix;
      30              :   const char *new_prefix;
      31              :   size_t old_len;
      32              :   size_t new_len;
      33              :   bool canonicalize;
      34              :   struct file_prefix_map *next;
      35              : };
      36              : 
      37              : /* Record a file prefix mapping in the specified map.  ARG is the argument to
      38              :    -f*-prefix-map and must be of the form OLD=NEW.  OPT is the option name
      39              :    for diagnostics.  */
      40              : static void
      41         1220 : add_prefix_map (file_prefix_map *&maps, const char *arg, const char *opt)
      42              : {
      43         1220 :   file_prefix_map *map;
      44         1220 :   const char *p;
      45              : 
      46              :   /* Note: looking for the last '='. The thinking is we can control the paths
      47              :      inside our projects but not where the users build them.  */
      48         1220 :   p = strrchr (arg, '=');
      49         1220 :   if (!p)
      50              :     {
      51            0 :       error ("invalid argument %qs to %qs", arg, opt);
      52            0 :       return;
      53              :     }
      54         1220 :   map = XNEW (file_prefix_map);
      55         1220 :   map->canonicalize = flag_canon_prefix_map;
      56         1220 :   map->old_prefix = xstrndup (arg, p - arg);
      57         1220 :   map->old_len = p - arg;
      58         1220 :   if (map->canonicalize)
      59              :     {
      60            0 :       char *realname = lrealpath (map->old_prefix);
      61            0 :       free (const_cast <char *> (map->old_prefix));
      62            0 :       map->old_prefix = realname;
      63            0 :       map->old_len = strlen (realname);
      64              :     }
      65         1220 :   p++;
      66         1220 :   map->new_prefix = xstrdup (p);
      67         1220 :   map->new_len = strlen (p);
      68         1220 :   map->next = maps;
      69         1220 :   maps = map;
      70              : }
      71              : 
      72              : /* Perform user-specified mapping of filename prefixes.  Return the
      73              :    GC-allocated new name corresponding to FILENAME or FILENAME if no
      74              :    remapping was performed.  */
      75              : 
      76              : static const char *
      77      4041201 : remap_filename (file_prefix_map *maps, const char *filename)
      78              : {
      79      4041201 :   file_prefix_map *map;
      80      4041201 :   char *s;
      81      4041201 :   const char *name;
      82      4041201 :   const char *realname = NULL;
      83      4041201 :   size_t name_len;
      84              : 
      85      4041201 :   if (!filename)
      86              :     return filename;
      87              : 
      88      4049341 :   for (map = maps; map; map = map->next)
      89         8697 :     if (map->canonicalize)
      90              :       {
      91            0 :         if (realname == NULL)
      92              :           {
      93            0 :             if (lbasename (filename) == filename)
      94              :               realname = filename;
      95              :             else
      96            0 :               realname = lrealpath (filename);
      97              :           }
      98            0 :         if (filename_ncmp (realname, map->old_prefix, map->old_len) == 0)
      99              :           break;
     100              :       }
     101         8697 :     else if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0)
     102              :       break;
     103      4041201 :   if (!map)
     104              :     {
     105      4040644 :       if (realname != filename)
     106      4040644 :         free (const_cast <char *> (realname));
     107      4040644 :       return filename;
     108              :     }
     109          557 :   if (map->canonicalize)
     110            0 :     name = realname + map->old_len;
     111              :   else
     112          557 :     name = filename + map->old_len;
     113          557 :   name_len = strlen (name) + 1;
     114              : 
     115          557 :   s = (char *) ggc_alloc_atomic (name_len + map->new_len);
     116          557 :   memcpy (s, map->new_prefix, map->new_len);
     117          557 :   memcpy (s + map->new_len, name, name_len);
     118          557 :   if (realname != filename)
     119          557 :     free (const_cast <char *> (realname));
     120              :   return s;
     121              : }
     122              : 
     123              : /* NOTE: if adding another -f*-prefix-map option then don't forget to
     124              :    ignore it in DW_AT_producer (gen_command_line_string in opts.cc).  */
     125              : 
     126              : /* Linked lists of file_prefix_map structures.  */
     127              : static file_prefix_map *macro_prefix_maps; /* -fmacro-prefix-map  */
     128              : static file_prefix_map *debug_prefix_maps; /* -fdebug-prefix-map  */
     129              : static file_prefix_map *profile_prefix_maps; /* -fprofile-prefix-map  */
     130              : 
     131              : /* Record a file prefix mapping for -fmacro-prefix-map.  */
     132              : void
     133            8 : add_macro_prefix_map (const char *arg)
     134              : {
     135            8 :   add_prefix_map (macro_prefix_maps, arg, "-fmacro-prefix-map");
     136            8 : }
     137              : 
     138              : /* Record a file prefix mapping for -fdebug-prefix-map.  */
     139              : void
     140          552 : add_debug_prefix_map (const char *arg)
     141              : {
     142          552 :   add_prefix_map (debug_prefix_maps, arg, "-fdebug-prefix-map");
     143          552 : }
     144              : 
     145              : /* Record a file prefix mapping for all -f*-prefix-map.  */
     146              : void
     147          220 : add_file_prefix_map (const char *arg)
     148              : {
     149          220 :   add_prefix_map (macro_prefix_maps, arg, "-ffile-prefix-map");
     150          220 :   add_prefix_map (debug_prefix_maps, arg, "-ffile-prefix-map");
     151          220 :   add_prefix_map (profile_prefix_maps, arg, "-ffile-prefix-map");
     152          220 : }
     153              : 
     154              : /* Record a file prefix mapping for -fprofile-prefix-map.  */
     155              : void
     156            0 : add_profile_prefix_map (const char *arg)
     157              : {
     158            0 :   add_prefix_map (profile_prefix_maps, arg, "-fprofile-prefix-map");
     159            0 : }
     160              : 
     161              : /* Remap using -fmacro-prefix-map.  Return the GC-allocated new name
     162              :    corresponding to FILENAME or FILENAME if no remapping was performed.  */
     163              : const char *
     164       275852 : remap_macro_filename (const char *filename)
     165              : {
     166       275852 :   return remap_filename (macro_prefix_maps, filename);
     167              : }
     168              : 
     169              : /* Remap using -fdebug-prefix-map.  Return the GC-allocated new name
     170              :    corresponding to FILENAME or FILENAME if no remapping was performed.  */
     171              : const char *
     172      3751807 : remap_debug_filename (const char *filename)
     173              : {
     174      3751807 :   return remap_filename (debug_prefix_maps, filename);
     175              : }
     176              : 
     177              : /* Remap using -fprofile-prefix-map.  Return the GC-allocated new name
     178              :    corresponding to FILENAME or FILENAME if no remapping was performed.  */
     179              : const char *
     180        13542 : remap_profile_filename (const char *filename)
     181              : {
     182        13542 :   return remap_filename (profile_prefix_maps, filename);
     183              : }
        

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.