]>
Commit | Line | Data |
---|---|---|
7365279f | 1 | /* Implementation of file prefix remapping support (-f*-prefix-map options). |
8d9254fc | 2 | Copyright (C) 2017-2020 Free Software Foundation, Inc. |
7365279f BK |
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 | } |