1 /* Basic C++ demangling support for GDB.
2
3 Copyright (C) 1991-2024 Free Software Foundation, Inc.
4
5 Written by Fred Fish at Cygnus Support.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22
23 /* This file contains support code for C++ demangling that is common
24 to a styles of demangling, and GDB specific. */
25
26 #include "cli/cli-utils.h"
27 #include "command.h"
28 #include "cli/cli-cmds.h"
29 #include "demangle.h"
30 #include "gdb-demangle.h"
31 #include "language.h"
32
33 /* Select the default C++ demangling style to use. The default is "auto",
34 which allows gdb to attempt to pick an appropriate demangling style for
35 the executable it has loaded. It can be set to a specific style ("gnu",
36 "lucid", "arm", "hp", etc.) in which case gdb will never attempt to do auto
37 selection of the style unless you do an explicit "set demangle auto".
38 To select one of these as the default, set DEFAULT_DEMANGLING_STYLE in
39 the appropriate target configuration file. */
40
41 #ifndef DEFAULT_DEMANGLING_STYLE
42 #define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
43 #endif
44
45 /* See documentation in gdb-demangle.h. */
46 bool demangle = true;
47
48 static void
show_demangle(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)49 show_demangle (struct ui_file *file, int from_tty,
50 struct cmd_list_element *c, const char *value)
51 {
52 gdb_printf (file,
53 _("Demangling of encoded C++/ObjC names "
54 "when displaying symbols is %s.\n"),
55 value);
56 }
57
58 /* See documentation in gdb-demangle.h. */
59 bool asm_demangle = false;
60
61 static void
show_asm_demangle(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)62 show_asm_demangle (struct ui_file *file, int from_tty,
63 struct cmd_list_element *c, const char *value)
64 {
65 gdb_printf (file,
66 _("Demangling of C++/ObjC names in "
67 "disassembly listings is %s.\n"),
68 value);
69 }
70
71 /* String name for the current demangling style. Set by the
72 "set demangle-style" command, printed as part of the output by the
73 "show demangle-style" command. */
74
75 static const char *current_demangling_style_string;
76
77 /* The array of names of the known demangling styles. Generated by
78 _initialize_demangler from libiberty_demanglers[] array. */
79
80 static const char **demangling_style_names;
81 static void
show_demangling_style_names(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)82 show_demangling_style_names(struct ui_file *file, int from_tty,
83 struct cmd_list_element *c, const char *value)
84 {
85 gdb_printf (file, _("The current C++ demangling style is \"%s\".\n"),
86 value);
87 }
88
89 /* Set current demangling style. Called by the "set demangle-style"
90 command after it has updated the current_demangling_style_string to
91 match what the user has entered.
92
93 If the user has entered a string that matches a known demangling style
94 name in the demanglers[] array then just leave the string alone and update
95 the current_demangling_style enum value to match.
96
97 If the user has entered a string that doesn't match, including an empty
98 string, then print a list of the currently known styles and restore
99 the current_demangling_style_string to match the current_demangling_style
100 enum value.
101
102 Note: Assumes that current_demangling_style_string always points to
103 a malloc'd string, even if it is a null-string. */
104
105 static void
set_demangling_command(const char * ignore,int from_tty,struct cmd_list_element * c)106 set_demangling_command (const char *ignore,
107 int from_tty, struct cmd_list_element *c)
108 {
109 const struct demangler_engine *dem;
110 int i;
111
112 /* First just try to match whatever style name the user supplied with
113 one of the known ones. Don't bother special casing for an empty
114 name, we just treat it as any other style name that doesn't match.
115 If we match, update the current demangling style enum. */
116
117 for (dem = libiberty_demanglers, i = 0;
118 dem->demangling_style != unknown_demangling;
119 dem++)
120 {
121 if (strcmp (current_demangling_style_string,
122 dem->demangling_style_name) == 0)
123 {
124 current_demangling_style = dem->demangling_style;
125 current_demangling_style_string = demangling_style_names[i];
126 break;
127 }
128 i++;
129 }
130
131 /* We should have found a match, given we only add known styles to
132 the enumeration list. */
133 gdb_assert (dem->demangling_style != unknown_demangling);
134 }
135
136 /* G++ uses a special character to indicate certain internal names. Which
137 character it is depends on the platform:
138 - Usually '$' on systems where the assembler will accept that
139 - Usually '.' otherwise (this includes most sysv4-like systems and most
140 ELF targets)
141 - Occasionally '_' if neither of the above is usable
142
143 We check '$' first because it is the safest, and '.' often has another
144 meaning. We don't currently try to handle '_' because the precise forms
145 of the names are different on those targets. */
146
147 static char cplus_markers[] = {'$', '.', '\0'};
148
149 /* See documentation in gdb-demangle.h. */
150
151 bool
is_cplus_marker(int c)152 is_cplus_marker (int c)
153 {
154 return c && strchr (cplus_markers, c) != NULL;
155 }
156
157 /* Demangle the given string in the current language. */
158
159 static void
demangle_command(const char * args,int from_tty)160 demangle_command (const char *args, int from_tty)
161 {
162 const char *name;
163 const char *arg_start;
164 int processing_args = 1;
165 const struct language_defn *lang;
166
167 std::string arg_buf = args != NULL ? args : "";
168 arg_start = arg_buf.c_str ();
169
170 std::string lang_name;
171 while (processing_args
172 && *arg_start == '-')
173 {
174 const char *p = skip_to_space (arg_start);
175
176 if (strncmp (arg_start, "-l", p - arg_start) == 0)
177 lang_name = extract_arg (&p);
178 else if (strncmp (arg_start, "--", p - arg_start) == 0)
179 processing_args = 0;
180 else
181 report_unrecognized_option_error ("demangle", arg_start);
182
183 arg_start = skip_spaces (p);
184 }
185
186 name = arg_start;
187
188 if (*name == '\0')
189 error (_("Usage: demangle [-l LANGUAGE] [--] NAME"));
190
191 if (!lang_name.empty ())
192 {
193 enum language lang_enum;
194
195 lang_enum = language_enum (lang_name.c_str ());
196 if (lang_enum == language_unknown)
197 error (_("Unknown language \"%s\""), lang_name.c_str ());
198 lang = language_def (lang_enum);
199 }
200 else
201 lang = current_language;
202
203 gdb::unique_xmalloc_ptr<char> demangled
204 = lang->demangle_symbol (name, DMGL_ANSI | DMGL_PARAMS);
205 if (demangled != NULL)
206 gdb_printf ("%s\n", demangled.get ());
207 else
208 error (_("Can't demangle \"%s\""), name);
209 }
210
211 void _initialize_gdb_demangle ();
212 void
_initialize_gdb_demangle()213 _initialize_gdb_demangle ()
214 {
215 int i, ndems;
216
217 /* Fill the demangling_style_names[] array, and set the default
218 demangling style chosen at compilation time. */
219 for (ndems = 0;
220 libiberty_demanglers[ndems].demangling_style != unknown_demangling;
221 ndems++)
222 ;
223 demangling_style_names = XCNEWVEC (const char *, ndems + 1);
224 for (i = 0;
225 libiberty_demanglers[i].demangling_style != unknown_demangling;
226 i++)
227 {
228 demangling_style_names[i]
229 = xstrdup (libiberty_demanglers[i].demangling_style_name);
230
231 if (current_demangling_style_string == NULL
232 && strcmp (DEFAULT_DEMANGLING_STYLE, demangling_style_names[i]) == 0)
233 current_demangling_style_string = demangling_style_names[i];
234 }
235
236 add_setshow_boolean_cmd ("demangle", class_support, &demangle, _("\
237 Set demangling of encoded C++/ObjC names when displaying symbols."), _("\
238 Show demangling of encoded C++/ObjC names when displaying symbols."), NULL,
239 NULL,
240 show_demangle,
241 &setprintlist, &showprintlist);
242
243 add_setshow_boolean_cmd ("asm-demangle", class_support, &asm_demangle, _("\
244 Set demangling of C++/ObjC names in disassembly listings."), _("\
245 Show demangling of C++/ObjC names in disassembly listings."), NULL,
246 NULL,
247 show_asm_demangle,
248 &setprintlist, &showprintlist);
249
250 add_setshow_enum_cmd ("demangle-style", class_support,
251 demangling_style_names,
252 ¤t_demangling_style_string, _("\
253 Set the current C++ demangling style."), _("\
254 Show the current C++ demangling style."), _("\
255 Use `set demangle-style' without arguments for a list of demangling styles."),
256 set_demangling_command,
257 show_demangling_style_names,
258 &setlist, &showlist);
259
260 add_cmd ("demangle", class_support, demangle_command, _("\
261 Demangle a mangled name.\n\
262 Usage: demangle [-l LANGUAGE] [--] NAME\n\
263 If LANGUAGE is not specified, NAME is demangled in the current language."),
264 &cmdlist);
265 }
266