diff --git a/bfd/bfd.c b/bfd/bfd.c index a3c522c..fa68883 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -2466,9 +2466,9 @@ bfd_demangle (bfd *abfd, const char *name, int options) ++name; pre_len = name - pre; - /* Strip off @plt and suchlike too. */ + /* Strip off @plt too. */ alloc = NULL; - suf = strchr (name, '@'); + suf = strstr (name, "@plt"); if (suf != NULL) { alloc = (char *) bfd_malloc (suf - name + 1); diff --git a/gdb/Makefile.in b/gdb/Makefile.in index c3e074b..9399039 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -612,7 +612,8 @@ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(LIBCTF) $(ZLIB) \ @LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \ $(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \ $(LIBIBERTY) $(WIN32LIBS) $(LIBGNU) $(LIBICONV) $(LIBMPFR) \ - $(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) + $(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) \ + -lLLVMDemangle CDEPS = $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) $(LIBCTF) \ $(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU) diff --git a/include/demangle.h b/include/demangle.h index f5d9b9e..8ac014b 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -57,9 +57,10 @@ extern "C" { #define DMGL_GNAT (1 << 15) #define DMGL_DLANG (1 << 16) #define DMGL_RUST (1 << 17) /* Rust wraps GNU_V3 style mangling. */ +#define DMGL_MSVC (1 << 30) /* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST) +#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST|DMGL_MSVC) /* Disable a limit on the depth of recursion in mangled strings. Note if this limit is disabled then stack exhaustion is possible when @@ -89,7 +90,8 @@ extern enum demangling_styles java_demangling = DMGL_JAVA, gnat_demangling = DMGL_GNAT, dlang_demangling = DMGL_DLANG, - rust_demangling = DMGL_RUST + rust_demangling = DMGL_RUST, + msvc_demangling = DMGL_MSVC } current_demangling_style; /* Define string names for the various demangling styles. */ @@ -101,6 +103,7 @@ extern enum demangling_styles #define GNAT_DEMANGLING_STYLE_STRING "gnat" #define DLANG_DEMANGLING_STYLE_STRING "dlang" #define RUST_DEMANGLING_STYLE_STRING "rust" +#define MSVC_DEMANGLING_STYLE_STRING "msvc" /* Some macros to test what demangling style is active. */ @@ -111,6 +114,7 @@ extern enum demangling_styles #define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT) #define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG) #define RUST_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_RUST) +#define MSVC_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_MSVC) /* Provide information about the available demangle styles. This code is pulled from gdb into libiberty because it is useful to binutils also. */ @@ -180,6 +184,9 @@ rust_demangle_sym (char *sym); extern char * rust_demangle (const char *mangled, int options); +extern char* +msvc_demangle(const char* mangled, int options); + enum gnu_v3_ctor_kinds { gnu_v3_complete_object_ctor = 1, gnu_v3_base_object_ctor, diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 0be45b4..de25b9b 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -145,6 +145,7 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \ physmem.c putenv.c \ random.c regex.c rename.c rindex.c \ rust-demangle.c \ + msvc-demangle.cpp \ safe-ctype.c setenv.c setproctitle.c sha1.c sigsetmask.c \ simple-object.c simple-object-coff.c simple-object-elf.c \ simple-object-mach-o.c simple-object-xcoff.c \ @@ -183,6 +184,7 @@ REQUIRED_OFILES = \ ./pex-common.$(objext) ./pex-one.$(objext) \ ./@pexecute@.$(objext) ./vprintf-support.$(objext) \ ./rust-demangle.$(objext) \ + ./msvc-demangle.$(objext) \ ./safe-ctype.$(objext) \ ./simple-object.$(objext) ./simple-object-coff.$(objext) \ ./simple-object-elf.$(objext) ./simple-object-mach-o.$(objext) \ @@ -1200,6 +1202,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir else true; fi $(COMPILE.c) $(srcdir)/rust-demangle.c $(OUTPUT_OPTION) +./msvc-demangle.$(objext): $(srcdir)/msvc-demangle.cpp + if [ x"$(PICFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(srcdir)/msvc-demangle.cpp -o pic/$@; \ + else true; fi + if [ x"$(NOASANFLAG)" != x ]; then \ + $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/msvc-demangle.cpp -o noasan/$@; \ + else true; fi + $(COMPILE.c) $(srcdir)/msvc-demangle.cpp $(OUTPUT_OPTION) + ./safe-ctype.$(objext): $(srcdir)/safe-ctype.c $(INCDIR)/ansidecl.h \ $(INCDIR)/safe-ctype.h if [ x"$(PICFLAG)" != x ]; then \ diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index a39e2bf..3ddfa3e 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -53,6 +53,7 @@ void * realloc (); #include "libiberty.h" #include "rust-demangle.h" +#include "msvc-demangle.h" enum demangling_styles current_demangling_style = auto_demangling; @@ -100,6 +101,12 @@ const struct demangler_engine libiberty_demanglers[] = "Rust style demangling" } , + { + MSVC_DEMANGLING_STYLE_STRING, + msvc_demangling, + "MSVC style demangling" + } + , { NULL, unknown_demangling, NULL } @@ -161,8 +168,12 @@ cplus_demangle (const char *mangled, int options) options |= (int) current_demangling_style & DMGL_STYLE_MASK; /* The V3 ABI demangling is implemented elsewhere. */ - if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING) + if (GNU_V3_DEMANGLING || RUST_DEMANGLING || MSVC_DEMANGLING || AUTO_DEMANGLING) { + ret = msvc_demangle (mangled, options); + if (ret) + return ret; + ret = cplus_demangle_v3 (mangled, options); if (GNU_V3_DEMANGLING) return ret; diff --git a/libiberty/msvc-demangle.cpp b/libiberty/msvc-demangle.cpp new file mode 100644 index 0000000..9e2b499 --- /dev/null +++ b/libiberty/msvc-demangle.cpp @@ -0,0 +1,26 @@ +#define HAVE_DECL_BASENAME 1 +#include "demangle.h" + +#include + +#include + +extern "C" +char* msvc_demangle(const char* sym, int options) +{ + auto suffix = std::strchr(sym, '!'); + if (suffix != 0) + { + sym = suffix + 1; + } + + auto flags = llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention); + if (!(options & DMGL_ANSI)) { + /* TODO: Wait for LLVM's demangler to get a flag for this */; + } + if (!(options & DMGL_PARAMS)) { + /* TODO: Wait for LLVM's demangler to get a flag for this */; + } + + return llvm::microsoftDemangle(sym, nullptr, nullptr, nullptr, flags); +} diff --git a/libiberty/msvc-demangle.h b/libiberty/msvc-demangle.h new file mode 100644 index 0000000..cffec0a --- /dev/null +++ b/libiberty/msvc-demangle.h @@ -0,0 +1,6 @@ +#ifdef __cplusplus +extern "C" +#else +extern +#endif +char* msvc_demangle(const char* sym, int options);