diff options
| author | Zequan Wu <zequanwu@google.com> | 2022-04-14 10:58:17 -0700 |
|---|---|---|
| committer | Zequan Wu <zequanwu@google.com> | 2022-04-14 11:00:56 -0700 |
| commit | ef7cba71486df8d6905000f932805774f1cbcc46 (patch) | |
| tree | bba5100083b69f4ef2cf233d44163ccc8f20d8ba /lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp | |
| parent | 99d9c44434f57df5f188146925eea3bd8771260d (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.cpp | 127 |
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(); |
