diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h index 12c70b602e24..ada059cd725d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -28,7 +28,7 @@ const char *ExtractUptr(const char *str, const char *delims, uptr *result); const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter, char **result); -const char *DemangleCXXABI(const char *name); +const char *DemangleSwiftAndCXX(const char *name); // SymbolizerTool is an interface that is implemented by individual "tools" // that can perform symbolication (external llvm-symbolizer, libbacktrace, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cc index a963b75a6784..d591abca15df 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cc @@ -32,7 +32,7 @@ bool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { Dl_info info; int result = dladdr((const void *)addr, &info); if (!result) return false; - const char *demangled = DemangleCXXABI(info.dli_sname); + const char *demangled = DemangleSwiftAndCXX(info.dli_sname); stack->info.function = demangled ? internal_strdup(demangled) : nullptr; return true; } @@ -41,7 +41,7 @@ bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) { Dl_info info; int result = dladdr((const void *)addr, &info); if (!result) return false; - const char *demangled = DemangleCXXABI(info.dli_sname); + const char *demangled = DemangleSwiftAndCXX(info.dli_sname); datainfo->name = internal_strdup(demangled); datainfo->start = (uptr)info.dli_saddr; return true; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc index 7de3dbd0890f..2abfc25bd01f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -26,6 +26,7 @@ #include "sanitizer_symbolizer_libbacktrace.h" #include "sanitizer_symbolizer_mac.h" +#include // for dlsym() #include #include #include @@ -61,6 +62,38 @@ const char *DemangleCXXABI(const char *name) { return name; } +// Attempts to demangle a Swift name. The demangler will return nullptr +/// if a non-Swift name is passed in. +const char *DemangleSwift(const char *name) { + // Not to call dlsym every time we demangle, check if we are dealing with + // Swift mangled name first. + if (name[0] != '_' || name[1] != 'T') { + return nullptr; + } + + // As of now, there are no headers for the Swift runtime. Once they are + // present, we will weakly link since we do not require Swift runtime to be + // linked. + typedef char *(*swift_demangle_ft)(const char *mangledName, + size_t mangledNameLength, + char *outputBuffer, + size_t *outputBufferSize, + uint32_t flags); + swift_demangle_ft swift_demangle_f = + (swift_demangle_ft) dlsym(RTLD_DEFAULT, "swift_demangle"); + if (swift_demangle_f) + return swift_demangle_f(name, internal_strlen(name), 0, 0, 0); + + return nullptr; +} + +const char *DemangleSwiftAndCXX(const char *name) { + CHECK(name); + if (const char *swift_demangled_name = DemangleSwift(name)) + return swift_demangled_name; + return DemangleCXXABI(name); +} + bool SymbolizerProcess::StartSymbolizerSubprocess() { if (!FileExists(path_)) { if (!reported_invalid_path_) { @@ -364,7 +397,7 @@ class InternalSymbolizer : public SymbolizerTool { #endif // SANITIZER_SUPPORTS_WEAK_HOOKS const char *Symbolizer::PlatformDemangle(const char *name) { - return DemangleCXXABI(name); + return DemangleSwiftAndCXX(name); } void Symbolizer::PlatformPrepareForSandboxing() {} diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc index 429ac591e502..8ff8bbb6cb33 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc @@ -55,4 +55,14 @@ TEST(Symbolizer, ExtractTokenUpToDelimiter) { InternalFree(token); } +TEST(Symbolizer, DemangleSwiftAndCXX) { + // Swift names are not demangled in default llvm build because Swift + // runtime is not linked in. + EXPECT_STREQ("_TtSd", DemangleSwiftAndCXX("_TtSd")); + // Check that the rest demangles properly. + EXPECT_STREQ("f1(char*, int)", DemangleSwiftAndCXX("_Z2f1Pci")); + EXPECT_STREQ("foo", DemangleSwiftAndCXX("foo")); + EXPECT_STREQ("", DemangleSwiftAndCXX("")); +} + } // namespace __sanitizer