mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2025-12-28 02:05:04 +01:00
Initial support for dumping DWARF corresponding to Swift code
The DWARF data for Swift code has a top-level DW_TAG_module DIE as the child of the DW_TAG_compile_unit DIE and the parent of the DW_TAG_subprogram DIEs that dump_syms uses to locate functions. dump_syms needs to process DW_TAG_module DIEs as introducing nested scopes to make it work with Swift. This also reworks demangling to be language-specific, so that the C++ demangler isn't invoked when processing Swift code. The DWARF data for Swift code presents its mangled names in the same form as used for C++ (DW_AT_MIPS_linkage_name or DW_AT_linkage_name) but the mangling is Swift-specific (beginning with _T instead of _Z). There is no programmatic interface to a Swift name demangler as an analogue to C++'s __cxa_demangle(), so mangled Swift names are exposed as-is. Xcode's "xcrun swift-demangle" can be used to post-process these mangled Swift names on macOS. Support for mangled names presented in a DW_AT_linkage_name attribute, as used by DWARF 4, is added. This supersedes the earlier use of DW_AT_MIPS_linkage_name. BUG=google-breakpad:702,google-breakpad:715 R=ted.mielczarek@gmail.com Review URL: https://codereview.chromium.org/2147523005 .
This commit is contained in:
parent
138886803c
commit
7398ce15b7
6 changed files with 130 additions and 33 deletions
|
|
@ -34,18 +34,66 @@
|
|||
|
||||
#include "common/language.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace {
|
||||
|
||||
string MakeQualifiedNameWithSeparator(const string& parent_name,
|
||||
const char* separator,
|
||||
const string& name) {
|
||||
if (parent_name.empty()) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return parent_name + separator + name;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
// C++ language-specific operations.
|
||||
class CPPLanguage: public Language {
|
||||
public:
|
||||
CPPLanguage() {}
|
||||
|
||||
string MakeQualifiedName(const string &parent_name,
|
||||
const string &name) const {
|
||||
if (parent_name.empty())
|
||||
return name;
|
||||
else
|
||||
return parent_name + "::" + name;
|
||||
return MakeQualifiedNameWithSeparator(parent_name, "::", name);
|
||||
}
|
||||
|
||||
virtual DemangleResult DemangleName(const string& mangled,
|
||||
std::string* demangled) const {
|
||||
#if defined(__ANDROID__)
|
||||
// Android NDK doesn't provide abi::__cxa_demangle.
|
||||
demangled->clear();
|
||||
return kDontDemangle;
|
||||
#else
|
||||
int status;
|
||||
char* demangled_c =
|
||||
abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status);
|
||||
|
||||
DemangleResult result;
|
||||
if (status == 0) {
|
||||
result = kDemangleSuccess;
|
||||
demangled->clear();
|
||||
} else {
|
||||
result = kDemangleFailure;
|
||||
demangled->assign(demangled_c);
|
||||
}
|
||||
|
||||
if (demangled_c) {
|
||||
free(reinterpret_cast<void*>(demangled_c));
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -54,19 +102,45 @@ CPPLanguage CPPLanguageSingleton;
|
|||
// Java language-specific operations.
|
||||
class JavaLanguage: public Language {
|
||||
public:
|
||||
JavaLanguage() {}
|
||||
|
||||
string MakeQualifiedName(const string &parent_name,
|
||||
const string &name) const {
|
||||
if (parent_name.empty())
|
||||
return name;
|
||||
else
|
||||
return parent_name + "." + name;
|
||||
return MakeQualifiedNameWithSeparator(parent_name, ".", name);
|
||||
}
|
||||
};
|
||||
|
||||
JavaLanguage JavaLanguageSingleton;
|
||||
|
||||
// Swift language-specific operations.
|
||||
class SwiftLanguage: public Language {
|
||||
public:
|
||||
SwiftLanguage() {}
|
||||
|
||||
string MakeQualifiedName(const string &parent_name,
|
||||
const string &name) const {
|
||||
return MakeQualifiedNameWithSeparator(parent_name, ".", name);
|
||||
}
|
||||
|
||||
virtual DemangleResult DemangleName(const string& mangled,
|
||||
std::string* demangled) const {
|
||||
// There is no programmatic interface to a Swift demangler. Pass through the
|
||||
// mangled form because it encodes more information than the qualified name
|
||||
// that would have been built by MakeQualifiedName(). The output can be
|
||||
// post-processed by xcrun swift-demangle to transform mangled Swift names
|
||||
// into something more readable.
|
||||
demangled->assign(mangled);
|
||||
return kDemangleSuccess;
|
||||
}
|
||||
};
|
||||
|
||||
SwiftLanguage SwiftLanguageSingleton;
|
||||
|
||||
// Assembler language-specific operations.
|
||||
class AssemblerLanguage: public Language {
|
||||
public:
|
||||
AssemblerLanguage() {}
|
||||
|
||||
bool HasFunctions() const { return false; }
|
||||
string MakeQualifiedName(const string &parent_name,
|
||||
const string &name) const {
|
||||
|
|
@ -78,6 +152,7 @@ AssemblerLanguage AssemblerLanguageSingleton;
|
|||
|
||||
const Language * const Language::CPlusPlus = &CPPLanguageSingleton;
|
||||
const Language * const Language::Java = &JavaLanguageSingleton;
|
||||
const Language * const Language::Swift = &SwiftLanguageSingleton;
|
||||
const Language * const Language::Assembler = &AssemblerLanguageSingleton;
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue