[llvm] bc1c365 - Give microsoftDemangle() an outparam for how many input bytes were consumed.

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Wed May 20 13:18:13 PDT 2020


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";
   }


        


More information about the llvm-commits mailing list