[llvm] r184361 - llvm-dwarfdump: Add support for dumping the .debug_loc section

David Blaikie dblaikie at gmail.com
Wed Jun 19 14:37:13 PDT 2013


Author: dblaikie
Date: Wed Jun 19 16:37:13 2013
New Revision: 184361

URL: http://llvm.org/viewvc/llvm-project?rev=184361&view=rev
Log:
llvm-dwarfdump: Add support for dumping the .debug_loc section

This is a basic implementation - we still don't have any support (that I
know of) for dumping DWARF expressions in a meaningful way, so the
location information itself is just printed as a sequence of bytes as we
do elsewhere.

Added:
    llvm/trunk/lib/DebugInfo/DWARFDebugLoc.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugLoc.h
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.cpp
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.o
    llvm/trunk/test/DebugInfo/dwarfdump-debug-loc-simple.test
Modified:
    llvm/trunk/include/llvm/DebugInfo/DIContext.h
    llvm/trunk/lib/DebugInfo/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARFContext.h
    llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp
    llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DIContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DIContext.h?rev=184361&r1=184360&r2=184361&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DIContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DIContext.h Wed Jun 19 16:37:13 2013
@@ -105,6 +105,7 @@ enum DIDumpType {
   DIDT_Info,
   DIDT_InfoDwo,
   DIDT_Line,
+  DIDT_Loc,
   DIDT_Ranges,
   DIDT_Pubnames,
   DIDT_Str,

Modified: llvm/trunk/lib/DebugInfo/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CMakeLists.txt?rev=184361&r1=184360&r2=184361&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/CMakeLists.txt Wed Jun 19 16:37:13 2013
@@ -9,6 +9,7 @@ add_llvm_library(LLVMDebugInfo
   DWARFDebugFrame.cpp
   DWARFDebugInfoEntry.cpp
   DWARFDebugLine.cpp
+  DWARFDebugLoc.cpp
   DWARFDebugRangeList.cpp
   DWARFFormValue.cpp
   )

Modified: llvm/trunk/lib/DebugInfo/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.cpp?rev=184361&r1=184360&r2=184361&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.cpp Wed Jun 19 16:37:13 2013
@@ -35,6 +35,11 @@ void DWARFContext::dump(raw_ostream &OS,
       getCompileUnitAtIndex(i)->dump(OS);
   }
 
+  if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
+    OS << ".debug_loc contents:\n";
+    getDebugLoc()->dump(OS);
+  }
+
   if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
     OS << "\n.debug_frame contents:\n";
     getDebugFrame()->dump(OS);
@@ -171,6 +176,18 @@ const DWARFDebugAbbrev *DWARFContext::ge
   return AbbrevDWO.get();
 }
 
+const DWARFDebugLoc *DWARFContext::getDebugLoc() {
+  if (Loc)
+    return Loc.get();
+
+  DataExtractor LocData(getLocSection(), isLittleEndian(), 0);
+  Loc.reset(new DWARFDebugLoc(locRelocMap()));
+  // assume all compile units have the same address byte size
+  if (getNumCompileUnits())
+    Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
+  return Loc.get();
+}
+
 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
   if (Aranges)
     return Aranges.get();
@@ -542,6 +559,7 @@ DWARFContextInMemory::DWARFContextInMemo
     StringRef *Section = StringSwitch<StringRef*>(name)
         .Case("debug_info", &InfoSection)
         .Case("debug_abbrev", &AbbrevSection)
+        .Case("debug_loc", &LocSection)
         .Case("debug_line", &LineSection)
         .Case("debug_aranges", &ARangeSection)
         .Case("debug_frame", &DebugFrameSection)
@@ -576,6 +594,7 @@ DWARFContextInMemory::DWARFContextInMemo
     // Record relocations for the debug_info and debug_line sections.
     RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
         .Case("debug_info", &InfoRelocMap)
+        .Case("debug_loc", &LocRelocMap)
         .Case("debug_info.dwo", &InfoDWORelocMap)
         .Case("debug_line", &LineRelocMap)
         .Default(0);

Modified: llvm/trunk/lib/DebugInfo/DWARFContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.h?rev=184361&r1=184360&r2=184361&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.h Wed Jun 19 16:37:13 2013
@@ -14,6 +14,7 @@
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugFrame.h"
 #include "DWARFDebugLine.h"
+#include "DWARFDebugLoc.h"
 #include "DWARFDebugRangeList.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
@@ -28,6 +29,7 @@ namespace llvm {
 class DWARFContext : public DIContext {
   SmallVector<DWARFCompileUnit, 1> CUs;
   OwningPtr<DWARFDebugAbbrev> Abbrev;
+  OwningPtr<DWARFDebugLoc> Loc;
   OwningPtr<DWARFDebugAranges> Aranges;
   OwningPtr<DWARFDebugLine> Line;
   OwningPtr<DWARFDebugFrame> DebugFrame;
@@ -80,6 +82,9 @@ public:
   /// Get a pointer to the parsed DebugAbbrev object.
   const DWARFDebugAbbrev *getDebugAbbrev();
 
+  /// Get a pointer to the parsed DebugLoc object.
+  const DWARFDebugLoc *getDebugLoc();
+
   /// Get a pointer to the parsed dwo abbreviations object.
   const DWARFDebugAbbrev *getDebugAbbrevDWO();
 
@@ -104,8 +109,10 @@ public:
   virtual uint8_t getAddressSize() const = 0;
   virtual const RelocAddrMap &infoRelocMap() const = 0;
   virtual const RelocAddrMap &lineRelocMap() const = 0;
+  virtual const RelocAddrMap &locRelocMap() const = 0;
   virtual StringRef getInfoSection() = 0;
   virtual StringRef getAbbrevSection() = 0;
+  virtual StringRef getLocSection() = 0;
   virtual StringRef getARangeSection() = 0;
   virtual StringRef getDebugFrameSection() = 0;
   virtual StringRef getLineSection() = 0;
@@ -142,9 +149,11 @@ class DWARFContextInMemory : public DWAR
   bool IsLittleEndian;
   uint8_t AddressSize;
   RelocAddrMap InfoRelocMap;
+  RelocAddrMap LocRelocMap;
   RelocAddrMap LineRelocMap;
   StringRef InfoSection;
   StringRef AbbrevSection;
+  StringRef LocSection;
   StringRef ARangeSection;
   StringRef DebugFrameSection;
   StringRef LineSection;
@@ -169,9 +178,11 @@ public:
   virtual bool isLittleEndian() const { return IsLittleEndian; }
   virtual uint8_t getAddressSize() const { return AddressSize; }
   virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
+  virtual const RelocAddrMap &locRelocMap() const { return LocRelocMap; }
   virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
   virtual StringRef getInfoSection() { return InfoSection; }
   virtual StringRef getAbbrevSection() { return AbbrevSection; }
+  virtual StringRef getLocSection() { return LocSection; }
   virtual StringRef getARangeSection() { return ARangeSection; }
   virtual StringRef getDebugFrameSection() { return DebugFrameSection; }
   virtual StringRef getLineSection() { return LineSection; }

Added: llvm/trunk/lib/DebugInfo/DWARFDebugLoc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugLoc.cpp?rev=184361&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugLoc.cpp (added)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugLoc.cpp Wed Jun 19 16:37:13 2013
@@ -0,0 +1,74 @@
+//===-- DWARFDebugLoc.cpp -------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugLoc.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+void DWARFDebugLoc::dump(raw_ostream &OS) const {
+  for (LocationLists::const_iterator I = Locations.begin(), E = Locations.end(); I != E; ++I) {
+    OS << format("0x%8.8x: ", I->Offset);
+    const unsigned Indent = 12;
+    for (SmallVectorImpl<Entry>::const_iterator I2 = I->Entries.begin(), E2 = I->Entries.end(); I2 != E2; ++I2) {
+      if (I2 != I->Entries.begin())
+        OS.indent(Indent);
+      OS << "Begining address offset: " << format("0x%016" PRIx64, I2->Begin)
+         << '\n';
+      OS.indent(Indent) << "  Ending address offset: "
+                        << format("0x%016" PRIx64, I2->End) << '\n';
+      OS.indent(Indent) << "   Location description: ";
+      for (SmallVectorImpl<unsigned char>::const_iterator I3 = I2->Loc.begin(), E3 = I2->Loc.end(); I3 != E3; ++I3) {
+        OS << format("%2.2x ", *I3);
+      }
+      OS << "\n\n";
+    }
+  }
+}
+
+void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
+  uint32_t Offset = 0;
+  while (data.isValidOffset(Offset)) {
+    Locations.resize(Locations.size() + 1);
+    LocationList &Loc = Locations.back();
+    Loc.Offset = Offset;
+    // 2.6.2 Location Lists
+    // A location list entry consists of:
+    while (true) {
+      Entry E;
+      RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
+      // 1. A beginning address offset. ...
+      E.Begin = data.getUnsigned(&Offset, AddressSize);
+      if (AI != RelocMap.end())
+        E.Begin += AI->second.second;
+
+      AI = RelocMap.find(Offset);
+      // 2. An ending address offset. ...
+      E.End = data.getUnsigned(&Offset, AddressSize);
+      if (AI != RelocMap.end())
+        E.End += AI->second.second;
+
+      // The end of any given location list is marked by an end of list entry,
+      // which consists of a 0 for the beginning address offset and a 0 for the
+      // ending address offset.
+      if (E.Begin == 0 && E.End == 0)
+        break;
+
+      unsigned Bytes = data.getU16(&Offset);
+      // A single location description describing the location of the object...
+      StringRef str = data.getData().substr(Offset, Bytes);
+      Offset += Bytes;
+      E.Loc.reserve(str.size());
+      std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
+      Loc.Entries.push_back(llvm_move(E));
+    }
+  }
+}

Added: llvm/trunk/lib/DebugInfo/DWARFDebugLoc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugLoc.h?rev=184361&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugLoc.h (added)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugLoc.h Wed Jun 19 16:37:13 2013
@@ -0,0 +1,60 @@
+//===-- DWARFDebugLoc.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_DWARFDEBUGLOC_H
+#define LLVM_DEBUGINFO_DWARFDEBUGLOC_H
+
+#include "DWARFRelocMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataExtractor.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+class DWARFDebugLoc {
+  /// A single location within a location list.
+  struct Entry {
+    /// The beginning address of the instruction range.
+    uint64_t Begin;
+    /// The ending address of the instruction range.
+    uint64_t End;
+    /// The location of the variable within the specified range.
+    SmallVector<unsigned char, 4> Loc;
+  };
+
+  /// A list of locations that contain one variable.
+  struct LocationList {
+    /// The beginning offset where this location list is stored in the debug_loc
+    /// section.
+    unsigned Offset;
+    /// All the locations in which the variable is stored.
+    SmallVector<Entry, 2> Entries;
+  };
+
+  typedef SmallVector<LocationList, 4> LocationLists;
+
+  /// A list of all the variables in the debug_loc section, each one describing
+  /// the locations in which the variable is stored.
+  LocationLists Locations;
+
+  /// A map used to resolve binary relocations.
+  const RelocAddrMap &RelocMap;
+
+public:
+  DWARFDebugLoc(const RelocAddrMap &LocRelocMap) : RelocMap(LocRelocMap) {}
+  /// Print the location lists found within the debug_loc section.
+  void dump(raw_ostream &OS) const;
+  /// Parse the debug_loc section accessible via the 'data' parameter using the
+  /// specified address size to interpret the address ranges.
+  void parse(DataExtractor data, unsigned AddressSize);
+};
+}
+
+#endif

Modified: llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp?rev=184361&r1=184360&r2=184361&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFFormValue.cpp Wed Jun 19 16:37:13 2013
@@ -126,9 +126,13 @@ DWARFFormValue::extractValue(DataExtract
       Value.uval = data.getU16(offset_ptr);
       break;
     case DW_FORM_data4:
-    case DW_FORM_ref4:
+    case DW_FORM_ref4: {
+      RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
       Value.uval = data.getU32(offset_ptr);
+      if (AI != cu->getRelocMap()->end())
+        Value.uval += AI->second.second;
       break;
+    }
     case DW_FORM_data8:
     case DW_FORM_ref8:
       Value.uval = data.getU64(offset_ptr);

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.cpp?rev=184361&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.cpp (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.cpp Wed Jun 19 16:37:13 2013
@@ -0,0 +1,13 @@
+// clang -c -g -o dwarfdump-test-loc-list-32bit.elf.o -m32 dwarfdump-test-loc-list-32bit.elf.cpp
+
+namespace pr14763 {
+struct foo {
+  foo(const foo&);
+};
+
+foo func(bool b, foo f, foo g) {
+  if (b)
+    return f;
+  return g;
+}
+}

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.o?rev=184361&view=auto
==============================================================================
Binary files llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.o (added) and llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test-loc-list-32bit.elf.o Wed Jun 19 16:37:13 2013 differ

Added: llvm/trunk/test/DebugInfo/dwarfdump-debug-loc-simple.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/dwarfdump-debug-loc-simple.test?rev=184361&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/dwarfdump-debug-loc-simple.test (added)
+++ llvm/trunk/test/DebugInfo/dwarfdump-debug-loc-simple.test Wed Jun 19 16:37:13 2013
@@ -0,0 +1,26 @@
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-loc-list-32bit.elf.o | FileCheck %s
+Note: the input file was generated from Inputs/dwarfdump-test-loc-list-32bit.elf.cpp
+
+CHECK: .debug_info
+CHECK: DW_AT_name{{.*}}"f"
+CHECK: DW_AT_location{{.*}}([[F_LOC:0x[0-9a-f]*]])
+CHECK: DW_AT_name{{.*}}"g"
+CHECK: DW_AT_location{{.*}}([[G_LOC:0x[0-9a-f]*]])
+CHECK: .debug_loc contents:
+CHECK-NEXT: [[F_LOC]]: Begining address offset: 0x0000000000000000
+CHECK-NEXT:              Ending address offset: 0x0000000000000023
+this is actually the wrong location due to PR14763, but that doesn't matter for
+the purposes of testing dwarfdump
+CHECK-NEXT:               Location description: 51
+CHECK-NEXT: {{^$}}
+CHECK-NEXT:            Begining address offset: 0x0000000000000023
+CHECK-NEXT:              Ending address offset: 0x000000000000005d
+CHECK-NEXT:               Location description: 75 70
+CHECK-NEXT: {{^$}}
+CHECK-NEXT: [[G_LOC]]: Begining address offset: 0x0000000000000000
+CHECK-NEXT:              Ending address offset: 0x0000000000000020
+CHECK-NEXT:               Location description: 50
+CHECK-NEXT: {{^$}}
+CHECK-NEXT:            Begining address offset: 0x0000000000000020
+CHECK-NEXT:              Ending address offset: 0x000000000000005d
+CHECK-NEXT:               Location description: 75 74

Modified: llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp?rev=184361&r1=184360&r2=184361&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp (original)
+++ llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp Wed Jun 19 16:37:13 2013
@@ -63,6 +63,7 @@ DumpType("debug-dump", cl::init(DIDT_All
         clEnumValN(DIDT_Info, "info", ".debug_info"),
         clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
         clEnumValN(DIDT_Line, "line", ".debug_line"),
+        clEnumValN(DIDT_Loc, "loc", ".debug_loc"),
         clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
         clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
         clEnumValN(DIDT_Pubnames, "pubnames", ".debug_pubnames"),





More information about the llvm-commits mailing list