summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2013-06-19 21:37:13 +0000
committerDavid Blaikie <dblaikie@gmail.com>2013-06-19 21:37:13 +0000
commit3df7d2f70bb316ebeec8a8c862b3da5386fbb145 (patch)
treeefdb44c6da2587da53aee3079c914e688692fc13 /lib
parentba54bca472a15d0657e1b88776f7069042b60b4e (diff)
downloadllvm-3df7d2f70bb316ebeec8a8c862b3da5386fbb145.tar.gz
llvm-3df7d2f70bb316ebeec8a8c862b3da5386fbb145.tar.bz2
llvm-3df7d2f70bb316ebeec8a8c862b3da5386fbb145.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184361 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/DebugInfo/CMakeLists.txt1
-rw-r--r--lib/DebugInfo/DWARFContext.cpp19
-rw-r--r--lib/DebugInfo/DWARFContext.h11
-rw-r--r--lib/DebugInfo/DWARFDebugLoc.cpp74
-rw-r--r--lib/DebugInfo/DWARFDebugLoc.h60
-rw-r--r--lib/DebugInfo/DWARFFormValue.cpp6
6 files changed, 170 insertions, 1 deletions
diff --git a/lib/DebugInfo/CMakeLists.txt b/lib/DebugInfo/CMakeLists.txt
index e97455abac..4a6221d454 100644
--- a/lib/DebugInfo/CMakeLists.txt
+++ b/lib/DebugInfo/CMakeLists.txt
@@ -9,6 +9,7 @@ add_llvm_library(LLVMDebugInfo
DWARFDebugFrame.cpp
DWARFDebugInfoEntry.cpp
DWARFDebugLine.cpp
+ DWARFDebugLoc.cpp
DWARFDebugRangeList.cpp
DWARFFormValue.cpp
)
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index aaae952da5..6ecd0a75a1 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -35,6 +35,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
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::getDebugAbbrevDWO() {
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::DWARFContextInMemory(object::ObjectFile *Obj) :
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::DWARFContextInMemory(object::ObjectFile *Obj) :
// 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);
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index 78c18e6168..af9965fd1d 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -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 DWARFContext {
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; }
diff --git a/lib/DebugInfo/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARFDebugLoc.cpp
new file mode 100644
index 0000000000..46de489204
--- /dev/null
+++ b/lib/DebugInfo/DWARFDebugLoc.cpp
@@ -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));
+ }
+ }
+}
diff --git a/lib/DebugInfo/DWARFDebugLoc.h b/lib/DebugInfo/DWARFDebugLoc.h
new file mode 100644
index 0000000000..d31aaaa127
--- /dev/null
+++ b/lib/DebugInfo/DWARFDebugLoc.h
@@ -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
diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp
index 5f06f43d81..1a1cf2452c 100644
--- a/lib/DebugInfo/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARFFormValue.cpp
@@ -126,9 +126,13 @@ DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
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);