summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectFile
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ObjectFile')
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp83
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h4
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp5
3 files changed, 58 insertions, 34 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index 511b984261b..6807563b86c 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -16,11 +16,14 @@ using namespace lldb_private;
using namespace lldb_private::breakpad;
namespace {
-enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack };
+enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack, CFI, Init };
}
-static Token toToken(llvm::StringRef str) {
- return llvm::StringSwitch<Token>(str)
+template<typename T>
+static T stringTo(llvm::StringRef Str);
+
+template <> Token stringTo<Token>(llvm::StringRef Str) {
+ return llvm::StringSwitch<Token>(Str)
.Case("MODULE", Token::Module)
.Case("INFO", Token::Info)
.Case("CODE_ID", Token::CodeID)
@@ -28,21 +31,25 @@ static Token toToken(llvm::StringRef str) {
.Case("FUNC", Token::Func)
.Case("PUBLIC", Token::Public)
.Case("STACK", Token::Stack)
+ .Case("CFI", Token::CFI)
+ .Case("INIT", Token::Init)
.Default(Token::Unknown);
}
-static llvm::Triple::OSType toOS(llvm::StringRef str) {
+template <>
+llvm::Triple::OSType stringTo<llvm::Triple::OSType>(llvm::StringRef Str) {
using llvm::Triple;
- return llvm::StringSwitch<Triple::OSType>(str)
+ return llvm::StringSwitch<Triple::OSType>(Str)
.Case("Linux", Triple::Linux)
.Case("mac", Triple::MacOSX)
.Case("windows", Triple::Win32)
.Default(Triple::UnknownOS);
}
-static llvm::Triple::ArchType toArch(llvm::StringRef str) {
+template <>
+llvm::Triple::ArchType stringTo<llvm::Triple::ArchType>(llvm::StringRef Str) {
using llvm::Triple;
- return llvm::StringSwitch<Triple::ArchType>(str)
+ return llvm::StringSwitch<Triple::ArchType>(Str)
.Case("arm", Triple::arm)
.Case("arm64", Triple::aarch64)
.Case("mips", Triple::mips)
@@ -56,6 +63,13 @@ static llvm::Triple::ArchType toArch(llvm::StringRef str) {
.Default(Triple::UnknownArch);
}
+template<typename T>
+static T consume(llvm::StringRef &Str) {
+ llvm::StringRef Token;
+ std::tie(Token, Str) = getToken(Str);
+ return stringTo<T>(Token);
+}
+
/// Return the number of hex digits needed to encode an (POD) object of a given
/// type.
template <typename T> static constexpr size_t hex_digits() {
@@ -112,8 +126,8 @@ static UUID parseModuleId(llvm::Triple::OSType os, llvm::StringRef str) {
: sizeof(data.uuid));
}
-Record::Kind Record::classify(llvm::StringRef Line) {
- Token Tok = toToken(getToken(Line).first);
+llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
+ Token Tok = consume<Token>(Line);
switch (Tok) {
case Token::Module:
return Record::Module;
@@ -126,36 +140,45 @@ Record::Kind Record::classify(llvm::StringRef Line) {
case Token::Public:
return Record::Public;
case Token::Stack:
- return Record::Stack;
+ Tok = consume<Token>(Line);
+ switch (Tok) {
+ case Token::CFI:
+ Tok = consume<Token>(Line);
+ return Tok == Token::Init ? Record::StackCFIInit : Record::StackCFI;
+ default:
+ return llvm::None;
+ }
- case Token::CodeID:
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.
return Record::Line;
+
+ case Token::CodeID:
+ case Token::CFI:
+ case Token::Init:
+ // These should never appear at the start of a valid record.
+ return llvm::None;
}
llvm_unreachable("Fully covered switch above!");
}
llvm::Optional<ModuleRecord> ModuleRecord::parse(llvm::StringRef Line) {
// MODULE Linux x86_64 E5894855C35DCCCCCCCCCCCCCCCCCCCC0 a.out
- llvm::StringRef Str;
- std::tie(Str, Line) = getToken(Line);
- if (toToken(Str) != Token::Module)
+ if (consume<Token>(Line) != Token::Module)
return llvm::None;
- std::tie(Str, Line) = getToken(Line);
- llvm::Triple::OSType OS = toOS(Str);
+ llvm::Triple::OSType OS = consume<llvm::Triple::OSType>(Line);
if (OS == llvm::Triple::UnknownOS)
return llvm::None;
- std::tie(Str, Line) = getToken(Line);
- llvm::Triple::ArchType Arch = toArch(Str);
+ llvm::Triple::ArchType Arch = consume<llvm::Triple::ArchType>(Line);
if (Arch == llvm::Triple::UnknownArch)
return llvm::None;
+ llvm::StringRef Str;
std::tie(Str, Line) = getToken(Line);
UUID ID = parseModuleId(OS, Str);
if (!ID)
@@ -173,15 +196,13 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
llvm::Optional<InfoRecord> InfoRecord::parse(llvm::StringRef Line) {
// INFO CODE_ID 554889E55DC3CCCCCCCCCCCCCCCCCCCC [a.exe]
- llvm::StringRef Str;
- std::tie(Str, Line) = getToken(Line);
- if (toToken(Str) != Token::Info)
+ if (consume<Token>(Line) != Token::Info)
return llvm::None;
- std::tie(Str, Line) = getToken(Line);
- if (toToken(Str) != Token::CodeID)
+ if (consume<Token>(Line) != Token::CodeID)
return llvm::None;
+ llvm::StringRef Str;
std::tie(Str, Line) = getToken(Line);
// If we don't have any text following the code ID (e.g. on linux), we should
// use this as the UUID. Otherwise, we should revert back to the module ID.
@@ -200,11 +221,10 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) {
// FILE number name
- llvm::StringRef Str;
- std::tie(Str, Line) = getToken(Line);
- if (toToken(Str) != Token::File)
+ if (consume<Token>(Line) != Token::File)
return llvm::None;
+ llvm::StringRef Str;
size_t Number;
std::tie(Str, Line) = getToken(Line);
if (!to_integer(Str, Number))
@@ -231,11 +251,10 @@ static bool parsePublicOrFunc(llvm::StringRef Line, bool &Multiple,
Token Tok = Size ? Token::Func : Token::Public;
- llvm::StringRef Str;
- std::tie(Str, Line) = getToken(Line);
- if (toToken(Str) != Tok)
+ if (consume<Token>(Line) != Tok)
return false;
+ llvm::StringRef Str;
std::tie(Str, Line) = getToken(Line);
Multiple = Str == "m";
@@ -354,8 +373,10 @@ llvm::StringRef breakpad::toString(Record::Kind K) {
return "LINE";
case Record::Public:
return "PUBLIC";
- case Record::Stack:
- return "STACK";
+ case Record::StackCFIInit:
+ return "STACK CFI INIT";
+ case Record::StackCFI:
+ return "STACK CFI";
}
llvm_unreachable("Unknown record kind!");
}
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
index 4353479c106..e80cc22b3d0 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
@@ -20,12 +20,12 @@ namespace breakpad {
class Record {
public:
- enum Kind { Module, Info, File, Func, Line, Public, Stack };
+ enum Kind { Module, Info, File, Func, Line, Public, StackCFIInit, StackCFI };
/// 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
/// records, but the full parse can still fail in case of corrupted input.
- static Kind classify(llvm::StringRef Line);
+ static llvm::Optional<Kind> classify(llvm::StringRef Line);
protected:
Record(Kind K) : TheKind(K) {}
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index ab68985691b..e68d80cdc72 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -148,11 +148,14 @@ void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
llvm::StringRef line;
std::tie(line, text) = text.split('\n');
- Record::Kind next_section = Record::classify(line);
+ llvm::Optional<Record::Kind> next_section = Record::classify(line);
if (next_section == Record::Line) {
// Line records logically belong to the preceding Func record, so we put
// them in the same section.
next_section = Record::Func;
+ } else if (next_section == Record::StackCFI) {
+ // Same goes for StackCFI and StackCFIInit
+ next_section = Record::StackCFIInit;
}
if (next_section == current_section)
continue;
OpenPOWER on IntegriCloud