17d62b00eSchristos /* Basic C++ demangling support for GDB. 27d62b00eSchristos 3*6881a400Schristos Copyright (C) 1991-2023 Free Software Foundation, Inc. 47d62b00eSchristos 57d62b00eSchristos Written by Fred Fish at Cygnus Support. 67d62b00eSchristos 77d62b00eSchristos This file is part of GDB. 87d62b00eSchristos 97d62b00eSchristos This program is free software; you can redistribute it and/or modify 107d62b00eSchristos it under the terms of the GNU General Public License as published by 117d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 127d62b00eSchristos (at your option) any later version. 137d62b00eSchristos 147d62b00eSchristos This program is distributed in the hope that it will be useful, 157d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 167d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 177d62b00eSchristos GNU General Public License for more details. 187d62b00eSchristos 197d62b00eSchristos You should have received a copy of the GNU General Public License 207d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 217d62b00eSchristos 227d62b00eSchristos 237d62b00eSchristos /* This file contains support code for C++ demangling that is common 247d62b00eSchristos to a styles of demangling, and GDB specific. */ 257d62b00eSchristos 267d62b00eSchristos #include "defs.h" 277d62b00eSchristos #include "cli/cli-utils.h" /* for skip_to_space */ 287d62b00eSchristos #include "command.h" 297d62b00eSchristos #include "gdbcmd.h" 307d62b00eSchristos #include "demangle.h" 317d62b00eSchristos #include "gdb-demangle.h" 327d62b00eSchristos #include "language.h" 337d62b00eSchristos 347d62b00eSchristos /* Select the default C++ demangling style to use. The default is "auto", 357d62b00eSchristos which allows gdb to attempt to pick an appropriate demangling style for 367d62b00eSchristos the executable it has loaded. It can be set to a specific style ("gnu", 377d62b00eSchristos "lucid", "arm", "hp", etc.) in which case gdb will never attempt to do auto 387d62b00eSchristos selection of the style unless you do an explicit "set demangle auto". 397d62b00eSchristos To select one of these as the default, set DEFAULT_DEMANGLING_STYLE in 407d62b00eSchristos the appropriate target configuration file. */ 417d62b00eSchristos 427d62b00eSchristos #ifndef DEFAULT_DEMANGLING_STYLE 437d62b00eSchristos #define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING 447d62b00eSchristos #endif 457d62b00eSchristos 467d62b00eSchristos /* See documentation in gdb-demangle.h. */ 477d62b00eSchristos bool demangle = true; 487d62b00eSchristos 497d62b00eSchristos static void 507d62b00eSchristos show_demangle (struct ui_file *file, int from_tty, 517d62b00eSchristos struct cmd_list_element *c, const char *value) 527d62b00eSchristos { 53*6881a400Schristos gdb_printf (file, 547d62b00eSchristos _("Demangling of encoded C++/ObjC names " 557d62b00eSchristos "when displaying symbols is %s.\n"), 567d62b00eSchristos value); 577d62b00eSchristos } 587d62b00eSchristos 597d62b00eSchristos /* See documentation in gdb-demangle.h. */ 607d62b00eSchristos bool asm_demangle = false; 617d62b00eSchristos 627d62b00eSchristos static void 637d62b00eSchristos show_asm_demangle (struct ui_file *file, int from_tty, 647d62b00eSchristos struct cmd_list_element *c, const char *value) 657d62b00eSchristos { 66*6881a400Schristos gdb_printf (file, 677d62b00eSchristos _("Demangling of C++/ObjC names in " 687d62b00eSchristos "disassembly listings is %s.\n"), 697d62b00eSchristos value); 707d62b00eSchristos } 717d62b00eSchristos 727d62b00eSchristos /* String name for the current demangling style. Set by the 737d62b00eSchristos "set demangle-style" command, printed as part of the output by the 747d62b00eSchristos "show demangle-style" command. */ 757d62b00eSchristos 767d62b00eSchristos static const char *current_demangling_style_string; 777d62b00eSchristos 787d62b00eSchristos /* The array of names of the known demangling styles. Generated by 797d62b00eSchristos _initialize_demangler from libiberty_demanglers[] array. */ 807d62b00eSchristos 817d62b00eSchristos static const char **demangling_style_names; 827d62b00eSchristos static void 837d62b00eSchristos show_demangling_style_names(struct ui_file *file, int from_tty, 847d62b00eSchristos struct cmd_list_element *c, const char *value) 857d62b00eSchristos { 86*6881a400Schristos gdb_printf (file, _("The current C++ demangling style is \"%s\".\n"), 877d62b00eSchristos value); 887d62b00eSchristos } 897d62b00eSchristos 907d62b00eSchristos /* Set current demangling style. Called by the "set demangle-style" 917d62b00eSchristos command after it has updated the current_demangling_style_string to 927d62b00eSchristos match what the user has entered. 937d62b00eSchristos 947d62b00eSchristos If the user has entered a string that matches a known demangling style 957d62b00eSchristos name in the demanglers[] array then just leave the string alone and update 967d62b00eSchristos the current_demangling_style enum value to match. 977d62b00eSchristos 987d62b00eSchristos If the user has entered a string that doesn't match, including an empty 997d62b00eSchristos string, then print a list of the currently known styles and restore 1007d62b00eSchristos the current_demangling_style_string to match the current_demangling_style 1017d62b00eSchristos enum value. 1027d62b00eSchristos 1037d62b00eSchristos Note: Assumes that current_demangling_style_string always points to 1047d62b00eSchristos a malloc'd string, even if it is a null-string. */ 1057d62b00eSchristos 1067d62b00eSchristos static void 1077d62b00eSchristos set_demangling_command (const char *ignore, 1087d62b00eSchristos int from_tty, struct cmd_list_element *c) 1097d62b00eSchristos { 1107d62b00eSchristos const struct demangler_engine *dem; 1117d62b00eSchristos int i; 1127d62b00eSchristos 1137d62b00eSchristos /* First just try to match whatever style name the user supplied with 1147d62b00eSchristos one of the known ones. Don't bother special casing for an empty 1157d62b00eSchristos name, we just treat it as any other style name that doesn't match. 1167d62b00eSchristos If we match, update the current demangling style enum. */ 1177d62b00eSchristos 1187d62b00eSchristos for (dem = libiberty_demanglers, i = 0; 1197d62b00eSchristos dem->demangling_style != unknown_demangling; 1207d62b00eSchristos dem++) 1217d62b00eSchristos { 1227d62b00eSchristos if (strcmp (current_demangling_style_string, 1237d62b00eSchristos dem->demangling_style_name) == 0) 1247d62b00eSchristos { 1257d62b00eSchristos current_demangling_style = dem->demangling_style; 1267d62b00eSchristos current_demangling_style_string = demangling_style_names[i]; 1277d62b00eSchristos break; 1287d62b00eSchristos } 1297d62b00eSchristos i++; 1307d62b00eSchristos } 1317d62b00eSchristos 1327d62b00eSchristos /* We should have found a match, given we only add known styles to 1337d62b00eSchristos the enumeration list. */ 1347d62b00eSchristos gdb_assert (dem->demangling_style != unknown_demangling); 1357d62b00eSchristos } 1367d62b00eSchristos 1377d62b00eSchristos /* G++ uses a special character to indicate certain internal names. Which 1387d62b00eSchristos character it is depends on the platform: 1397d62b00eSchristos - Usually '$' on systems where the assembler will accept that 1407d62b00eSchristos - Usually '.' otherwise (this includes most sysv4-like systems and most 1417d62b00eSchristos ELF targets) 1427d62b00eSchristos - Occasionally '_' if neither of the above is usable 1437d62b00eSchristos 1447d62b00eSchristos We check '$' first because it is the safest, and '.' often has another 1457d62b00eSchristos meaning. We don't currently try to handle '_' because the precise forms 1467d62b00eSchristos of the names are different on those targets. */ 1477d62b00eSchristos 1487d62b00eSchristos static char cplus_markers[] = {'$', '.', '\0'}; 1497d62b00eSchristos 1507d62b00eSchristos /* See documentation in gdb-demangle.h. */ 1517d62b00eSchristos 1527d62b00eSchristos bool 1537d62b00eSchristos is_cplus_marker (int c) 1547d62b00eSchristos { 1557d62b00eSchristos return c && strchr (cplus_markers, c) != NULL; 1567d62b00eSchristos } 1577d62b00eSchristos 1587d62b00eSchristos /* Demangle the given string in the current language. */ 1597d62b00eSchristos 1607d62b00eSchristos static void 1617d62b00eSchristos demangle_command (const char *args, int from_tty) 1627d62b00eSchristos { 1637d62b00eSchristos const char *name; 1647d62b00eSchristos const char *arg_start; 1657d62b00eSchristos int processing_args = 1; 1667d62b00eSchristos const struct language_defn *lang; 1677d62b00eSchristos 1687d62b00eSchristos std::string arg_buf = args != NULL ? args : ""; 1697d62b00eSchristos arg_start = arg_buf.c_str (); 1707d62b00eSchristos 1717d62b00eSchristos std::string lang_name; 1727d62b00eSchristos while (processing_args 1737d62b00eSchristos && *arg_start == '-') 1747d62b00eSchristos { 1757d62b00eSchristos const char *p = skip_to_space (arg_start); 1767d62b00eSchristos 1777d62b00eSchristos if (strncmp (arg_start, "-l", p - arg_start) == 0) 1787d62b00eSchristos lang_name = extract_arg (&p); 1797d62b00eSchristos else if (strncmp (arg_start, "--", p - arg_start) == 0) 1807d62b00eSchristos processing_args = 0; 1817d62b00eSchristos else 1827d62b00eSchristos report_unrecognized_option_error ("demangle", arg_start); 1837d62b00eSchristos 1847d62b00eSchristos arg_start = skip_spaces (p); 1857d62b00eSchristos } 1867d62b00eSchristos 1877d62b00eSchristos name = arg_start; 1887d62b00eSchristos 1897d62b00eSchristos if (*name == '\0') 1907d62b00eSchristos error (_("Usage: demangle [-l LANGUAGE] [--] NAME")); 1917d62b00eSchristos 1927d62b00eSchristos if (!lang_name.empty ()) 1937d62b00eSchristos { 1947d62b00eSchristos enum language lang_enum; 1957d62b00eSchristos 1967d62b00eSchristos lang_enum = language_enum (lang_name.c_str ()); 1977d62b00eSchristos if (lang_enum == language_unknown) 1987d62b00eSchristos error (_("Unknown language \"%s\""), lang_name.c_str ()); 1997d62b00eSchristos lang = language_def (lang_enum); 2007d62b00eSchristos } 2017d62b00eSchristos else 2027d62b00eSchristos lang = current_language; 2037d62b00eSchristos 204*6881a400Schristos gdb::unique_xmalloc_ptr<char> demangled 205*6881a400Schristos = language_demangle (lang, name, DMGL_ANSI | DMGL_PARAMS); 2067d62b00eSchristos if (demangled != NULL) 207*6881a400Schristos gdb_printf ("%s\n", demangled.get ()); 2087d62b00eSchristos else 2097d62b00eSchristos error (_("Can't demangle \"%s\""), name); 2107d62b00eSchristos } 2117d62b00eSchristos 2127d62b00eSchristos void _initialize_gdb_demangle (); 2137d62b00eSchristos void 2147d62b00eSchristos _initialize_gdb_demangle () 2157d62b00eSchristos { 2167d62b00eSchristos int i, ndems; 2177d62b00eSchristos 2187d62b00eSchristos /* Fill the demangling_style_names[] array, and set the default 2197d62b00eSchristos demangling style chosen at compilation time. */ 2207d62b00eSchristos for (ndems = 0; 2217d62b00eSchristos libiberty_demanglers[ndems].demangling_style != unknown_demangling; 2227d62b00eSchristos ndems++) 2237d62b00eSchristos ; 2247d62b00eSchristos demangling_style_names = XCNEWVEC (const char *, ndems + 1); 2257d62b00eSchristos for (i = 0; 2267d62b00eSchristos libiberty_demanglers[i].demangling_style != unknown_demangling; 2277d62b00eSchristos i++) 2287d62b00eSchristos { 2297d62b00eSchristos demangling_style_names[i] 2307d62b00eSchristos = xstrdup (libiberty_demanglers[i].demangling_style_name); 2317d62b00eSchristos 2327d62b00eSchristos if (current_demangling_style_string == NULL 2337d62b00eSchristos && strcmp (DEFAULT_DEMANGLING_STYLE, demangling_style_names[i]) == 0) 2347d62b00eSchristos current_demangling_style_string = demangling_style_names[i]; 2357d62b00eSchristos } 2367d62b00eSchristos 2377d62b00eSchristos add_setshow_boolean_cmd ("demangle", class_support, &demangle, _("\ 2387d62b00eSchristos Set demangling of encoded C++/ObjC names when displaying symbols."), _("\ 2397d62b00eSchristos Show demangling of encoded C++/ObjC names when displaying symbols."), NULL, 2407d62b00eSchristos NULL, 2417d62b00eSchristos show_demangle, 2427d62b00eSchristos &setprintlist, &showprintlist); 2437d62b00eSchristos 2447d62b00eSchristos add_setshow_boolean_cmd ("asm-demangle", class_support, &asm_demangle, _("\ 2457d62b00eSchristos Set demangling of C++/ObjC names in disassembly listings."), _("\ 2467d62b00eSchristos Show demangling of C++/ObjC names in disassembly listings."), NULL, 2477d62b00eSchristos NULL, 2487d62b00eSchristos show_asm_demangle, 2497d62b00eSchristos &setprintlist, &showprintlist); 2507d62b00eSchristos 2517d62b00eSchristos add_setshow_enum_cmd ("demangle-style", class_support, 2527d62b00eSchristos demangling_style_names, 2537d62b00eSchristos ¤t_demangling_style_string, _("\ 2547d62b00eSchristos Set the current C++ demangling style."), _("\ 2557d62b00eSchristos Show the current C++ demangling style."), _("\ 2567d62b00eSchristos Use `set demangle-style' without arguments for a list of demangling styles."), 2577d62b00eSchristos set_demangling_command, 2587d62b00eSchristos show_demangling_style_names, 2597d62b00eSchristos &setlist, &showlist); 2607d62b00eSchristos 2617d62b00eSchristos add_cmd ("demangle", class_support, demangle_command, _("\ 2627d62b00eSchristos Demangle a mangled name.\n\ 2637d62b00eSchristos Usage: demangle [-l LANGUAGE] [--] NAME\n\ 2647d62b00eSchristos If LANGUAGE is not specified, NAME is demangled in the current language."), 2657d62b00eSchristos &cmdlist); 2667d62b00eSchristos } 267