[llvm] r250582 - [llvm-symbolizer] Use the export table if no symbols are present

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 16 16:43:22 PDT 2015


Author: rnk
Date: Fri Oct 16 18:43:22 2015
New Revision: 250582

URL: http://llvm.org/viewvc/llvm-project?rev=250582&view=rev
Log:
[llvm-symbolizer] Use the export table if no symbols are present

This lets us make guesses about symbols in third party DLLs without
debug info, like MSVCR120.dll or kernel32.dll. dbghelp does the same
thing.

Added:
    llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.cpp
    llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.exe
    llvm/trunk/test/tools/llvm-symbolizer/coff-exports.test
Modified:
    llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp
    llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
    llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h

Modified: llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp?rev=250582&r1=250581&r2=250582&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp (original)
+++ llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp Fri Oct 16 18:43:22 2015
@@ -1,5 +1,5 @@
 // To generate the corresponding EXE, run:
-// clang-cl -O2 -gdwarf -c coff-dwarf.cpp && lld-link -debug coff-dwarf.obj
+// clang-cl -MD -O2 -gdwarf -c coff-dwarf.cpp && lld-link -debug coff-dwarf.obj
 
 extern "C" int puts(const char *str);
 

Added: llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.cpp?rev=250582&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.cpp (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.cpp Fri Oct 16 18:43:22 2015
@@ -0,0 +1,20 @@
+// To generate the corresponding EXE, run:
+// clang-cl -MD -c coff-exports.cpp && lld-link /MANIFEST:NO coff-exports.obj
+
+#define EXPORT __declspec(dllexport)
+
+extern "C" int puts(const char *str);
+
+EXPORT void __declspec(noinline) foo() {
+  puts("foo1");
+  puts("foo2");
+}
+
+void bar() {
+  foo();
+}
+
+EXPORT int main() {
+  bar();
+  return 0;
+}

Added: llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.exe
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.exe?rev=250582&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.exe (added) and llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-exports.exe Fri Oct 16 18:43:22 2015 differ

Added: llvm/trunk/test/tools/llvm-symbolizer/coff-exports.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/coff-exports.test?rev=250582&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/coff-exports.test (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/coff-exports.test Fri Oct 16 18:43:22 2015
@@ -0,0 +1,17 @@
+RUN: grep '^ADDR:' %s | sed -s 's/ADDR: //' \
+RUN: 	 | llvm-symbolizer --inlining --relative-address -obj="%p/Inputs/coff-exports.exe" \
+RUN:	 | FileCheck %s
+
+ADDR: 0x500A
+ADDR: 0x5038
+ADDR: 0x504B
+
+We get the expected stack trace, except 'foo' appears for the 'bar' frame
+because 'bar' isn't in the export table.
+
+CHECK: foo(void)
+CHECK: ??:0:0
+CHECK: foo(void)
+CHECK: ??:0:0
+CHECK: main
+CHECK: ??:0:0

Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp?rev=250582&r1=250581&r2=250582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp (original)
+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp Fri Oct 16 18:43:22 2015
@@ -83,6 +83,50 @@ ModuleInfo::ModuleInfo(ObjectFile *Obj,
       computeSymbolSizes(*Module);
   for (auto &P : Symbols)
     addSymbol(P.first, P.second, OpdExtractor.get(), OpdAddress);
+
+  // If this is a COFF object and we didn't find any symbols, try the export
+  // table.
+  if (Symbols.empty()) {
+    if (auto *CoffObj = dyn_cast<COFFObjectFile>(Obj))
+      addCoffExportSymbols(CoffObj);
+  }
+}
+
+void ModuleInfo::addCoffExportSymbols(const COFFObjectFile *CoffObj) {
+  // Get all export names and offsets.
+  struct OffsetNamePair {
+    uint32_t Offset;
+    StringRef Name;
+  };
+  std::vector<OffsetNamePair> ExportSyms;
+  for (const ExportDirectoryEntryRef &Ref : CoffObj->export_directories()) {
+    StringRef Name;
+    uint32_t Offset;
+    if (error(Ref.getSymbolName(Name)) || error(Ref.getExportRVA(Offset)))
+      return;
+    ExportSyms.push_back(OffsetNamePair{Offset, Name});
+  }
+  if (ExportSyms.empty())
+    return;
+
+  // Sort by ascending offset.
+  array_pod_sort(ExportSyms.begin(), ExportSyms.end(),
+                 [](const OffsetNamePair *L, const OffsetNamePair *R) -> int {
+                   return L->Offset - R->Offset;
+                 });
+
+  // Approximate the symbol sizes by assuming they run to the next symbol.
+  // FIXME: This assumes all exports are functions.
+  uint64_t ImageBase = CoffObj->getImageBase();
+  for (auto I = ExportSyms.begin(), E = ExportSyms.end(); I != E; ++I) {
+    OffsetNamePair &Export = *I;
+    // FIXME: The last export has a one byte size now.
+    uint32_t NextOffset = I != E ? I->Offset : Export.Offset + 1;
+    uint64_t SymbolStart = ImageBase + Export.Offset;
+    uint64_t SymbolSize = NextOffset - Export.Offset;
+    SymbolDesc SD = {SymbolStart, SymbolSize};
+    Functions.insert(std::make_pair(SD, Export.Name));
+  }
 }
 
 void ModuleInfo::addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize,

Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h?rev=250582&r1=250581&r2=250582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h (original)
+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h Fri Oct 16 18:43:22 2015
@@ -130,6 +130,7 @@ private:
   void addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize,
                  DataExtractor *OpdExtractor = nullptr,
                  uint64_t OpdAddress = 0);
+  void addCoffExportSymbols(const COFFObjectFile *CoffObj);
   ObjectFile *Module;
   std::unique_ptr<DIContext> DebugInfoContext;
 




More information about the llvm-commits mailing list