[llvm] r249784 - [llvm-symbolizer] Make --relative-address work with DWARF contexts

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 8 17:15:02 PDT 2015


Author: rnk
Date: Thu Oct  8 19:15:01 2015
New Revision: 249784

URL: http://llvm.org/viewvc/llvm-project?rev=249784&view=rev
Log:
[llvm-symbolizer] Make --relative-address work with DWARF contexts

Summary:
Previously the relative address flag only affected PDB debug info.  Now
both DIContext implementations always expect to be passed virtual
addresses. llvm-symbolizer is now responsible for adding ImageBase to
module offsets when --relative-offset is passed.

Reviewers: zturner

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D12883

Added:
    llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp
    llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.exe
    llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.input
    llvm/trunk/test/tools/llvm-symbolizer/coff-dwarf.test
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h
    llvm/trunk/include/llvm/Object/COFF.h
    llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp
    llvm/trunk/lib/Object/COFFObjectFile.cpp
    llvm/trunk/test/tools/llvm-symbolizer/pdb/pdb.test
    llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
    llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h?rev=249784&r1=249783&r2=249784&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h Thu Oct  8 19:15:01 2015
@@ -32,8 +32,7 @@ class PDBContext : public DIContext {
 
 public:
   PDBContext(const object::COFFObjectFile &Object,
-             std::unique_ptr<IPDBSession> PDBSession,
-             bool RelativeAddress);
+             std::unique_ptr<IPDBSession> PDBSession);
 
   static bool classof(const DIContext *DICtx) {
     return DICtx->getKind() == CK_PDB;

Modified: llvm/trunk/include/llvm/Object/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?rev=249784&r1=249783&r2=249784&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/COFF.h (original)
+++ llvm/trunk/include/llvm/Object/COFF.h Thu Oct  8 19:15:01 2015
@@ -773,6 +773,7 @@ public:
   std::error_code getSectionContents(const coff_section *Sec,
                                      ArrayRef<uint8_t> &Res) const;
 
+  ErrorOr<uint64_t> getImageBase() const;
   std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
   std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
   std::error_code getHintName(uint32_t Rva, uint16_t &Hint,

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp?rev=249784&r1=249783&r2=249784&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp Thu Oct  8 19:15:01 2015
@@ -21,24 +21,11 @@ using namespace llvm;
 using namespace llvm::object;
 
 PDBContext::PDBContext(const COFFObjectFile &Object,
-                       std::unique_ptr<IPDBSession> PDBSession,
-                       bool RelativeAddress)
+                       std::unique_ptr<IPDBSession> PDBSession)
     : DIContext(CK_PDB), Session(std::move(PDBSession)) {
-  if (!RelativeAddress) {
-    uint64_t ImageBase = 0;
-    if (Object.is64()) {
-      const pe32plus_header *Header = nullptr;
-      Object.getPE32PlusHeader(Header);
-      if (Header)
-        ImageBase = Header->ImageBase;
-    } else {
-      const pe32_header *Header = nullptr;
-      Object.getPE32Header(Header);
-      if (Header)
-        ImageBase = static_cast<uint64_t>(Header->ImageBase);
-    }
-    Session->setLoadAddress(ImageBase);
-  }
+  ErrorOr<uint64_t> ImageBase = Object.getImageBase();
+  if (ImageBase)
+    Session->setLoadAddress(ImageBase.get());
 }
 
 void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}

Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=249784&r1=249783&r2=249784&view=diff
==============================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp Thu Oct  8 19:15:01 2015
@@ -174,10 +174,7 @@ ErrorOr<uint64_t> COFFObjectFile::getSym
 
   // The section VirtualAddress does not include ImageBase, and we want to
   // return virtual addresses.
-  if (PE32Header)
-    Result += PE32Header->ImageBase;
-  else if (PE32PlusHeader)
-    Result += PE32PlusHeader->ImageBase;
+  Result += getImageBase().get();
 
   return Result;
 }
@@ -274,10 +271,7 @@ uint64_t COFFObjectFile::getSectionAddre
 
   // The section VirtualAddress does not include ImageBase, and we want to
   // return virtual addresses.
-  if (PE32Header)
-    Result += PE32Header->ImageBase;
-  else if (PE32PlusHeader)
-    Result += PE32PlusHeader->ImageBase;
+  Result += getImageBase().get();
   return Result;
 }
 
@@ -424,10 +418,17 @@ std::error_code COFFObjectFile::initSymb
   return std::error_code();
 }
 
+ErrorOr<uint64_t> COFFObjectFile::getImageBase() const {
+  if (PE32Header)
+    return uint64_t(PE32Header->ImageBase);
+  else if (PE32PlusHeader)
+    return uint64_t(PE32PlusHeader->ImageBase);
+  return object_error::parse_failed;
+}
+
 // Returns the file offset for the given VA.
 std::error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
-  uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase
-                                  : (uint64_t)PE32PlusHeader->ImageBase;
+  uint64_t ImageBase = getImageBase().get();
   uint64_t Rva = Addr - ImageBase;
   assert(Rva <= UINT32_MAX);
   return getRvaPtr((uint32_t)Rva, Res);

Added: 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=249784&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.cpp Thu Oct  8 19:15:01 2015
@@ -0,0 +1,19 @@
+// To generate the corresponding EXE, run:
+// clang-cl -O2 -gdwarf -c coff-dwarf.cpp && lld-link -debug coff-dwarf.obj
+
+extern "C" int puts(const char *str);
+
+void __declspec(noinline) foo() {
+  puts("foo1");
+  puts("foo2");
+}
+
+// LLVM should inline this into main.
+static void bar() {
+  foo();
+}
+
+int main() {
+  bar();
+  return 0;
+}

Added: llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.exe
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.exe?rev=249784&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.exe (added) and llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.exe Thu Oct  8 19:15:01 2015 differ

Added: llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.input
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.input?rev=249784&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.input (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/Inputs/coff-dwarf.input Thu Oct  8 19:15:01 2015
@@ -0,0 +1,2 @@
+0x5009
+0x5038

Added: llvm/trunk/test/tools/llvm-symbolizer/coff-dwarf.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/coff-dwarf.test?rev=249784&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/coff-dwarf.test (added)
+++ llvm/trunk/test/tools/llvm-symbolizer/coff-dwarf.test Thu Oct  8 19:15:01 2015
@@ -0,0 +1,9 @@
+RUN: llvm-symbolizer --inlining --relative-address -obj="%p/Inputs/coff-dwarf.exe" \
+RUN:	    < %p/Inputs/coff-dwarf.input | FileCheck %s
+
+CHECK: foo(void)
+CHECK: coff-dwarf.cpp:7
+CHECK: bar(void)
+CHECK: coff-dwarf.cpp:13
+CHECK: main
+CHECK: coff-dwarf.cpp:17

Modified: llvm/trunk/test/tools/llvm-symbolizer/pdb/pdb.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/pdb/pdb.test?rev=249784&r1=249783&r2=249784&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/pdb/pdb.test (original)
+++ llvm/trunk/test/tools/llvm-symbolizer/pdb/pdb.test Thu Oct  8 19:15:01 2015
@@ -1,8 +1,18 @@
 RUN: llvm-symbolizer -obj="%p/Inputs/test.exe" < "%p/Inputs/test.exe.input" | \
 RUN:    FileCheck %s --check-prefix=CHECK
+RUN: llvm-symbolizer -obj="%p/Inputs/test.exe" < "%p/Inputs/test.exe.input" | \
+RUN:    FileCheck %s --check-prefix=CHECK
 RUN: llvm-symbolizer -obj="%p/Inputs/test.exe" -demangle=false < \
 RUN:    "%p/Inputs/test.exe.input" | FileCheck %s --check-prefix=CHECK-NO-DEMANGLE
 
+Subtract ImageBase from all the offsets and run the test again with
+--relative-address.
+
+RUN: python -c 'import sys;print "\n".join([hex(int(x, 16) - 0x400000) for x in sys.stdin])' \
+RUN:	< %p/Inputs/test.exe.input \
+RUN:	| llvm-symbolizer -obj="%p/Inputs/test.exe" -demangle=false --relative-address \
+RUN:    | FileCheck %s --check-prefix=CHECK-NO-DEMANGLE
+
 CHECK: foo(void)
 CHECK-NEXT: test.cpp:10
 CHECK: main

Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp?rev=249784&r1=249783&r2=249784&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp (original)
+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp Thu Oct  8 19:15:01 2015
@@ -126,6 +126,13 @@ bool ModuleInfo::isWin32Module() const {
   return CoffObject && CoffObject->getMachine() == COFF::IMAGE_FILE_MACHINE_I386;
 }
 
+uint64_t ModuleInfo::getModulePreferredBase() const {
+  if (auto *CoffObject = dyn_cast<COFFObjectFile>(Module))
+    if (auto Base = CoffObject->getImageBase())
+      return Base.get();
+  return 0;
+}
+
 bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
                                         std::string &Name, uint64_t &Addr,
                                         uint64_t &Size) const {
@@ -210,6 +217,12 @@ std::string LLVMSymbolizer::symbolizeCod
   ModuleInfo *Info = getOrCreateModuleInfo(ModuleName);
   if (!Info)
     return printDILineInfo(DILineInfo(), Info);
+
+  // If the user is giving us relative addresses, add the preferred base of the
+  // object to the offset before we do the query. It's what DIContext expects.
+  if (Opts.RelativeAddresses)
+    ModuleOffset += Info->getModulePreferredBase();
+
   if (Opts.PrintInlining) {
     DIInliningInfo InlinedContext =
         Info->symbolizeInlinedCode(ModuleOffset, Opts);
@@ -233,6 +246,10 @@ std::string LLVMSymbolizer::symbolizeDat
   uint64_t Size = 0;
   if (Opts.UseSymbolTable) {
     if (ModuleInfo *Info = getOrCreateModuleInfo(ModuleName)) {
+      // If the user is giving us relative addresses, add the preferred base of the
+      // object to the offset before we do the query. It's what DIContext expects.
+      if (Opts.RelativeAddresses)
+        ModuleOffset += Info->getModulePreferredBase();
       if (Info->symbolizeData(ModuleOffset, Name, Start, Size) && Opts.Demangle)
         Name = DemangleName(Name, Info);
     }
@@ -474,8 +491,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(co
     PDB_ErrorCode Error = loadDataForEXE(PDB_ReaderType::DIA,
                                          Objects.first->getFileName(), Session);
     if (Error == PDB_ErrorCode::Success) {
-      Context = new PDBContext(*CoffObject, std::move(Session),
-                               Opts.RelativeAddresses);
+      Context = new PDBContext(*CoffObject, std::move(Session));
     }
   }
   if (!Context)

Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h?rev=249784&r1=249783&r2=249784&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h (original)
+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.h Thu Oct  8 19:15:01 2015
@@ -117,6 +117,10 @@ public:
   // Return true if this is a 32-bit x86 PE COFF module.
   bool isWin32Module() const;
 
+  // Returns the preferred base of the module, i.e. where the loader would place
+  // it in memory assuming there were no conflicts.
+  uint64_t getModulePreferredBase() const;
+
 private:
   bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
                               std::string &Name, uint64_t &Addr,




More information about the llvm-commits mailing list