aboutsummaryrefslogtreecommitdiffstats
path: root/source/Plugins/ObjectFile/Breakpad
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
commitead246455adf1a215ec2715dad6533073a6beb4e (patch)
treef3f97a47d77053bf96fe74cdbd6fae74380e8a92 /source/Plugins/ObjectFile/Breakpad
parentfdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff)
downloadsrc-vendor/lldb.tar.gz
src-vendor/lldb.zip
Vendor import of stripped lldb trunk r375505, the last commit before thevendor/lldb/lldb-trunk-r375505vendor/lldb
upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/lldb/trunk@375505
Notes
Notes: svn path=/vendor/lldb/dist/; revision=353952 svn path=/vendor/lldb/lldb-r375505/; revision=353953; tag=vendor/lldb/lldb-trunk-r375505
Diffstat (limited to 'source/Plugins/ObjectFile/Breakpad')
-rw-r--r--source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp98
-rw-r--r--source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h25
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp4
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h9
4 files changed, 129 insertions, 7 deletions
diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index d489eaf11115..de17d986a860 100644
--- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -16,7 +16,19 @@ using namespace lldb_private;
using namespace lldb_private::breakpad;
namespace {
-enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack, CFI, Init };
+enum class Token {
+ Unknown,
+ Module,
+ Info,
+ CodeID,
+ File,
+ Func,
+ Public,
+ Stack,
+ CFI,
+ Init,
+ Win,
+};
}
template<typename T>
@@ -33,6 +45,7 @@ template <> Token stringTo<Token>(llvm::StringRef Str) {
.Case("STACK", Token::Stack)
.Case("CFI", Token::CFI)
.Case("INIT", Token::Init)
+ .Case("WIN", Token::Win)
.Default(Token::Unknown);
}
@@ -127,6 +140,8 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
switch (Tok) {
case Token::CFI:
return Record::StackCFI;
+ case Token::Win:
+ return Record::StackWin;
default:
return llvm::None;
}
@@ -134,13 +149,13 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
case Token::Unknown:
// Optimistically assume that any unrecognised token means this is a line
// record, those don't have a special keyword and start directly with a
- // hex number. CODE_ID should never be at the start of a line, but if it
- // is, it can be treated the same way as a garbled line record.
+ // hex number.
return Record::Line;
case Token::CodeID:
case Token::CFI:
case Token::Init:
+ case Token::Win:
// These should never appear at the start of a valid record.
return llvm::None;
}
@@ -390,6 +405,81 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
return OS << " " << R.UnwindRules;
}
+llvm::Optional<StackWinRecord> StackWinRecord::parse(llvm::StringRef Line) {
+ // STACK WIN type rva code_size prologue_size epilogue_size parameter_size
+ // saved_register_size local_size max_stack_size has_program_string
+ // program_string_OR_allocates_base_pointer
+
+ if (consume<Token>(Line) != Token::Stack)
+ return llvm::None;
+ if (consume<Token>(Line) != Token::Win)
+ return llvm::None;
+
+ llvm::StringRef Str;
+ uint8_t Type;
+ std::tie(Str, Line) = getToken(Line);
+ // Right now we only support the "FrameData" frame type.
+ if (!to_integer(Str, Type) || FrameType(Type) != FrameType::FrameData)
+ return llvm::None;
+
+ lldb::addr_t RVA;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, RVA, 16))
+ return llvm::None;
+
+ lldb::addr_t CodeSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, CodeSize, 16))
+ return llvm::None;
+
+ // Skip fields which we aren't using right now.
+ std::tie(Str, Line) = getToken(Line); // prologue_size
+ std::tie(Str, Line) = getToken(Line); // epilogue_size
+
+ lldb::addr_t ParameterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, ParameterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t SavedRegisterSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, SavedRegisterSize, 16))
+ return llvm::None;
+
+ lldb::addr_t LocalSize;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, LocalSize, 16))
+ return llvm::None;
+
+ std::tie(Str, Line) = getToken(Line); // max_stack_size
+
+ uint8_t HasProgramString;
+ std::tie(Str, Line) = getToken(Line);
+ if (!to_integer(Str, HasProgramString))
+ return llvm::None;
+ // FrameData records should always have a program string.
+ if (!HasProgramString)
+ return llvm::None;
+
+ return StackWinRecord(RVA, CodeSize, ParameterSize, SavedRegisterSize,
+ LocalSize, Line.trim());
+}
+
+bool breakpad::operator==(const StackWinRecord &L, const StackWinRecord &R) {
+ return L.RVA == R.RVA && L.CodeSize == R.CodeSize &&
+ L.ParameterSize == R.ParameterSize &&
+ L.SavedRegisterSize == R.SavedRegisterSize &&
+ L.LocalSize == R.LocalSize && L.ProgramString == R.ProgramString;
+}
+
+llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
+ const StackWinRecord &R) {
+ return OS << llvm::formatv(
+ "STACK WIN 4 {0:x-} {1:x-} ? ? {2} {3} {4} ? 1 {5}", R.RVA,
+ R.CodeSize, R.ParameterSize, R.SavedRegisterSize, R.LocalSize,
+ R.ProgramString);
+}
+
llvm::StringRef breakpad::toString(Record::Kind K) {
switch (K) {
case Record::Module:
@@ -406,6 +496,8 @@ llvm::StringRef breakpad::toString(Record::Kind K) {
return "PUBLIC";
case Record::StackCFI:
return "STACK CFI";
+ case Record::StackWin:
+ return "STACK WIN";
}
llvm_unreachable("Unknown record kind!");
}
diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
index 5d5cdb319c10..27bef975125d 100644
--- a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
+++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
@@ -20,7 +20,7 @@ namespace breakpad {
class Record {
public:
- enum Kind { Module, Info, File, Func, Line, Public, StackCFI };
+ enum Kind { Module, Info, File, Func, Line, Public, StackCFI, StackWin };
/// Attempt to guess the kind of the record present in the argument without
/// doing a full parse. The returned kind will always be correct for valid
@@ -157,6 +157,29 @@ public:
bool operator==(const StackCFIRecord &L, const StackCFIRecord &R);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R);
+class StackWinRecord : public Record {
+public:
+ static llvm::Optional<StackWinRecord> parse(llvm::StringRef Line);
+
+ StackWinRecord(lldb::addr_t RVA, lldb::addr_t CodeSize,
+ lldb::addr_t ParameterSize, lldb::addr_t SavedRegisterSize,
+ lldb::addr_t LocalSize, llvm::StringRef ProgramString)
+ : Record(StackWin), RVA(RVA), CodeSize(CodeSize),
+ ParameterSize(ParameterSize), SavedRegisterSize(SavedRegisterSize),
+ LocalSize(LocalSize), ProgramString(ProgramString) {}
+
+ enum class FrameType : uint8_t { FPO = 0, FrameData = 4 };
+ lldb::addr_t RVA;
+ lldb::addr_t CodeSize;
+ lldb::addr_t ParameterSize;
+ lldb::addr_t SavedRegisterSize;
+ lldb::addr_t LocalSize;
+ llvm::StringRef ProgramString;
+};
+
+bool operator==(const StackWinRecord &L, const StackWinRecord &R);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackWinRecord &R);
+
} // namespace breakpad
} // namespace lldb_private
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index 60dd9f9cecf0..3b9e0e2092a9 100644
--- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -42,6 +42,8 @@ llvm::Optional<Header> Header::parse(llvm::StringRef text) {
return Header{ArchSpec(triple), std::move(uuid)};
}
+char ObjectFileBreakpad::ID;
+
void ObjectFileBreakpad::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance,
@@ -125,7 +127,7 @@ Symtab *ObjectFileBreakpad::GetSymtab() {
void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
- m_sections_up = llvm::make_unique<SectionList>();
+ m_sections_up = std::make_unique<SectionList>();
llvm::Optional<Record::Kind> current_section;
offset_t section_start;
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index e8885e0cc898..cb4bba01fb71 100644
--- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -48,6 +48,13 @@ public:
uint32_t GetPluginVersion() override { return 1; }
+ // LLVM RTTI support
+ static char ID;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || ObjectFile::isA(ClassID);
+ }
+ static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
// ObjectFile Protocol.
bool ParseHeader() override;
@@ -78,8 +85,6 @@ public:
UUID GetUUID() override { return m_uuid; }
- FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); }
-
uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
Type CalculateType() override { return eTypeDebugInfo; }