[llvm-commits] [llvm] r173517 - in /llvm/trunk: include/llvm/ExecutionEngine/ObjectImage.h lib/DebugInfo/DWARFCompileUnit.h lib/DebugInfo/DWARFContext.cpp lib/DebugInfo/DWARFContext.h lib/DebugInfo/DWARFDebugLine.cpp lib/DebugInfo/DWARFDebugLine.h lib/DebugInfo/DWARFRelocMap.h lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h test/DebugInfo/Inputs/test-inline.o test/DebugInfo/debuglineinfo.test tools/llvm-rtdyld/CMakeLists.txt tools/llvm-rtdyld/Makefile tools/llvm-rtdyld/llvm-rtdyld.cpp

Andrew Kaylor andrew.kaylor at intel.com
Fri Jan 25 14:50:59 PST 2013


Author: akaylor
Date: Fri Jan 25 16:50:58 2013
New Revision: 173517

URL: http://llvm.org/viewvc/llvm-project?rev=173517&view=rev
Log:
Add support for applying in-memory relocations to the .debug_line section and, in the case of ELF files, using symbol addresses when available for relocations to the .debug_info section.  Also extending the llvm-rtdyld tool to add the ability to dump line number information for testing purposes.

Added:
    llvm/trunk/lib/DebugInfo/DWARFRelocMap.h
    llvm/trunk/test/DebugInfo/Inputs/test-inline.o   (with props)
    llvm/trunk/test/DebugInfo/debuglineinfo.test
Modified:
    llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
    llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h
    llvm/trunk/lib/DebugInfo/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARFContext.h
    llvm/trunk/lib/DebugInfo/DWARFDebugLine.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugLine.h
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
    llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt
    llvm/trunk/tools/llvm-rtdyld/Makefile
    llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp

Modified: llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/ObjectImage.h Fri Jan 25 16:50:58 2013
@@ -50,6 +50,8 @@ public:
 
   virtual StringRef getData() const = 0;
 
+  virtual object::ObjectFile* getObjectFile() const = 0;
+
   // Subclasses can override these methods to provide JIT debugging support
   virtual void registerWithDebugger() = 0;
   virtual void deregisterWithDebugger() = 0;

Modified: llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFCompileUnit.h Fri Jan 25 16:50:58 2013
@@ -13,6 +13,7 @@
 #include "DWARFDebugAbbrev.h"
 #include "DWARFDebugInfoEntry.h"
 #include "DWARFDebugRangeList.h"
+#include "DWARFRelocMap.h"
 #include <vector>
 
 namespace llvm {
@@ -20,7 +21,6 @@ namespace llvm {
 class DWARFDebugAbbrev;
 class StringRef;
 class raw_ostream;
-typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
 
 class DWARFCompileUnit {
   const DWARFDebugAbbrev *Abbrev;

Modified: llvm/trunk/lib/DebugInfo/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.cpp?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.cpp Fri Jan 25 16:50:58 2013
@@ -53,7 +53,7 @@ void DWARFContext::dump(raw_ostream &OS,
         DataExtractor lineData(getLineSection(), isLittleEndian(),
                                savedAddressByteSize);
         DWARFDebugLine::DumpingState state(OS);
-        DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
+        DWARFDebugLine::parseStatementTable(lineData, &lineRelocMap(), &stmtOffset, state);
       }
     }
   }
@@ -155,7 +155,7 @@ const DWARFDebugAranges *DWARFContext::g
 const DWARFLineTable *
 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
   if (!Line)
-    Line.reset(new DWARFDebugLine());
+    Line.reset(new DWARFDebugLine(&lineRelocMap()));
 
   unsigned stmtOffset =
     cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
@@ -422,12 +422,15 @@ DWARFContextInMemory::DWARFContextInMemo
     else
       continue;
 
-    // TODO: For now only handle relocations for the debug_info section.
+    // TODO: Add support for relocations in other sections as needed.
+    // Record relocations for the debug_info and debug_line sections.
     RelocAddrMap *Map;
     if (name == "debug_info")
       Map = &InfoRelocMap;
     else if (name == "debug_info.dwo")
       Map = &InfoDWORelocMap;
+    else if (name == "debug_line")
+      Map = &LineRelocMap;
     else
       continue;
 
@@ -441,10 +444,17 @@ DWARFContextInMemory::DWARFContextInMemo
         reloc_i->getAddress(Address);
         uint64_t Type;
         reloc_i->getType(Type);
+        uint64_t SymAddr = 0;
+        // ELF relocations may need the symbol address
+        if (Obj->isELF()) {
+          object::SymbolRef Sym;
+          reloc_i->getSymbol(Sym);
+          Sym.getAddress(SymAddr);
+        }
 
         object::RelocVisitor V(Obj->getFileFormatName());
         // The section address is always 0 for debug sections.
-        object::RelocToApply R(V.visit(Type, *reloc_i));
+        object::RelocToApply R(V.visit(Type, *reloc_i, 0, SymAddr));
         if (V.error()) {
           SmallString<32> Name;
           error_code ec(reloc_i->getTypeName(Name));

Modified: llvm/trunk/lib/DebugInfo/DWARFContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.h?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.h Fri Jan 25 16:50:58 2013
@@ -95,6 +95,7 @@ public:
 
   virtual bool isLittleEndian() const = 0;
   virtual const RelocAddrMap &infoRelocMap() const = 0;
+  virtual const RelocAddrMap &lineRelocMap() const = 0;
   virtual StringRef getInfoSection() = 0;
   virtual StringRef getAbbrevSection() = 0;
   virtual StringRef getARangeSection() = 0;
@@ -130,6 +131,7 @@ class DWARFContextInMemory : public DWAR
   virtual void anchor();
   bool IsLittleEndian;
   RelocAddrMap InfoRelocMap;
+  RelocAddrMap LineRelocMap;
   StringRef InfoSection;
   StringRef AbbrevSection;
   StringRef ARangeSection;
@@ -150,6 +152,7 @@ public:
   DWARFContextInMemory(object::ObjectFile *);
   virtual bool isLittleEndian() const { return IsLittleEndian; }
   virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
+  virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
   virtual StringRef getInfoSection() { return InfoSection; }
   virtual StringRef getAbbrevSection() { return AbbrevSection; }
   virtual StringRef getARangeSection() { return ARangeSection; }

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugLine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugLine.cpp?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugLine.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugLine.cpp Fri Jan 25 16:50:58 2013
@@ -155,7 +155,7 @@ DWARFDebugLine::getOrParseLineTable(Data
   if (pos.second) {
     // Parse and cache the line table for at this offset.
     State state;
-    if (!parseStatementTable(debug_line_data, &offset, state))
+    if (!parseStatementTable(debug_line_data, RelocMap, &offset, state))
       return 0;
     pos.first->second = state;
   }
@@ -219,7 +219,8 @@ DWARFDebugLine::parsePrologue(DataExtrac
 }
 
 bool
-DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
+DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, 
+                                    const RelocAddrMap *RMap,
                                     uint32_t *offset_ptr, State &state) {
   const uint32_t debug_line_offset = *offset_ptr;
 
@@ -268,7 +269,15 @@ DWARFDebugLine::parseStatementTable(Data
         // relocatable address. All of the other statement program opcodes
         // that affect the address register add a delta to it. This instruction
         // stores a relocatable value into it instead.
-        state.Address = debug_line_data.getAddress(offset_ptr);
+        {
+          // If this address is in our relocation map, apply the relocation.
+          RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
+          if (AI != RMap->end()) {
+             const std::pair<uint8_t, int64_t> &R = AI->second;
+             state.Address = debug_line_data.getAddress(offset_ptr) + R.second;
+          } else
+            state.Address = debug_line_data.getAddress(offset_ptr);
+        }
         break;
 
       case DW_LNE_define_file:

Modified: llvm/trunk/lib/DebugInfo/DWARFDebugLine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugLine.h?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugLine.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugLine.h Fri Jan 25 16:50:58 2013
@@ -10,6 +10,7 @@
 #ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H
 #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
 
+#include "DWARFRelocMap.h"
 #include "llvm/Support/DataExtractor.h"
 #include <map>
 #include <string>
@@ -21,6 +22,7 @@ class raw_ostream;
 
 class DWARFDebugLine {
 public:
+  DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {}
   struct FileNameEntry {
     FileNameEntry() : Name(0), DirIdx(0), ModTime(0), Length(0) {}
 
@@ -227,6 +229,7 @@ public:
                             Prologue *prologue);
   /// Parse a single line table (prologue and all rows).
   static bool parseStatementTable(DataExtractor debug_line_data,
+                                  const RelocAddrMap *RMap,
                                   uint32_t *offset_ptr, State &state);
 
   const LineTable *getLineTable(uint32_t offset) const;
@@ -238,6 +241,7 @@ private:
   typedef LineTableMapTy::iterator LineTableIter;
   typedef LineTableMapTy::const_iterator LineTableConstIter;
 
+  const RelocAddrMap *RelocMap;
   LineTableMapTy LineTableMap;
 };
 

Added: llvm/trunk/lib/DebugInfo/DWARFRelocMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFRelocMap.h?rev=173517&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFRelocMap.h (added)
+++ llvm/trunk/lib/DebugInfo/DWARFRelocMap.h Fri Jan 25 16:50:58 2013
@@ -0,0 +1,21 @@
+//===-- DWARFRelocMap.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARFRELOCMAP_H
+#define LLVM_DEBUGINFO_DWARFRELOCMAP_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
+
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_DWARFRELOCMAP_H
\ No newline at end of file

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h Fri Jan 25 16:50:58 2013
@@ -58,6 +58,8 @@ public:
 
   virtual StringRef getData() const { return ObjFile->getData(); }
 
+  virtual object::ObjectFile* getObjectFile() const { return ObjFile; }
+
   // Subclasses can override these methods to update the image with loaded
   // addresses for sections and common symbols
   virtual void updateSectionAddress(const object::SectionRef &Sec,

Added: llvm/trunk/test/DebugInfo/Inputs/test-inline.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/test-inline.o?rev=173517&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/test-inline.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/debuglineinfo.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/debuglineinfo.test?rev=173517&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/debuglineinfo.test (added)
+++ llvm/trunk/test/DebugInfo/debuglineinfo.test Fri Jan 25 16:50:58 2013
@@ -0,0 +1,15 @@
+RUN: llvm-rtdyld -printline %p/Inputs/test-inline.o \
+RUN:   | FileCheck %s -check-prefix TEST_INLINE
+
+; This test verifies that relocations are correctly applied to the
+; .debug_line section.  If relocations are not applied the first two
+; functions will be reported as both starting at address zero in the
+; line number table.
+TEST_INLINE:      Function: _Z15test_parametersPfPA2_dR11char_structPPitm, Size = 170
+TEST_INLINE-NEXT: Line info:test-inline.cpp, line:33
+TEST_INLINE-NEXT: Function: _Z3foov, Size = 3
+TEST_INLINE-NEXT: Line info:test-inline.cpp, line:28
+TEST_INLINE-NEXT: Function: main, Size = 146
+TEST_INLINE-NEXT: Line info:test-inline.cpp, line:39
+
+

Modified: llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-rtdyld/CMakeLists.txt Fri Jan 25 16:50:58 2013
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT)
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT debuginfo)
 
 add_llvm_tool(llvm-rtdyld
   llvm-rtdyld.cpp

Modified: llvm/trunk/tools/llvm-rtdyld/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/Makefile?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/Makefile (original)
+++ llvm/trunk/tools/llvm-rtdyld/Makefile Fri Jan 25 16:50:58 2013
@@ -9,7 +9,7 @@
 
 LEVEL := ../..
 TOOLNAME := llvm-rtdyld
-LINK_COMPONENTS := all-targets support MC object RuntimeDyld JIT
+LINK_COMPONENTS := all-targets support MC object RuntimeDyld JIT debuginfo
 
 # This tool has no plugins, optimize startup time.
 TOOL_NO_EXPORTS := 1

Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=173517&r1=173516&r2=173517&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
+++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Fri Jan 25 16:50:58 2013
@@ -13,6 +13,7 @@
 
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/DIContext.h"
 #include "llvm/ExecutionEngine/ObjectBuffer.h"
 #include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
@@ -31,7 +32,8 @@ InputFileList(cl::Positional, cl::ZeroOr
               cl::desc("<input file>"));
 
 enum ActionType {
-  AC_Execute
+  AC_Execute,
+  AC_PrintLineInfo
 };
 
 static cl::opt<ActionType>
@@ -39,6 +41,8 @@ Action(cl::desc("Action to perform:"),
        cl::init(AC_Execute),
        cl::values(clEnumValN(AC_Execute, "execute",
                              "Load, link, and execute the inputs."),
+                  clEnumValN(AC_PrintLineInfo, "printline",
+                             "Load, link, and print line information for each function."),
                   clEnumValEnd));
 
 static cl::opt<std::string>
@@ -114,6 +118,60 @@ static int Error(const Twine &Msg) {
 
 /* *** */
 
+static int printLineInfoForInput() {
+  // If we don't have any input files, read from stdin.
+  if (!InputFileList.size())
+    InputFileList.push_back("-");
+  for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
+    // Instantiate a dynamic linker.
+    TrivialMemoryManager *MemMgr = new TrivialMemoryManager;
+    RuntimeDyld Dyld(MemMgr);
+
+    // Load the input memory buffer.
+    OwningPtr<MemoryBuffer> InputBuffer;
+    OwningPtr<ObjectImage>  LoadedObject;
+    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
+                                                     InputBuffer))
+      return Error("unable to read input: '" + ec.message() + "'");
+
+    // Load the object file
+    LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
+    if (!LoadedObject) {
+      return Error(Dyld.getErrorString());
+    }
+
+    // Resolve all the relocations we can.
+    Dyld.resolveRelocations();
+
+    OwningPtr<DIContext> Context(DIContext::getDWARFContext(LoadedObject->getObjectFile()));
+
+    // Use symbol info to iterate functions in the object.
+    error_code ec;
+    for (object::symbol_iterator I = LoadedObject->begin_symbols(),
+                                 E = LoadedObject->end_symbols();
+                          I != E && !ec;
+                          I.increment(ec)) {
+      object::SymbolRef::Type SymType;
+      if (I->getType(SymType)) continue;
+      if (SymType == object::SymbolRef::ST_Function) {
+        StringRef  Name;
+        uint64_t   Addr;
+        uint64_t   Size;
+        if (I->getName(Name)) continue;
+        if (I->getAddress(Addr)) continue;
+        if (I->getSize(Size)) continue;
+
+        outs() << "Function: " << Name << ", Size = " << Size << "\n";
+
+        DILineInfo Result = Context->getLineInfoForAddress(Addr);
+        outs() << "  Line info:" << Result.getFileName() << ", line:" << Result.getLine() << "\n";
+      }
+    }
+  }
+
+  return 0;
+}
+
 static int executeInput() {
   // Instantiate a dynamic linker.
   TrivialMemoryManager *MemMgr = new TrivialMemoryManager;
@@ -180,5 +238,7 @@ int main(int argc, char **argv) {
   switch (Action) {
   case AC_Execute:
     return executeInput();
+  case AC_PrintLineInfo:
+    return printLineInfoForInput();
   }
 }





More information about the llvm-commits mailing list