Author: Nico Weber Date: 2020-05-20T16:17:31-04:00 New Revision: bc1c3655bfd67a0b4ccece465729c39d769e9707
URL: https://github.com/llvm/llvm-project/commit/bc1c3655bfd67a0b4ccece465729c39d769e9707 DIFF: https://github.com/llvm/llvm-project/commit/bc1c3655bfd67a0b4ccece465729c39d769e9707.diff LOG: Give microsoftDemangle() an outparam for how many input bytes were consumed. Demangling Itanium symbols either consumes the whole input or fails, but Microsoft symbols can be successfully demangled with just some of the input. Add an outparam that enables clients to know how much of the input was consumed, and use this flag to give llvm-undname an opt-in warning on partially consumed symbols. Differential Revision: https://reviews.llvm.org/D80173 Added: llvm/test/Demangle/warn-trailing.test Modified: lldb/source/Core/Mangled.cpp llvm/include/llvm/Demangle/Demangle.h llvm/lib/DebugInfo/Symbolize/Symbolize.cpp llvm/lib/Demangle/Demangle.cpp llvm/lib/Demangle/MicrosoftDemangle.cpp llvm/tools/llvm-microsoft-demangle-fuzzer/llvm-microsoft-demangle-fuzzer.cpp llvm/tools/llvm-objdump/COFFDump.cpp llvm/tools/llvm-undname/llvm-undname.cpp Removed: ################################################################################ diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp index b44cbeb4fec9..56914ae117dd 100644 --- a/lldb/source/Core/Mangled.cpp +++ b/lldb/source/Core/Mangled.cpp @@ -181,7 +181,7 @@ void Mangled::SetValue(ConstString name) { // Local helpers for diff erent 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 index 7b85b9a9ccf7..b4006a067d10 100644 --- a/llvm/include/llvm/Demangle/Demangle.h +++ b/llvm/include/llvm/Demangle/Demangle.h @@ -40,7 +40,21 @@ enum MSDemangleFlags { 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 diff erent demangling schemes. diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index ff017b078019..b055230588df 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -624,7 +624,7 @@ LLVMSymbolizer::DemangleName(const std::string &Name, // 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 index 5f921537b9bd..71dafa0b2e43 100644 --- a/llvm/lib/Demangle/Demangle.cpp +++ b/llvm/lib/Demangle/Demangle.cpp @@ -24,8 +24,8 @@ std::string llvm::demangle(const std::string &MangledName) { 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 index c681d6e25b87..16074314a84d 100644 --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -2334,14 +2334,16 @@ void Demangler::dumpBackReferences() { 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 @@ char *llvm::microsoftDemangle(const char *MangledName, char *Buf, size_t *N, 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 index 000000000000..6219e44cdc69 --- /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 index 2aa4d8dca27b..64dd483789d2 100644 --- 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 index 1e817d8645de..c829b496f6c3 100644 --- a/llvm/tools/llvm-objdump/COFFDump.cpp +++ b/llvm/tools/llvm-objdump/COFFDump.cpp @@ -679,11 +679,9 @@ void objdump::printCOFFSymbolTable(const COFFObjectFile *coff) { << "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 index 7c3682510f64..f9f9e0537e9e 100644 --- a/llvm/tools/llvm-undname/llvm-undname.cpp +++ b/llvm/tools/llvm-undname/llvm-undname.cpp @@ -45,6 +45,9 @@ cl::opt<bool> NoMemberType("no-member-type", cl::Optional, cl::init(false)); cl::opt<std::string> RawFile("raw-file", cl::Optional, cl::desc("for fuzzer data"), cl::Hidden); +cl::opt<bool> WarnTrailing("warn-trailing", cl::Optional, + cl::desc("warn on trailing characters"), cl::Hidden, + cl::init(false)); cl::list<std::string> Symbols(cl::Positional, cl::desc("<input symbols>"), cl::ZeroOrMore); @@ -62,11 +65,15 @@ static bool msDemangle(const std::string &S) { 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"; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits