summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ObjectFile/Breakpad
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-11-19 20:06:13 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-11-19 20:06:13 +0000
commitc0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch)
treef42add1021b9f2ac6a69ac7cf6c4499962739a45 /lldb/source/Plugins/ObjectFile/Breakpad
parent344a3780b2e33f6ca763666c380202b18aab72a3 (diff)
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/Breakpad')
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp91
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h50
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp11
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h6
4 files changed, 140 insertions, 18 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
index bd8eeedce57d..24941be515de 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
@@ -23,6 +23,8 @@ enum class Token {
CodeID,
File,
Func,
+ Inline,
+ InlineOrigin,
Public,
Stack,
CFI,
@@ -41,6 +43,8 @@ template <> Token stringTo<Token>(llvm::StringRef Str) {
.Case("CODE_ID", Token::CodeID)
.Case("FILE", Token::File)
.Case("FUNC", Token::Func)
+ .Case("INLINE", Token::Inline)
+ .Case("INLINE_ORIGIN", Token::InlineOrigin)
.Case("PUBLIC", Token::Public)
.Case("STACK", Token::Stack)
.Case("CFI", Token::CFI)
@@ -145,7 +149,10 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) {
default:
return llvm::None;
}
-
+ case Token::Inline:
+ return Record::Inline;
+ case Token::InlineOrigin:
+ return Record::InlineOrigin;
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
@@ -216,9 +223,11 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
return OS << "INFO CODE_ID " << R.ID.GetAsString();
}
-llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) {
- // FILE number name
- if (consume<Token>(Line) != Token::File)
+template <typename T>
+static llvm::Optional<T> parseNumberName(llvm::StringRef Line,
+ Token TokenType) {
+ // TOKEN number name
+ if (consume<Token>(Line) != TokenType)
return llvm::None;
llvm::StringRef Str;
@@ -231,7 +240,12 @@ llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) {
if (Name.empty())
return llvm::None;
- return FileRecord(Number, Name);
+ return T(Number, Name);
+}
+
+llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) {
+ // FILE number name
+ return parseNumberName<FileRecord>(Line, Token::File);
}
llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
@@ -239,6 +253,17 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
return OS << "FILE " << R.Number << " " << R.Name;
}
+llvm::Optional<InlineOriginRecord>
+InlineOriginRecord::parse(llvm::StringRef Line) {
+ // INLINE_ORIGIN number name
+ return parseNumberName<InlineOriginRecord>(Line, Token::InlineOrigin);
+}
+
+llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
+ const InlineOriginRecord &R) {
+ return OS << "INLINE_ORIGIN " << R.Number << " " << R.Name;
+}
+
static bool parsePublicOrFunc(llvm::StringRef Line, bool &Multiple,
lldb::addr_t &Address, lldb::addr_t *Size,
lldb::addr_t &ParamSize, llvm::StringRef &Name) {
@@ -299,6 +324,58 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
R.ParamSize, R.Name);
}
+llvm::Optional<InlineRecord> InlineRecord::parse(llvm::StringRef Line) {
+ // INLINE inline_nest_level call_site_line call_site_file_num origin_num
+ // [address size]+
+ if (consume<Token>(Line) != Token::Inline)
+ return llvm::None;
+
+ llvm::SmallVector<llvm::StringRef> Tokens;
+ SplitString(Line, Tokens, " ");
+ if (Tokens.size() < 6 || Tokens.size() % 2 == 1)
+ return llvm::None;
+
+ size_t InlineNestLevel;
+ uint32_t CallSiteLineNum;
+ size_t CallSiteFileNum;
+ size_t OriginNum;
+ if (!(to_integer(Tokens[0], InlineNestLevel) &&
+ to_integer(Tokens[1], CallSiteLineNum) &&
+ to_integer(Tokens[2], CallSiteFileNum) &&
+ to_integer(Tokens[3], OriginNum)))
+ return llvm::None;
+
+ InlineRecord Record = InlineRecord(InlineNestLevel, CallSiteLineNum,
+ CallSiteFileNum, OriginNum);
+ for (size_t i = 4; i < Tokens.size(); i += 2) {
+ lldb::addr_t Address;
+ if (!to_integer(Tokens[i], Address, 16))
+ return llvm::None;
+ lldb::addr_t Size;
+ if (!to_integer(Tokens[i + 1].trim(), Size, 16))
+ return llvm::None;
+ Record.Ranges.emplace_back(Address, Size);
+ }
+ return Record;
+}
+
+bool breakpad::operator==(const InlineRecord &L, const InlineRecord &R) {
+ return L.InlineNestLevel == R.InlineNestLevel &&
+ L.CallSiteLineNum == R.CallSiteLineNum &&
+ L.CallSiteFileNum == R.CallSiteFileNum && L.OriginNum == R.OriginNum &&
+ L.Ranges == R.Ranges;
+}
+
+llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS,
+ const InlineRecord &R) {
+ OS << llvm::formatv("INLINE {0} {1} {2} {3}", R.InlineNestLevel,
+ R.CallSiteLineNum, R.CallSiteFileNum, R.OriginNum);
+ for (const auto &range : R.Ranges) {
+ OS << llvm::formatv(" {0:x-} {1:x-}", range.first, range.second);
+ }
+ return OS;
+}
+
llvm::Optional<LineRecord> LineRecord::parse(llvm::StringRef Line) {
lldb::addr_t Address;
llvm::StringRef Str;
@@ -490,6 +567,10 @@ llvm::StringRef breakpad::toString(Record::Kind K) {
return "FILE";
case Record::Func:
return "FUNC";
+ case Record::Inline:
+ return "INLINE";
+ case Record::InlineOrigin:
+ return "INLINE_ORIGIN";
case Record::Line:
return "LINE";
case Record::Public:
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
index 1620a1210b84..8a11323d521c 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h
@@ -20,7 +20,18 @@ namespace breakpad {
class Record {
public:
- enum Kind { Module, Info, File, Func, Line, Public, StackCFI, StackWin };
+ enum Kind {
+ Module,
+ Info,
+ File,
+ Func,
+ Inline,
+ InlineOrigin,
+ 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
@@ -89,6 +100,23 @@ inline bool operator==(const FileRecord &L, const FileRecord &R) {
}
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRecord &R);
+class InlineOriginRecord : public Record {
+public:
+ static llvm::Optional<InlineOriginRecord> parse(llvm::StringRef Line);
+ InlineOriginRecord(size_t Number, llvm::StringRef Name)
+ : Record(InlineOrigin), Number(Number), Name(Name) {}
+
+ size_t Number;
+ llvm::StringRef Name;
+};
+
+inline bool operator==(const InlineOriginRecord &L,
+ const InlineOriginRecord &R) {
+ return L.Number == R.Number && L.Name == R.Name;
+}
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const InlineOriginRecord &R);
+
class FuncRecord : public Record {
public:
static llvm::Optional<FuncRecord> parse(llvm::StringRef Line);
@@ -107,6 +135,26 @@ public:
bool operator==(const FuncRecord &L, const FuncRecord &R);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FuncRecord &R);
+class InlineRecord : public Record {
+public:
+ static llvm::Optional<InlineRecord> parse(llvm::StringRef Line);
+ InlineRecord(size_t InlineNestLevel, uint32_t CallSiteLineNum,
+ size_t CallSiteFileNum, size_t OriginNum)
+ : Record(Inline), InlineNestLevel(InlineNestLevel),
+ CallSiteLineNum(CallSiteLineNum), CallSiteFileNum(CallSiteFileNum),
+ OriginNum(OriginNum) {}
+
+ size_t InlineNestLevel;
+ uint32_t CallSiteLineNum;
+ size_t CallSiteFileNum;
+ size_t OriginNum;
+ // A vector of address range covered by this inline
+ std::vector<std::pair<lldb::addr_t, lldb::addr_t>> Ranges;
+};
+
+bool operator==(const InlineRecord &L, const InlineRecord &R);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InlineRecord &R);
+
class LineRecord : public Record {
public:
static llvm::Optional<LineRecord> parse(llvm::StringRef Line);
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index 7a9163ddb880..bad730512ff4 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -56,11 +56,6 @@ void ObjectFileBreakpad::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
-ConstString ObjectFileBreakpad::GetPluginNameStatic() {
- static ConstString g_name("breakpad");
- return g_name;
-}
-
ObjectFile *ObjectFileBreakpad::CreateInstance(
const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset,
const FileSpec *file, offset_t file_offset, offset_t length) {
@@ -153,9 +148,9 @@ void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
std::tie(line, text) = text.split('\n');
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.
+ if (next_section == Record::Line || next_section == Record::Inline) {
+ // Line/Inline records logically belong to the preceding Func record, so
+ // we put them in the same section.
next_section = Record::Func;
}
if (next_section == current_section)
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index 8724feaa422d..c320c7ad3e2e 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -21,7 +21,7 @@ public:
static void Initialize();
static void Terminate();
- static ConstString GetPluginNameStatic();
+ static llvm::StringRef GetPluginNameStatic() { return "breakpad"; }
static const char *GetPluginDescriptionStatic() {
return "Breakpad object file reader.";
}
@@ -44,9 +44,7 @@ public:
ModuleSpecList &specs);
// PluginInterface protocol
- ConstString GetPluginName() override { return GetPluginNameStatic(); }
-
- uint32_t GetPluginVersion() override { return 1; }
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
// LLVM RTTI support
static char ID;