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                               &current_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