summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp9
-rw-r--r--lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h12
-rw-r--r--lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord4
-rw-r--r--lldb/lit/SymbolFile/PDB/function-level-linking.test4
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp3
-rw-r--r--lldb/tools/lldb-test/lldb-test.cpp111
6 files changed, 126 insertions, 17 deletions
diff --git a/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp b/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp
new file mode 100644
index 00000000000..fa0030bacbf
--- /dev/null
+++ b/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp
@@ -0,0 +1,9 @@
+#include "FunctionLevelLinkingTest.h"
+
+int foo() {
+ return 0;
+}
+
+int main() {
+ return foo() + bar() + baz();
+}
diff --git a/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h b/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h
new file mode 100644
index 00000000000..0cc9d80d85d
--- /dev/null
+++ b/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h
@@ -0,0 +1,12 @@
+#ifndef FUNCTION_LEVEL_LINKING_TEST_H
+#define FUNCTION_LEVEL_LINKING_TEST_H
+
+int bar() {
+ return 0;
+}
+
+int baz() {
+ return 0;
+}
+
+#endif
diff --git a/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord b/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord
new file mode 100644
index 00000000000..48abd0b872f
--- /dev/null
+++ b/lldb/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord
@@ -0,0 +1,4 @@
+?foo@@YAHXZ
+?bar@@YAHXZ
+main
+?baz@@YAHXZ
diff --git a/lldb/lit/SymbolFile/PDB/function-level-linking.test b/lldb/lit/SymbolFile/PDB/function-level-linking.test
new file mode 100644
index 00000000000..9b28ec1ba21
--- /dev/null
+++ b/lldb/lit/SymbolFile/PDB/function-level-linking.test
@@ -0,0 +1,4 @@
+REQUIRES: windows, lld
+RUN: clang-cl /c /Zi /Gy %S/Inputs/FunctionLevelLinkingTest.cpp /o %t.obj
+RUN: lld-link /debug:full /nodefaultlib /entry:main /order:@%S/Inputs/FunctionLevelLinkingTest.ord %t.obj /out:%t.exe
+RUN: lldb-test symbols -verify %t.exe
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index f298749f10d..19a0e95d206 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1571,6 +1571,9 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(
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());
+ sequence.reset(line_table->CreateLineSequenceContainer());
}
if (ShouldAddLine(match_line, lno, length)) {
diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index b27aad93336..c37d56ae7d0 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -21,6 +21,8 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
@@ -143,6 +145,9 @@ static FunctionNameType getFunctionNameFlags() {
return Result;
}
+static cl::opt<bool> Verify("verify", cl::desc("Verify symbol information."),
+ cl::sub(SymbolsSubcommand));
+
static Expected<CompilerDeclContext> getDeclContext(SymbolVendor &Vendor);
static Error findFunctions(lldb_private::Module &Module);
@@ -150,6 +155,7 @@ static Error findNamespaces(lldb_private::Module &Module);
static Error findTypes(lldb_private::Module &Module);
static Error findVariables(lldb_private::Module &Module);
static Error dumpModule(lldb_private::Module &Module);
+static Error verify(lldb_private::Module &Module);
static int dumpSymbols(Debugger &Dbg);
}
@@ -412,7 +418,75 @@ Error opts::symbols::dumpModule(lldb_private::Module &Module) {
return Error::success();
}
+Error opts::symbols::verify(lldb_private::Module &Module) {
+ SymbolVendor *plugin = Module.GetSymbolVendor();
+ if (!plugin)
+ return make_error<StringError>("Can't get a symbol vendor.",
+ inconvertibleErrorCode());
+
+ SymbolFile *symfile = plugin->GetSymbolFile();
+ if (!symfile)
+ return make_error<StringError>("Can't get a symbol file.",
+ inconvertibleErrorCode());
+
+ uint32_t comp_units_count = symfile->GetNumCompileUnits();
+
+ outs() << "Found " << comp_units_count << " compile units.\n";
+
+ for (uint32_t i = 0; i < comp_units_count; i++) {
+ lldb::CompUnitSP comp_unit = symfile->ParseCompileUnitAtIndex(i);
+ if (!comp_unit)
+ return make_error<StringError>("Can't get a compile unit.",
+ inconvertibleErrorCode());
+
+ outs() << "Processing '" << comp_unit->GetFilename().AsCString() <<
+ "' compile unit.\n";
+
+ LineTable *lt = comp_unit->GetLineTable();
+ if (!lt)
+ return make_error<StringError>(
+ "Can't get a line table of a compile unit.",
+ inconvertibleErrorCode());
+
+ uint32_t count = lt->GetSize();
+
+ outs() << "The line table contains " << count << " entries.\n";
+
+ if (count == 0)
+ continue;
+
+ LineEntry le;
+ if (!lt->GetLineEntryAtIndex(0, le))
+ return make_error<StringError>(
+ "Can't get a line entry of a compile unit",
+ inconvertibleErrorCode());
+
+ for (uint32_t i = 1; i < count; i++) {
+ lldb::addr_t curr_end =
+ le.range.GetBaseAddress().GetFileAddress() + le.range.GetByteSize();
+
+ if (!lt->GetLineEntryAtIndex(i, le))
+ return make_error<StringError>(
+ "Can't get a line entry of a compile unit",
+ inconvertibleErrorCode());
+
+ if (curr_end > le.range.GetBaseAddress().GetFileAddress())
+ return make_error<StringError>(
+ "Line table of a compile unit is inconsistent",
+ inconvertibleErrorCode());
+ }
+ }
+
+ outs() << "The symbol information is verified.\n";
+
+ return Error::success();
+}
+
int opts::symbols::dumpSymbols(Debugger &Dbg) {
+ if (Verify && Find != FindType::None) {
+ WithColor::error() << "Cannot both search and verify symbol information.\n";
+ return 1;
+ }
if (Find != FindType::None && Regex && !Context.empty()) {
WithColor::error()
<< "Cannot search using both regular expressions and context.\n";
@@ -435,23 +509,26 @@ int opts::symbols::dumpSymbols(Debugger &Dbg) {
}
Error (*Action)(lldb_private::Module &);
- switch (Find) {
- case FindType::Function:
- Action = findFunctions;
- break;
- case FindType::Namespace:
- Action = findNamespaces;
- break;
- case FindType::Type:
- Action = findTypes;
- break;
- case FindType::Variable:
- Action = findVariables;
- break;
- case FindType::None:
- Action = dumpModule;
- break;
- }
+ if (!Verify) {
+ switch (Find) {
+ case FindType::Function:
+ Action = findFunctions;
+ break;
+ case FindType::Namespace:
+ Action = findNamespaces;
+ break;
+ case FindType::Type:
+ Action = findTypes;
+ break;
+ case FindType::Variable:
+ Action = findVariables;
+ break;
+ case FindType::None:
+ Action = dumpModule;
+ break;
+ }
+ } else
+ Action = verify;
int HadErrors = 0;
for (const auto &File : InputFilenames) {
OpenPOWER on IntegriCloud