summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
diff options
context:
space:
mode:
authorZequan Wu <zequanwu@google.com>2022-04-14 10:58:17 -0700
committerZequan Wu <zequanwu@google.com>2022-04-14 11:00:56 -0700
commitef7cba71486df8d6905000f932805774f1cbcc46 (patch)
treebba5100083b69f4ef2cf233d44163ccc8f20d8ba /lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
parent99d9c44434f57df5f188146925eea3bd8771260d (diff)
[LLDB][NativePDB] Fix inline line info in line table
It fixes the following case: ``` 0602 line 1 (+1) 0315 code 0x15 (+0x15) 0B2B code 0x20 (+0xB) line 2 (+1) 0602 line 3 (+1) 0311 code 0x31 (+0x11) ... ``` Inline ranges should have following mapping: `[0x15, 0x20) -> line 1` `[0x20, 0x31) -> line 2` Inline line entries: `0x15, line 1`, `0x20, line 2`, `0x31, line 3`. Reviewed By: labath Differential Revision: https://reviews.llvm.org/D123092
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp127
1 files changed, 75 insertions, 52 deletions
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 351c0bfc37f3..00d4422bc979 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1303,8 +1303,8 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
GetFileIndex(*cii, inlinee_line.Header->FileID);
if (!file_index_or_err)
return;
- uint32_t decl_file_idx = file_index_or_err.get();
- decl_file = files.GetFileSpecAtIndex(decl_file_idx);
+ uint32_t file_offset = file_index_or_err.get();
+ decl_file = files.GetFileSpecAtIndex(file_offset);
uint32_t decl_line = inlinee_line.Header->SourceLineNum;
std::unique_ptr<Declaration> decl_up =
std::make_unique<Declaration>(decl_file, decl_line);
@@ -1312,54 +1312,36 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
// Parse range and line info.
uint32_t code_offset = 0;
int32_t line_offset = 0;
- bool has_base = false;
- bool is_new_line_offset = false;
-
- bool is_start_of_statement = false;
+ llvm::Optional<uint32_t> code_offset_base;
+ llvm::Optional<uint32_t> code_offset_end;
+ llvm::Optional<uint32_t> cur_line_offset;
+ llvm::Optional<uint32_t> next_line_offset;
+ llvm::Optional<uint32_t> next_file_offset;
+
+ bool is_terminal_entry = false;
+ bool is_start_of_statement = true;
// The first instruction is the prologue end.
bool is_prologue_end = true;
- auto change_code_offset = [&](uint32_t code_delta) {
- if (has_base) {
- inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
- code_offset, code_delta, decl_line + line_offset));
- is_prologue_end = false;
- is_start_of_statement = false;
- } else {
- is_start_of_statement = true;
- }
- has_base = true;
- code_offset += code_delta;
-
- if (is_new_line_offset) {
- LineTable::Entry line_entry(func_base + code_offset,
- decl_line + line_offset, 0, decl_file_idx,
- true, false, is_prologue_end, false, false);
- inline_site_sp->line_entries.push_back(line_entry);
- is_new_line_offset = false;
- }
- };
- auto change_code_length = [&](uint32_t length) {
- inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
- code_offset, length, decl_line + line_offset));
- has_base = false;
-
- LineTable::Entry end_line_entry(func_base + code_offset + length,
- decl_line + line_offset, 0, decl_file_idx,
- false, false, false, false, true);
- inline_site_sp->line_entries.push_back(end_line_entry);
+ auto update_code_offset = [&](uint32_t code_delta) {
+ if (!code_offset_base)
+ code_offset_base = code_offset;
+ else if (!code_offset_end)
+ code_offset_end = *code_offset_base + code_delta;
};
- auto change_line_offset = [&](int32_t line_delta) {
+ auto update_line_offset = [&](int32_t line_delta) {
line_offset += line_delta;
- if (has_base) {
- LineTable::Entry line_entry(
- func_base + code_offset, decl_line + line_offset, 0, decl_file_idx,
- is_start_of_statement, false, is_prologue_end, false, false);
- inline_site_sp->line_entries.push_back(line_entry);
- } else {
- // Add line entry in next call to change_code_offset.
- is_new_line_offset = true;
- }
+ if (!code_offset_base || !cur_line_offset)
+ cur_line_offset = line_offset;
+ else
+ next_line_offset = line_offset;
+ ;
+ };
+ auto update_file_offset = [&](uint32_t offset) {
+ if (!code_offset_base)
+ file_offset = offset;
+ else
+ next_file_offset = offset;
};
for (auto &annot : inline_site.annotations()) {
@@ -1367,26 +1349,67 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
case BinaryAnnotationsOpCode::CodeOffset:
case BinaryAnnotationsOpCode::ChangeCodeOffset:
case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
- change_code_offset(annot.U1);
+ code_offset += annot.U1;
+ update_code_offset(annot.U1);
break;
case BinaryAnnotationsOpCode::ChangeLineOffset:
- change_line_offset(annot.S1);
+ update_line_offset(annot.S1);
break;
case BinaryAnnotationsOpCode::ChangeCodeLength:
- change_code_length(annot.U1);
+ update_code_offset(annot.U1);
code_offset += annot.U1;
+ is_terminal_entry = true;
break;
case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
- change_code_offset(annot.U1);
- change_line_offset(annot.S1);
+ code_offset += annot.U1;
+ update_code_offset(annot.U1);
+ update_line_offset(annot.S1);
break;
case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
- change_code_offset(annot.U2);
- change_code_length(annot.U1);
+ code_offset += annot.U2;
+ update_code_offset(annot.U2);
+ update_code_offset(annot.U1);
+ code_offset += annot.U1;
+ is_terminal_entry = true;
+ break;
+ case BinaryAnnotationsOpCode::ChangeFile:
+ update_file_offset(annot.U1);
break;
default:
break;
}
+
+ // Add range if current range is finished.
+ if (code_offset_base && code_offset_end && cur_line_offset) {
+ inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
+ *code_offset_base, *code_offset_end - *code_offset_base,
+ decl_line + *cur_line_offset));
+ // Set base, end, file offset and line offset for next range.
+ if (next_file_offset)
+ file_offset = *next_file_offset;
+ cur_line_offset = next_line_offset ? next_line_offset : llvm::None;
+ code_offset_base = is_terminal_entry ? llvm::None : code_offset_end;
+ code_offset_end = next_line_offset = next_file_offset = llvm::None;
+ }
+ if (code_offset_base && cur_line_offset) {
+ if (is_terminal_entry) {
+ LineTable::Entry line_entry(
+ func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
+ file_offset, false, false, false, false, true);
+ inline_site_sp->line_entries.push_back(line_entry);
+ } else {
+ LineTable::Entry line_entry(func_base + *code_offset_base,
+ decl_line + *cur_line_offset, 0,
+ file_offset, is_start_of_statement, false,
+ is_prologue_end, false, false);
+ inline_site_sp->line_entries.push_back(line_entry);
+ is_prologue_end = false;
+ is_start_of_statement = false;
+ }
+ }
+ if (is_terminal_entry)
+ is_start_of_statement = true;
+ is_terminal_entry = false;
}
inline_site_sp->ranges.Sort();