[Lldb-commits] [lldb] r334260 - PDB support of function-level linking and splitted functions

Aaron Smith via lldb-commits lldb-commits at lists.llvm.org
Thu Jun 7 19:45:25 PDT 2018


Author: asmith
Date: Thu Jun  7 19:45:25 2018
New Revision: 334260

URL: http://llvm.org/viewvc/llvm-project?rev=334260&view=rev
Log:
PDB support of function-level linking and splitted functions

Summary:
The patch adds support of splitted functions (when MSVC is used with PGO) and function-level linking feature.

SymbolFilePDB::ParseCompileUnitLineTable function relies on fact that ranges of compiled source files in the binary are continuous and don't intersect each other. The function creates LineSequence for each file and inserts it into LineTable, and implementation of last one relies on continuity of the sequence. But it's not always true when function-level linking enabled, e.g. in added input test file test-pdb-function-level-linking.exe there is xstring's std__basic_string_char_std__char_traits_char__std__allocator_char_____max_size (.00454820) between test-pdb-function-level-linking.cpp's foo (.00454770) and main (.004548F0).

To fix the problem this patch renews the sequence on each address gap.

Reviewers: asmith, zturner

Reviewed By: asmith

Subscribers: aleksandr.urakov, labath, mgorny, lldb-commits

Differential Revision: https://reviews.llvm.org/D47708

Added:
    lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp
    lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h
    lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord
    lldb/trunk/lit/SymbolFile/PDB/function-level-linking.test
Modified:
    lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
    lldb/trunk/tools/lldb-test/lldb-test.cpp

Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp?rev=334260&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.cpp Thu Jun  7 19:45:25 2018
@@ -0,0 +1,9 @@
+#include "FunctionLevelLinkingTest.h"
+
+int foo() {
+  return 0;
+}
+
+int main() {
+  return foo() + bar() + baz();
+}

Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h?rev=334260&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.h Thu Jun  7 19:45:25 2018
@@ -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

Added: lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord?rev=334260&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord (added)
+++ lldb/trunk/lit/SymbolFile/PDB/Inputs/FunctionLevelLinkingTest.ord Thu Jun  7 19:45:25 2018
@@ -0,0 +1,4 @@
+?foo@@YAHXZ
+?bar@@YAHXZ
+main
+?baz@@YAHXZ

Added: lldb/trunk/lit/SymbolFile/PDB/function-level-linking.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/PDB/function-level-linking.test?rev=334260&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/PDB/function-level-linking.test (added)
+++ lldb/trunk/lit/SymbolFile/PDB/function-level-linking.test Thu Jun  7 19:45:25 2018
@@ -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

Modified: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp?rev=334260&r1=334259&r2=334260&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp Thu Jun  7 19:45:25 2018
@@ -1571,6 +1571,9 @@ bool SymbolFilePDB::ParseCompileUnitLine
         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)) {

Modified: lldb/trunk/tools/lldb-test/lldb-test.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-test/lldb-test.cpp?rev=334260&r1=334259&r2=334260&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-test/lldb-test.cpp (original)
+++ lldb/trunk/tools/lldb-test/lldb-test.cpp Thu Jun  7 19:45:25 2018
@@ -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 getFunctionNameF
   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
 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_pri
   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
   }
 
   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) {




More information about the lldb-commits mailing list