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