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