summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp82
1 files changed, 53 insertions, 29 deletions
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index a626a806151..a6357408551 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -43,6 +43,12 @@ namespace
return lldb::LanguageType::eLanguageTypeUnknown;
}
}
+
+ bool
+ ShouldAddLine(uint32_t requested_line, uint32_t actual_line, uint32_t addr_length)
+ {
+ return ((requested_line == 0 || actual_line == requested_line) && addr_length > 0);
+ }
}
void
@@ -480,49 +486,67 @@ SymbolFilePDB::ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc,
auto lines = m_session_up->findLineNumbers(*cu, *file);
int entry_count = lines->getChildCount();
+ uint64_t prev_addr;
+ uint32_t prev_length;
+ uint32_t prev_line;
+ uint32_t prev_source_idx;
+
for (int i = 0; i < entry_count; ++i)
{
auto line = lines->getChildAtIndex(i);
- uint32_t lno = line->getLineNumber();
- // If `match_line` == 0 we add any line no matter what. Otherwise, we only add
- // lines that match the requested line number.
- if (match_line != 0 && lno != match_line)
- continue;
-
- uint64_t va = line->getVirtualAddress();
- uint32_t cno = line->getColumnNumber();
+ uint64_t lno = line->getLineNumber();
+ uint64_t addr = line->getVirtualAddress();
+ uint32_t length = line->getLength();
uint32_t source_id = line->getSourceFileId();
+ uint32_t col = line->getColumnNumber();
uint32_t source_idx = index_map[source_id];
- bool is_basic_block = false; // PDB doesn't even have this concept, but LLDB doesn't use it anyway.
- bool is_prologue = false;
- bool is_epilogue = false;
- bool is_statement = line->isStatement();
- auto func = m_session_up->findSymbolByAddress(va, llvm::PDB_SymType::Function);
- if (func)
- {
- auto prologue = func->findOneChild<llvm::PDBSymbolFuncDebugStart>();
- is_prologue = (va == prologue->getVirtualAddress());
+ // There was a gap between the current entry and the previous entry if the addresses don't perfectly line
+ // up.
+ bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
- auto epilogue = func->findOneChild<llvm::PDBSymbolFuncDebugEnd>();
- is_epilogue = (va == epilogue->getVirtualAddress());
+ // Before inserting the current entry, insert a terminal entry at the end of the previous entry's address
+ // range if the current entry resulted in a gap from the previous entry.
+ if (is_gap && ShouldAddLine(match_line, prev_line, prev_length))
+ {
+ line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
- if (is_epilogue)
+ if (ShouldAddLine(match_line, lno, length))
+ {
+ bool is_statement = line->isStatement();
+ bool is_prologue = false;
+ bool is_epilogue = false;
+ auto func = m_session_up->findSymbolByAddress(addr, llvm::PDB_SymType::Function);
+ if (func)
{
- // Once per function, add a termination entry after the last byte of the function.
- // TODO: This makes the assumption that all functions are laid out contiguously in
- // memory and have no gaps. This is a wrong assumption in the general case, but is
- // good enough to allow simple scenarios to work. This needs to be revisited.
- auto concrete_func = llvm::dyn_cast<llvm::PDBSymbolFunc>(func.get());
- lldb::addr_t end_addr = concrete_func->getVirtualAddress() + concrete_func->getLength();
- line_table->InsertLineEntry(end_addr, lno, 0, source_idx, false, false, false, false, true);
+ auto prologue = func->findOneChild<llvm::PDBSymbolFuncDebugStart>();
+ is_prologue = (addr == prologue->getVirtualAddress());
+
+ auto epilogue = func->findOneChild<llvm::PDBSymbolFuncDebugEnd>();
+ is_epilogue = (addr == epilogue->getVirtualAddress());
}
+
+ line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, source_idx, is_statement, false,
+ is_prologue, is_epilogue, false);
}
- line_table->InsertLineEntry(va, lno, cno, source_idx, is_statement, is_basic_block, is_prologue,
- is_epilogue, false);
+ prev_addr = addr;
+ prev_length = length;
+ prev_line = lno;
+ prev_source_idx = source_idx;
}
+
+ if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length))
+ {
+ // The end is always a terminal entry, so insert it regardless.
+ line_table->AppendLineEntryToSequence(sequence.get(), prev_addr + prev_length, prev_line, 0,
+ prev_source_idx, false, false, false, false, true);
+ }
+
+ line_table->InsertSequence(sequence.release());
}
sc.comp_unit->SetLineTable(line_table.release());
OpenPOWER on IntegriCloud