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 @@ -649,22 +649,29 @@ // vectorcall - foo@@12 // These are all different linkage names for 'foo'. StringRef demanglePE32ExternCFunc(StringRef SymbolName) { - // Remove any '_' or '@' prefix. char Front = SymbolName.empty() ? '\0' : SymbolName[0]; - if (Front == '_' || Front == '@') - SymbolName = SymbolName.drop_front(); // Remove any '@[0-9]+' suffix. + bool HasAtNumSuffix = false; if (Front != '?') { size_t AtPos = SymbolName.rfind('@'); if (AtPos != StringRef::npos && - all_of(drop_begin(SymbolName, AtPos + 1), isDigit)) + all_of(drop_begin(SymbolName, AtPos + 1), isDigit)) { SymbolName = SymbolName.substr(0, AtPos); + HasAtNumSuffix = true; + } } // Remove any ending '@' for vectorcall. - if (SymbolName.endswith("@")) + bool IsVectorCall = false; + if (HasAtNumSuffix && SymbolName.endswith("@")) { SymbolName = SymbolName.drop_back(); + IsVectorCall = true; + } + + // If not vectorcall, remove any '_' or '@' prefix. + if (!IsVectorCall && (Front == '_' || Front == '@')) + SymbolName = SymbolName.drop_front(); return SymbolName; } @@ -692,8 +699,14 @@ return Result; } - if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module()) - return std::string(demanglePE32ExternCFunc(Name)); + if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module()) { + std::string DemangledCName(demanglePE32ExternCFunc(Name)); + // On i386 Windows, the C name mangling for different calling conventions + // may also be applied on top of the Itanium or Rust name mangling. + if (nonMicrosoftDemangle(DemangledCName.c_str(), Result)) + return Result; + return DemangledCName; + } return Name; } diff --git a/llvm/test/DebugInfo/symbolize-demangling-mingw32.s b/llvm/test/DebugInfo/symbolize-demangling-mingw32.s new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/symbolize-demangling-mingw32.s @@ -0,0 +1,80 @@ +# REQUIRES: x86-registered-target + +# RUN: llvm-mc --filetype=obj --triple=i386-w64-windows-gnu %s -o %t.o -g + +# RUN: llvm-symbolizer --obj=%t.o 0 1 2 3 4 5 6 | FileCheck %s + + .def g + .scl 2 + .type 32 + .endef +g: + nop +# CHECK: {{^g$}} +# CHECK-NEXT: symbolize-demangling-mingw32.s:12 +# CHECK-EMPTY: + + .def baz + .scl 2 + .type 32 + .endef +baz: + nop +# CHECK-NEXT: {{^baz$}} +# CHECK-NEXT: symbolize-demangling-mingw32.s:22 +# CHECK-EMPTY: + +# void f() {} // __cdecl + .def __Z1fv + .scl 2 + .type 32 + .endef +__Z1fv: + nop +# CHECK-NEXT: {{^f\(\)$}} +# CHECK-NEXT: symbolize-demangling-mingw32.s:33 +# CHECK-EMPTY: + +# void __stdcall f1() {} + .def __Z2f1v@0 + .scl 2 + .type 32 + .endef +__Z2f1v@0: + nop +# CHECK-NEXT: {{^f1\(\)$}} +# CHECK-NEXT: symbolize-demangling-mingw32.s:44 +# CHECK-EMPTY: + +# void __fastcall f2(void) {} + .def @_Z2f2v@0 + .scl 2 + .type 32 + .endef +@_Z2f2v@0: + nop +# CHECK-NEXT: {{^f2\(\)$}} +# CHECK-NEXT: symbolize-demangling-mingw32.s:55 +# CHECK-EMPTY: + +# void __vectorcall f3(void) {} + .def _Z2f3v@@0 + .scl 2 + .type 32 + .endef +_Z2f3v@@0: + nop +# CHECK-NEXT: {{^f3\(\)$}} +# CHECK-NEXT: symbolize-demangling-mingw32.s:66 +# CHECK-EMPTY: + +# Rust + .def __RNvC1x1y + .scl 2 + .type 32 + .endef +__RNvC1x1y: + nop +# CHECK-NEXT: {{^x::y$}} +# CHECK-NEXT: symbolize-demangling-mingw32.s:77 +# CHECK-EMPTY: