1 /* Implementation of file prefix remapping support (-f*-prefix-map options). 2 Copyright (C) 2017 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 struct file_prefix_map *next; 34 }; 35 36 /* Record a file prefix mapping in the specified map. ARG is the argument to 37 -f*-prefix-map and must be of the form OLD=NEW. OPT is the option name 38 for diagnostics. */ 39 static void 40 add_prefix_map (file_prefix_map *&maps, const char *arg, const char *opt) 41 { 42 file_prefix_map *map; 43 const char *p; 44 45 /* Note: looking for the last '='. The thinking is we can control the paths 46 inside our projects but not where the users build them. */ 47 p = strrchr (arg, '='); 48 if (!p) 49 { 50 error ("invalid argument %qs to %qs", arg, opt); 51 return; 52 } 53 map = XNEW (file_prefix_map); 54 map->old_prefix = xstrndup (arg, p - arg); 55 map->old_len = p - arg; 56 p++; 57 map->new_prefix = xstrdup (p); 58 map->new_len = strlen (p); 59 map->next = maps; 60 maps = map; 61 } 62 63 /* Perform user-specified mapping of filename prefixes. Return the 64 GC-allocated new name corresponding to FILENAME or FILENAME if no 65 remapping was performed. */ 66 67 static const char * 68 remap_filename (file_prefix_map *maps, const char *filename) 69 { 70 file_prefix_map *map; 71 char *s; 72 const char *name; 73 size_t name_len; 74 75 for (map = maps; map; map = map->next) 76 if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0) 77 break; 78 if (!map) 79 return filename; 80 name = filename + map->old_len; 81 name_len = strlen (name) + 1; 82 83 s = (char *) ggc_alloc_atomic (name_len + map->new_len); 84 memcpy (s, map->new_prefix, map->new_len); 85 memcpy (s + map->new_len, name, name_len); 86 return s; 87 } 88 89 /* NOTE: if adding another -f*-prefix-map option then don't forget to 90 ignore it in DW_AT_producer (dwarf2out.c). */ 91 92 /* Linked lists of file_prefix_map structures. */ 93 static file_prefix_map *macro_prefix_maps; /* -fmacro-prefix-map */ 94 static file_prefix_map *debug_prefix_maps; /* -fdebug-prefix-map */ 95 96 /* Record a file prefix mapping for -fmacro-prefix-map. */ 97 void 98 add_macro_prefix_map (const char *arg) 99 { 100 add_prefix_map (macro_prefix_maps, arg, "-fmacro-prefix-map"); 101 } 102 103 /* Record a file prefix mapping for -fdebug-prefix-map. */ 104 void 105 add_debug_prefix_map (const char *arg) 106 { 107 add_prefix_map (debug_prefix_maps, arg, "-fdebug-prefix-map"); 108 } 109 110 /* Record a file prefix mapping for all -f*-prefix-map. */ 111 void 112 add_file_prefix_map (const char *arg) 113 { 114 add_prefix_map (macro_prefix_maps, arg, "-ffile-prefix-map"); 115 add_prefix_map (debug_prefix_maps, arg, "-ffile-prefix-map"); 116 } 117 118 /* Remap using -fmacro-prefix-map. Return the GC-allocated new name 119 corresponding to FILENAME or FILENAME if no remapping was performed. */ 120 const char * 121 remap_macro_filename (const char *filename) 122 { 123 return remap_filename (macro_prefix_maps, filename); 124 } 125 126 /* Remap using -fdebug-prefix-map. Return the GC-allocated new name 127 corresponding to FILENAME or FILENAME if no remapping was performed. */ 128 const char * 129 remap_debug_filename (const char *filename) 130 { 131 return remap_filename (debug_prefix_maps, filename); 132 } 133