diff --git a/CMakeLists.txt b/CMakeLists.txt index 55482e00..fe42832c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,6 @@ if(NOT absl_FOUND) set(BUILD_TESTING "${BLOATY_BUILD_TESTING_SAVE}") endif() -add_definitions(-D_LIBCXXABI_FUNC_VIS=) # For Demumble. if(BLOATY_ENABLE_RE2) add_definitions(-DUSE_RE2) endif() @@ -190,6 +189,9 @@ if(NOT absl_FOUND) endif() include_directories("${CMAKE_CURRENT_BINARY_DIR}/src") +include_directories(third_party/demumble/third_party/llvm/include) +include_directories(third_party/demumble/third_party/swift/include) + # Baseline build flags. if(MSVC) set(CMAKE_CXX_FLAGS "/EHsc /wd4018 /D_CRT_SECURE_NO_WARNINGS /DNOMINMAX") @@ -198,9 +200,23 @@ else() set(CMAKE_CXX_FLAGS_DEBUG "-g1") set(CMAKE_CXX_FLAGS_RELEASE "-O2") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g1") - set_source_files_properties(third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough) + set_source_files_properties(third_party/demumble/third_party/llvm/lib/Demangle/MicrosoftDemangle.cpp + third_party/demumble/third_party/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp + third_party/demumble/third_party/swift/lib/Demangling/Demangler.cpp + third_party/demumble/third_party/swift/lib/Demangling/Errors.cpp + third_party/demumble/third_party/swift/lib/Demangling/NodePrinter.cpp + third_party/demumble/third_party/swift/lib/Demangling/OldDemangler.cpp + third_party/demumble/third_party/swift/lib/Demangling/OldRemangler.cpp + third_party/demumble/third_party/swift/lib/Demangling/Remangler.cpp + PROPERTIES COMPILE_FLAGS -Wno-unused-parameter) endif() +add_definitions( + -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1 + -DSWIFT_STDLIB_HAS_TYPE_PRINTING=1 + -DSWIFT_SUPPORT_OLD_MANGLING=1 +) + if(APPLE) elseif(UNIX) if(BLOATY_ENABLE_BUILDID) @@ -276,8 +292,27 @@ add_library(libbloaty STATIC src/util.cc src/util.h src/webassembly.cc - # One source file, no special build system needed. - third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp + + # Demumble has an open issue build as a library. + # See https://github.com/nico/demumble/issues/39 + + third_party/demumble/third_party/llvm/lib/Demangle/Demangle.cpp + third_party/demumble/third_party/llvm/lib/Demangle/DLangDemangle.cpp + third_party/demumble/third_party/llvm/lib/Demangle/ItaniumDemangle.cpp + third_party/demumble/third_party/llvm/lib/Demangle/MicrosoftDemangle.cpp + third_party/demumble/third_party/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp + third_party/demumble/third_party/llvm/lib/Demangle/RustDemangle.cpp + third_party/demumble/third_party/swift/lib/Demangling/Context.cpp + third_party/demumble/third_party/swift/lib/Demangling/CrashReporter.cpp + third_party/demumble/third_party/swift/lib/Demangling/Demangler.cpp + third_party/demumble/third_party/swift/lib/Demangling/Errors.cpp + third_party/demumble/third_party/swift/lib/Demangling/ManglingUtils.cpp + third_party/demumble/third_party/swift/lib/Demangling/NodeDumper.cpp + third_party/demumble/third_party/swift/lib/Demangling/NodePrinter.cpp + third_party/demumble/third_party/swift/lib/Demangling/OldDemangler.cpp + third_party/demumble/third_party/swift/lib/Demangling/OldRemangler.cpp + third_party/demumble/third_party/swift/lib/Demangling/Punycode.cpp + third_party/demumble/third_party/swift/lib/Demangling/Remangler.cpp ) set_property(TARGET libbloaty PROPERTY FOLDER "bloaty") diff --git a/src/bloaty.cc b/src/bloaty.cc index f9fe9732..37bf27d8 100644 --- a/src/bloaty.cc +++ b/src/bloaty.cc @@ -60,7 +60,9 @@ typedef size_t z_size_t; #include "bloaty.pb.h" #include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/text_format.h" +#include "llvm/Demangle/Demangle.h" #include "re.h" +#include "swift/Demangling/Demangle.h" #include "util.h" using std::string_view; @@ -162,9 +164,6 @@ static std::string CSVEscape(string_view str) { } } -extern "C" char* __cxa_demangle(const char* mangled_name, char* buf, size_t* n, - int* status); - std::string ItaniumDemangle(string_view symbol, DataSource source) { if (source != DataSource::kShortSymbols && source != DataSource::kFullSymbols) { @@ -182,15 +181,41 @@ std::string ItaniumDemangle(string_view symbol, DataSource source) { if (absl::debugging_internal::Demangle(demangle_from.data(), demangled, sizeof(demangled))) { return std::string(demangled); + } else if (char* ms = llvm::microsoftDemangle( + demangle_from, NULL, NULL, + llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier | + llvm::MSDF_NoCallingConvention | + llvm::MSDF_NoMemberType | + llvm::MSDF_NoReturnType))) { + std::string ret(ms); + free(ms); + return ret; + } else if (swift::Demangle::isSwiftSymbol(demangle_from)) { + auto Opts = + swift::Demangle::DemangleOptions::SimplifiedUIDemangleOptions(); + std::string swift = + swift::Demangle::demangleSymbolAsString(demangle_from, Opts); + return swift; } else { return std::string(symbol); } } else if (source == DataSource::kFullSymbols) { - char* demangled = __cxa_demangle(demangle_from.data(), NULL, NULL, NULL); - if (demangled) { - std::string ret(demangled); - free(demangled); + if (char* itanium = llvm::itaniumDemangle(demangle_from)) { + std::string ret(itanium); + free(itanium); + return ret; + } else if (char* ms = llvm::microsoftDemangle(demangle_from, NULL, NULL)) { + std::string ret(ms); + free(ms); + return ret; + } else if (char* rust = llvm::rustDemangle(demangle_from)) { + std::string ret(rust); + free(rust); return ret; + } else if (swift::Demangle::isSwiftSymbol(demangle_from)) { + swift::Demangle::DemangleOptions options; + options.SynthesizeSugarOnTypes = true; + return swift::Demangle::demangleSymbolAsString(demangle_from, options); } else { return std::string(symbol); } diff --git a/tests/elf/demangle-multi.test b/tests/elf/demangle-multi.test new file mode 100644 index 00000000..c251fc15 --- /dev/null +++ b/tests/elf/demangle-multi.test @@ -0,0 +1,50 @@ +# Test that bloaty can demangle Swift, Rust, Microsoft, and complex C++ symbols using demumble + +# RUN: %yaml2obj %s -o %t.obj +# RUN: %bloaty %t.obj -d fullsymbols | %FileCheck %s --check-prefix=FULL +# RUN: %bloaty %t.obj -d shortsymbols | %FileCheck %s --check-prefix=SHORT + +# FULL-DAG: test.hello() -> () +# FULL-DAG: foo::bar::<> +# FULL-DAG: void __cdecl test(void) +# FULL-DAG: __llvm_libc_21_0_0_git::cpp::enable_if && FPBits<_Float16>::FRACTION_LEN < 64ul, _Float16>::type __llvm_libc_21_0_0_git::fputil::DyadicFloat<64ul>::generic_as<_Float16, true>() const + +# SHORT-DAG: hello() +# SHORT-DAG: foo::bar::<> +# SHORT-DAG: test(void) +# SHORT-DAG: __llvm_libc_21_0_0_git::fputil::DyadicFloat<>::generic_as<>() + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: '90909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090' +Symbols: + - Name: _$s4test5helloyyF + Type: STT_FUNC + Section: .text + Value: 0x0 + Size: 0x10 + - Name: _RINvC3foo3barE + Type: STT_FUNC + Section: .text + Value: 0x10 + Size: 0x10 + - Name: '?test@@YAXXZ' + Type: STT_FUNC + Section: .text + Value: 0x20 + Size: 0x10 + - Name: _ZNK22__llvm_libc_21_0_0_git6fputil11DyadicFloatILm64EE10generic_asIDF16_Lb1EEENS_3cpp9enable_ifIXaasr3cppE19is_floating_point_vIT_Eltsr6FPBitsIS6_EE12FRACTION_LENLm64EES6_E4typeEv + Type: STT_FUNC + Section: .text + Value: 0x30 + Size: 0x10 +... diff --git a/third_party/demumble b/third_party/demumble index 01098eab..10e00fb7 160000 --- a/third_party/demumble +++ b/third_party/demumble @@ -1 +1 @@ -Subproject commit 01098eab821b33bd31b9778aea38565cd796aa85 +Subproject commit 10e00fb708a3d24c1bb16682cac76925ffb76af5