diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp --- a/lldb/source/Core/Mangled.cpp +++ b/lldb/source/Core/Mangled.cpp @@ -181,7 +181,7 @@ // Local helpers for different demangling implementations. static char *GetMSVCDemangledStr(const char *M) { char *demangled_cstr = llvm::microsoftDemangle( - M, nullptr, nullptr, nullptr, + M, nullptr, nullptr, nullptr, nullptr, llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention | llvm::MSDF_NoMemberType)); diff --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h --- a/llvm/include/llvm/Demangle/Demangle.h +++ b/llvm/include/llvm/Demangle/Demangle.h @@ -40,7 +40,21 @@ MSDF_NoReturnType = 1 << 3, MSDF_NoMemberType = 1 << 4, }; -char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n, + +/// Demangles the Microsoft symbol pointed at by mangled_name and returns it. +/// Returns a pointer to the start of a null-terminated demangled string on +/// success, or nullptr on error. +/// If n_read is non-null and demangling was successful, it receives how many +/// bytes of the input string were consumed. +/// buf can point to a *n_buf bytes large buffer where the demangled name is +/// stored. If the buffer is too small, it is grown with realloc(). If buf is +/// nullptr, then this malloc()s memory for the result. +/// *n_buf stores the size of buf on input if buf is non-nullptr, and it +/// receives the size of the demangled string on output if n_buf is not nullptr. +/// status receives one of the demangle_ enum entries above if it's not nullptr. +/// Flags controls various details of the demangled representation. +char *microsoftDemangle(const char *mangled_name, size_t *n_read, + char *buf, size_t *n_buf, int *status, MSDemangleFlags Flags = MSDF_None); /// Attempt to demangle a string using different demangling schemes. diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -624,7 +624,7 @@ // Only do MSVC C++ demangling on symbols starting with '?'. int status = 0; char *DemangledName = microsoftDemangle( - Name.c_str(), nullptr, nullptr, &status, + Name.c_str(), nullptr, nullptr, nullptr, &status, MSDemangleFlags(MSDF_NoAccessSpecifier | MSDF_NoCallingConvention | MSDF_NoMemberType | MSDF_NoReturnType)); if (status != 0) diff --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp --- a/llvm/lib/Demangle/Demangle.cpp +++ b/llvm/lib/Demangle/Demangle.cpp @@ -24,8 +24,8 @@ if (isItaniumEncoding(MangledName)) Demangled = itaniumDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); else - Demangled = - microsoftDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); + Demangled = microsoftDemangle(MangledName.c_str(), nullptr, nullptr, + nullptr, nullptr); if (!Demangled) return MangledName; diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -2334,14 +2334,16 @@ std::printf("\n"); } -char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N, +char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled, + char *Buf, size_t *N, int *Status, MSDemangleFlags Flags) { - int InternalStatus = demangle_success; Demangler D; OutputStream S; StringView Name{MangledName}; SymbolNode *AST = D.parse(Name); + if (!D.Error && NMangled) + *NMangled = Name.begin() - MangledName; if (Flags & MSDF_DumpBackrefs) D.dumpBackReferences(); @@ -2356,6 +2358,7 @@ if (Flags & MSDF_NoMemberType) OF = OutputFlags(OF | OF_NoMemberType); + int InternalStatus = demangle_success; if (D.Error) InternalStatus = demangle_invalid_mangled_name; else if (!initializeOutputStream(Buf, N, S, 1024)) diff --git a/llvm/test/Demangle/warn-trailing.test b/llvm/test/Demangle/warn-trailing.test new file mode 100644 --- /dev/null +++ b/llvm/test/Demangle/warn-trailing.test @@ -0,0 +1,6 @@ +; RUN: llvm-undname -warn-trailing 2>&1 < %s | FileCheck %s + +?x@@3HAasdf +; CHECK: ?x@@3HAasdf +; CHECK-NEXT: int x +; CHECK-NEXT: warning: trailing characters: asdf diff --git a/llvm/tools/llvm-microsoft-demangle-fuzzer/llvm-microsoft-demangle-fuzzer.cpp b/llvm/tools/llvm-microsoft-demangle-fuzzer/llvm-microsoft-demangle-fuzzer.cpp --- a/llvm/tools/llvm-microsoft-demangle-fuzzer/llvm-microsoft-demangle-fuzzer.cpp +++ b/llvm/tools/llvm-microsoft-demangle-fuzzer/llvm-microsoft-demangle-fuzzer.cpp @@ -15,6 +15,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { std::string NullTerminatedString((const char *)Data, Size); free(llvm::microsoftDemangle(NullTerminatedString.c_str(), nullptr, nullptr, - nullptr)); + nullptr, nullptr)); return 0; } diff --git a/llvm/tools/llvm-objdump/COFFDump.cpp b/llvm/tools/llvm-objdump/COFFDump.cpp --- a/llvm/tools/llvm-objdump/COFFDump.cpp +++ b/llvm/tools/llvm-objdump/COFFDump.cpp @@ -679,11 +679,9 @@ << "0x" << format("%08x", unsigned(Symbol->getValue())) << " " << Name; if (Demangle && Name.startswith("?")) { - char *DemangledSymbol = nullptr; - size_t Size = 0; int Status = -1; - DemangledSymbol = - microsoftDemangle(Name.data(), DemangledSymbol, &Size, &Status); + char *DemangledSymbol = + microsoftDemangle(Name.data(), nullptr, nullptr, nullptr, &Status); if (Status == 0 && DemangledSymbol) { outs() << " (" << StringRef(DemangledSymbol) << ")"; diff --git a/llvm/tools/llvm-undname/llvm-undname.cpp b/llvm/tools/llvm-undname/llvm-undname.cpp --- a/llvm/tools/llvm-undname/llvm-undname.cpp +++ b/llvm/tools/llvm-undname/llvm-undname.cpp @@ -45,6 +45,9 @@ cl::init(false)); cl::opt RawFile("raw-file", cl::Optional, cl::desc("for fuzzer data"), cl::Hidden); +cl::opt WarnTrailing("warn-trailing", cl::Optional, + cl::desc("warn on trailing characters"), cl::Hidden, + cl::init(false)); cl::list Symbols(cl::Positional, cl::desc(""), cl::ZeroOrMore); @@ -62,11 +65,15 @@ if (NoMemberType) Flags = MSDemangleFlags(Flags | MSDF_NoMemberType); + size_t NRead; char *ResultBuf = - microsoftDemangle(S.c_str(), nullptr, nullptr, &Status, Flags); + microsoftDemangle(S.c_str(), &NRead, nullptr, nullptr, &Status, Flags); if (Status == llvm::demangle_success) { outs() << ResultBuf << "\n"; outs().flush(); + if (WarnTrailing && NRead < S.size()) + WithColor::warning() << "trailing characters: " << S.c_str() + NRead + << "\n"; } else { WithColor::error() << "Invalid mangled name\n"; }