aboutsummaryrefslogtreecommitdiffstats
path: root/lib/DebugInfo
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-01 14:51:49 -0800
committerStephen Hines <srhines@google.com>2014-12-02 16:08:10 -0800
commit37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch)
tree8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /lib/DebugInfo
parentd2327b22152ced7bc46dc629fc908959e8a52d03 (diff)
downloadexternal_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/Android.mk1
-rw-r--r--lib/DebugInfo/CMakeLists.txt1
-rw-r--r--lib/DebugInfo/DIContext.cpp2
-rw-r--r--lib/DebugInfo/DWARFAbbreviationDeclaration.h4
-rw-r--r--lib/DebugInfo/DWARFAcceleratorTable.cpp133
-rw-r--r--lib/DebugInfo/DWARFAcceleratorTable.h51
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.h13
-rw-r--r--lib/DebugInfo/DWARFContext.cpp244
-rw-r--r--lib/DebugInfo/DWARFContext.h91
-rw-r--r--lib/DebugInfo/DWARFDebugAbbrev.cpp4
-rw-r--r--lib/DebugInfo/DWARFDebugAbbrev.h4
-rw-r--r--lib/DebugInfo/DWARFDebugArangeSet.h4
-rw-r--r--lib/DebugInfo/DWARFDebugAranges.h4
-rw-r--r--lib/DebugInfo/DWARFDebugFrame.cpp3
-rw-r--r--lib/DebugInfo/DWARFDebugFrame.h4
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.cpp115
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.h17
-rw-r--r--lib/DebugInfo/DWARFDebugLine.cpp38
-rw-r--r--lib/DebugInfo/DWARFDebugLine.h12
-rw-r--r--lib/DebugInfo/DWARFDebugLoc.h4
-rw-r--r--lib/DebugInfo/DWARFDebugRangeList.h4
-rw-r--r--lib/DebugInfo/DWARFFormValue.cpp44
-rw-r--r--lib/DebugInfo/DWARFRelocMap.h6
-rw-r--r--lib/DebugInfo/DWARFSection.h24
-rw-r--r--lib/DebugInfo/DWARFTypeUnit.h13
-rw-r--r--lib/DebugInfo/DWARFUnit.cpp45
-rw-r--r--lib/DebugInfo/DWARFUnit.h104
27 files changed, 685 insertions, 304 deletions
diff --git a/lib/DebugInfo/Android.mk b/lib/DebugInfo/Android.mk
index 12dfb3b..e777e9c 100644
--- a/lib/DebugInfo/Android.mk
+++ b/lib/DebugInfo/Android.mk
@@ -3,6 +3,7 @@ LOCAL_PATH:= $(call my-dir)
debuginfo_SRC_FILES := \
DIContext.cpp \
DWARFAbbreviationDeclaration.cpp \
+ DWARFAcceleratorTable.cpp \
DWARFCompileUnit.cpp \
DWARFContext.cpp \
DWARFDebugAbbrev.cpp \
diff --git a/lib/DebugInfo/CMakeLists.txt b/lib/DebugInfo/CMakeLists.txt
index 61a3fb0..81fc84d 100644
--- a/lib/DebugInfo/CMakeLists.txt
+++ b/lib/DebugInfo/CMakeLists.txt
@@ -1,6 +1,7 @@
add_llvm_library(LLVMDebugInfo
DIContext.cpp
DWARFAbbreviationDeclaration.cpp
+ DWARFAcceleratorTable.cpp
DWARFCompileUnit.cpp
DWARFContext.cpp
DWARFDebugAbbrev.cpp
diff --git a/lib/DebugInfo/DIContext.cpp b/lib/DebugInfo/DIContext.cpp
index 49a4409..01aecf8 100644
--- a/lib/DebugInfo/DIContext.cpp
+++ b/lib/DebugInfo/DIContext.cpp
@@ -13,6 +13,6 @@ using namespace llvm;
DIContext::~DIContext() {}
-DIContext *DIContext::getDWARFContext(object::ObjectFile *Obj) {
+DIContext *DIContext::getDWARFContext(const object::ObjectFile &Obj) {
return new DWARFContextInMemory(Obj);
}
diff --git a/lib/DebugInfo/DWARFAbbreviationDeclaration.h b/lib/DebugInfo/DWARFAbbreviationDeclaration.h
index b86b9ec..bb05c30 100644
--- a/lib/DebugInfo/DWARFAbbreviationDeclaration.h
+++ b/lib/DebugInfo/DWARFAbbreviationDeclaration.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
-#define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
+#define LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataExtractor.h"
diff --git a/lib/DebugInfo/DWARFAcceleratorTable.cpp b/lib/DebugInfo/DWARFAcceleratorTable.cpp
new file mode 100644
index 0000000..703274d
--- /dev/null
+++ b/lib/DebugInfo/DWARFAcceleratorTable.cpp
@@ -0,0 +1,133 @@
+//===--- DWARFAcceleratorTable.cpp ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFAcceleratorTable.h"
+
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+bool DWARFAcceleratorTable::extract() {
+ uint32_t Offset = 0;
+
+ // Check that we can at least read the header.
+ if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
+ return false;
+
+ Hdr.Magic = AccelSection.getU32(&Offset);
+ Hdr.Version = AccelSection.getU16(&Offset);
+ Hdr.HashFunction = AccelSection.getU16(&Offset);
+ Hdr.NumBuckets = AccelSection.getU32(&Offset);
+ Hdr.NumHashes = AccelSection.getU32(&Offset);
+ Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
+
+ // Check that we can read all the hashes and offsets from the
+ // section (see SourceLevelDebugging.rst for the structure of the index).
+ if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
+ Hdr.NumBuckets*4 + Hdr.NumHashes*8))
+ return false;
+
+ HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
+ uint32_t NumAtoms = AccelSection.getU32(&Offset);
+
+ for (unsigned i = 0; i < NumAtoms; ++i) {
+ uint16_t AtomType = AccelSection.getU16(&Offset);
+ uint16_t AtomForm = AccelSection.getU16(&Offset);
+ HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
+ }
+
+ return true;
+}
+
+void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
+ // Dump the header.
+ OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
+ << "Version = " << format("0x%04x", Hdr.Version) << '\n'
+ << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n'
+ << "Bucket count = " << Hdr.NumBuckets << '\n'
+ << "Hashes count = " << Hdr.NumHashes << '\n'
+ << "HeaderData length = " << Hdr.HeaderDataLength << '\n'
+ << "DIE offset base = " << HdrData.DIEOffsetBase << '\n'
+ << "Number of atoms = " << HdrData.Atoms.size() << '\n';
+
+ unsigned i = 0;
+ SmallVector<DWARFFormValue, 3> AtomForms;
+ for (const auto &Atom: HdrData.Atoms) {
+ OS << format("Atom[%d] Type: ", i++);
+ if (const char *TypeString = dwarf::AtomTypeString(Atom.first))
+ OS << TypeString;
+ else
+ OS << format("DW_ATOM_Unknown_0x%x", Atom.first);
+ OS << " Form: ";
+ if (const char *FormString = dwarf::FormEncodingString(Atom.second))
+ OS << FormString;
+ else
+ OS << format("DW_FORM_Unknown_0x%x", Atom.second);
+ OS << '\n';
+ AtomForms.push_back(DWARFFormValue(Atom.second));
+ }
+
+ // Now go through the actual tables and dump them.
+ uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
+ unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
+ unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
+
+ for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
+ unsigned Index = AccelSection.getU32(&Offset);
+
+ OS << format("Bucket[%d]\n", Bucket);
+ if (Index == UINT32_MAX) {
+ OS << " EMPTY\n";
+ continue;
+ }
+
+ for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
+ unsigned HashOffset = HashesBase + HashIdx*4;
+ unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
+ uint32_t Hash = AccelSection.getU32(&HashOffset);
+
+ if (Hash % Hdr.NumBuckets != Bucket)
+ break;
+
+ unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
+ OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
+ if (!AccelSection.isValidOffset(DataOffset)) {
+ OS << " Invalid section offset\n";
+ continue;
+ }
+ while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
+ unsigned StringOffset = AccelSection.getU32(&DataOffset);
+ RelocAddrMap::const_iterator Reloc = Relocs.find(DataOffset-4);
+ if (Reloc != Relocs.end())
+ StringOffset += Reloc->second.second;
+ if (!StringOffset)
+ break;
+ OS << format(" Name: %08x \"%s\"\n", StringOffset,
+ StringSection.getCStr(&StringOffset));
+ unsigned NumData = AccelSection.getU32(&DataOffset);
+ for (unsigned Data = 0; Data < NumData; ++Data) {
+ OS << format(" Data[%d] => ", Data);
+ unsigned i = 0;
+ for (auto &Atom : AtomForms) {
+ OS << format("{Atom[%d]: ", i++);
+ if (Atom.extractValue(AccelSection, &DataOffset, nullptr))
+ Atom.dump(OS, nullptr);
+ else
+ OS << "Error extracting the value";
+ OS << "} ";
+ }
+ OS << '\n';
+ }
+ }
+ }
+ }
+}
+}
diff --git a/lib/DebugInfo/DWARFAcceleratorTable.h b/lib/DebugInfo/DWARFAcceleratorTable.h
new file mode 100644
index 0000000..7dc9591
--- /dev/null
+++ b/lib/DebugInfo/DWARFAcceleratorTable.h
@@ -0,0 +1,51 @@
+//===--- DWARFAcceleratorTable.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFRelocMap.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/DWARFFormValue.h"
+
+#include <cstdint>
+
+namespace llvm {
+
+class DWARFAcceleratorTable {
+
+ struct Header {
+ uint32_t Magic;
+ uint16_t Version;
+ uint16_t HashFunction;
+ uint32_t NumBuckets;
+ uint32_t NumHashes;
+ uint32_t HeaderDataLength;
+ };
+
+ struct HeaderData {
+ typedef uint16_t AtomType;
+ typedef uint16_t Form;
+ uint32_t DIEOffsetBase;
+ SmallVector<std::pair<AtomType, Form>, 3> Atoms;
+ };
+
+ struct Header Hdr;
+ struct HeaderData HdrData;
+ DataExtractor AccelSection;
+ DataExtractor StringSection;
+ const RelocAddrMap& Relocs;
+public:
+ DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection,
+ const RelocAddrMap &Relocs)
+ : AccelSection(AccelSection), StringSection(StringSection), Relocs(Relocs) {}
+
+ bool extract();
+ void dump(raw_ostream &OS) const;
+};
+
+}
diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h
index 2ed188e..b3190b18 100644
--- a/lib/DebugInfo/DWARFCompileUnit.h
+++ b/lib/DebugInfo/DWARFCompileUnit.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
-#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H
+#define LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H
#include "DWARFUnit.h"
@@ -16,10 +16,11 @@ namespace llvm {
class DWARFCompileUnit : public DWARFUnit {
public:
- DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
- StringRef SS, StringRef SOS, StringRef AOS,
- const RelocAddrMap *M, bool LE)
- : DWARFUnit(DA, IS, RS, SS, SOS, AOS, M, LE) {}
+ DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool LE,
+ const DWARFUnitSectionBase &UnitSection)
+ : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LE, UnitSection) {}
void dump(raw_ostream &OS);
// VTable anchor.
~DWARFCompileUnit() override;
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 3961905..9a2c7cc 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -9,6 +9,7 @@
#include "DWARFContext.h"
#include "DWARFDebugArangeSet.h"
+#include "DWARFAcceleratorTable.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
@@ -59,6 +60,18 @@ static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
}
}
+static void dumpAccelSection(raw_ostream &OS, StringRef Name,
+ const DWARFSection& Section, StringRef StringSection,
+ bool LittleEndian) {
+ DataExtractor AccelSection(Section.Data, LittleEndian, 0);
+ DataExtractor StrData(StringSection, LittleEndian, 0);
+ OS << "\n." << Name << " contents:\n";
+ DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs);
+ if (!Accel.extract())
+ return;
+ Accel.dump(OS);
+}
+
void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
OS << ".debug_abbrev contents:\n";
@@ -86,15 +99,17 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
OS << "\n.debug_types contents:\n";
- for (const auto &TU : type_units())
- TU->dump(OS);
+ for (const auto &TUS : type_unit_sections())
+ for (const auto &TU : TUS)
+ TU->dump(OS);
}
if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
getNumDWOTypeUnits()) {
OS << "\n.debug_types.dwo contents:\n";
- for (const auto &DWOTU : dwo_type_units())
- DWOTU->dump(OS);
+ for (const auto &DWOTUS : dwo_type_unit_sections())
+ for (const auto &DWOTU : DWOTUS)
+ DWOTU->dump(OS);
}
if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
@@ -216,6 +231,22 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
}
}
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
+ dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
+ getStringSection(), isLittleEndian());
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
+ dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
+ getStringSection(), isLittleEndian());
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
+ dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
+ getStringSection(), isLittleEndian());
+
+ if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
+ dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
+ getStringSection(), isLittleEndian());
}
const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
@@ -291,7 +322,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
}
const DWARFLineTable *
-DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
+DWARFContext::getLineTableForUnit(DWARFUnit *cu) {
if (!Line)
Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
@@ -312,110 +343,34 @@ DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
}
void DWARFContext::parseCompileUnits() {
- if (!CUs.empty())
- return;
- uint32_t offset = 0;
- const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
- isLittleEndian(), 0);
- while (DIData.isValidOffset(offset)) {
- std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(
- getDebugAbbrev(), getInfoSection().Data, getRangeSection(),
- getStringSection(), StringRef(), getAddrSection(),
- &getInfoSection().Relocs, isLittleEndian()));
- if (!CU->extract(DIData, &offset)) {
- break;
- }
- CUs.push_back(std::move(CU));
- offset = CUs.back()->getNextUnitOffset();
- }
+ CUs.parse(*this, getInfoSection());
}
void DWARFContext::parseTypeUnits() {
if (!TUs.empty())
return;
for (const auto &I : getTypesSections()) {
- uint32_t offset = 0;
- const DataExtractor &DIData =
- DataExtractor(I.second.Data, isLittleEndian(), 0);
- while (DIData.isValidOffset(offset)) {
- std::unique_ptr<DWARFTypeUnit> TU(
- new DWARFTypeUnit(getDebugAbbrev(), I.second.Data, getRangeSection(),
- getStringSection(), StringRef(), getAddrSection(),
- &I.second.Relocs, isLittleEndian()));
- if (!TU->extract(DIData, &offset))
- break;
- TUs.push_back(std::move(TU));
- offset = TUs.back()->getNextUnitOffset();
- }
+ TUs.push_back(DWARFUnitSection<DWARFTypeUnit>());
+ TUs.back().parse(*this, I.second);
}
}
void DWARFContext::parseDWOCompileUnits() {
- if (!DWOCUs.empty())
- return;
- uint32_t offset = 0;
- const DataExtractor &DIData =
- DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
- while (DIData.isValidOffset(offset)) {
- std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(
- getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(),
- getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
- &getInfoDWOSection().Relocs, isLittleEndian()));
- if (!DWOCU->extract(DIData, &offset)) {
- break;
- }
- DWOCUs.push_back(std::move(DWOCU));
- offset = DWOCUs.back()->getNextUnitOffset();
- }
+ DWOCUs.parseDWO(*this, getInfoDWOSection());
}
void DWARFContext::parseDWOTypeUnits() {
if (!DWOTUs.empty())
return;
for (const auto &I : getTypesDWOSections()) {
- uint32_t offset = 0;
- const DataExtractor &DIData =
- DataExtractor(I.second.Data, isLittleEndian(), 0);
- while (DIData.isValidOffset(offset)) {
- std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(
- getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(),
- getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
- &I.second.Relocs, isLittleEndian()));
- if (!TU->extract(DIData, &offset))
- break;
- DWOTUs.push_back(std::move(TU));
- offset = DWOTUs.back()->getNextUnitOffset();
- }
+ DWOTUs.push_back(DWARFUnitSection<DWARFTypeUnit>());
+ DWOTUs.back().parseDWO(*this, I.second);
}
}
-namespace {
- struct OffsetComparator {
-
- bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
- const std::unique_ptr<DWARFCompileUnit> &RHS) const {
- return LHS->getOffset() < RHS->getOffset();
- }
- bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
- uint32_t RHS) const {
- return LHS->getOffset() < RHS;
- }
- bool operator()(uint32_t LHS,
- const std::unique_ptr<DWARFCompileUnit> &RHS) const {
- return LHS < RHS->getOffset();
- }
- };
-}
-
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
parseCompileUnits();
-
- std::unique_ptr<DWARFCompileUnit> *CU =
- std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator());
- if (CU != CUs.end()) {
- return CU->get();
- }
- return nullptr;
+ return CUs.getUnitForOffset(Offset);
}
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
@@ -425,47 +380,6 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
return getCompileUnitForOffset(CUOffset);
}
-static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
- const DWARFLineTable *LineTable,
- uint64_t FileIndex, FileLineInfoKind Kind,
- std::string &FileName) {
- if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
- !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
- return false;
- if (Kind == FileLineInfoKind::AbsoluteFilePath &&
- sys::path::is_relative(FileName)) {
- // We may still need to append compilation directory of compile unit.
- SmallString<16> AbsolutePath;
- if (const char *CompilationDir = CU->getCompilationDir()) {
- sys::path::append(AbsolutePath, CompilationDir);
- }
- sys::path::append(AbsolutePath, FileName);
- FileName = AbsolutePath.str();
- }
- return true;
-}
-
-static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
- const DWARFLineTable *LineTable,
- uint64_t Address,
- FileLineInfoKind Kind,
- DILineInfo &Result) {
- if (!CU || !LineTable)
- return false;
- // Get the index of row we're looking for in the line table.
- uint32_t RowIndex = LineTable->lookupAddress(Address);
- if (RowIndex == -1U)
- return false;
- // Take file number and line/column from the row.
- const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
- if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
- Result.FileName))
- return false;
- Result.Line = Row.Line;
- Result.Column = Row.Column;
- return true;
-}
-
static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
FunctionNameKind Kind,
std::string &FunctionName) {
@@ -496,8 +410,9 @@ DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
return Result;
getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
if (Spec.FLIKind != FileLineInfoKind::None) {
- const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
- getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
+ if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
+ LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
+ Spec.FLIKind, Result);
}
return Result;
}
@@ -522,7 +437,7 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
return Lines;
}
- const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
+ const DWARFLineTable *LineTable = getLineTableForUnit(CU);
// Get the index of row we're looking for in the line table.
std::vector<uint32_t> RowVector;
@@ -533,8 +448,8 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
// Take file number and line/column from the row.
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
DILineInfo Result;
- getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
- Result.FileName);
+ LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
+ Spec.FLIKind, Result.FileName);
Result.FunctionName = FunctionName;
Result.Line = Row.Line;
Result.Column = Row.Column;
@@ -561,11 +476,11 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
// try to at least get file/line info from symbol table.
if (Spec.FLIKind != FileLineInfoKind::None) {
DILineInfo Frame;
- LineTable = getLineTableForCompileUnit(CU);
- if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
- Frame)) {
+ LineTable = getLineTableForUnit(CU);
+ if (LineTable &&
+ LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
+ Spec.FLIKind, Frame))
InliningInfo.addFrame(Frame);
- }
}
return InliningInfo;
}
@@ -582,15 +497,17 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
if (i == 0) {
// For the topmost frame, initialize the line table of this
// compile unit and fetch file/line info from it.
- LineTable = getLineTableForCompileUnit(CU);
+ LineTable = getLineTableForUnit(CU);
// For the topmost routine, get file/line info from line table.
- getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
- Frame);
+ if (LineTable)
+ LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
+ Spec.FLIKind, Frame);
} else {
// Otherwise, use call file, call line and call column from
// previous DIE in inlined chain.
- getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
- Frame.FileName);
+ if (LineTable)
+ LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
+ Spec.FLIKind, Frame.FileName);
Frame.Line = CallLine;
Frame.Column = CallColumn;
}
@@ -621,12 +538,19 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data,
return true;
}
-DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
- : IsLittleEndian(Obj->isLittleEndian()),
- AddressSize(Obj->getBytesInAddress()) {
- for (const SectionRef &Section : Obj->sections()) {
+DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj)
+ : IsLittleEndian(Obj.isLittleEndian()),
+ AddressSize(Obj.getBytesInAddress()) {
+ for (const SectionRef &Section : Obj.sections()) {
StringRef name;
Section.getName(name);
+ // Skip BSS and Virtual sections, they aren't interesting.
+ bool IsBSS = Section.isBSS();
+ if (IsBSS)
+ continue;
+ bool IsVirtual = Section.isVirtual();
+ if (IsVirtual)
+ continue;
StringRef data;
Section.getContents(data);
@@ -670,6 +594,11 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
.Case("debug_str.dwo", &StringDWOSection)
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
.Case("debug_addr", &AddrSection)
+ .Case("apple_names", &AppleNamesSection.Data)
+ .Case("apple_types", &AppleTypesSection.Data)
+ .Case("apple_namespaces", &AppleNamespacesSection.Data)
+ .Case("apple_namespac", &AppleNamespacesSection.Data)
+ .Case("apple_objc", &AppleObjCSection.Data)
// Any more debug info sections go here.
.Default(nullptr);
if (SectionData) {
@@ -687,7 +616,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
}
section_iterator RelocatedSection = Section.getRelocatedSection();
- if (RelocatedSection == Obj->section_end())
+ if (RelocatedSection == Obj.section_end())
continue;
StringRef RelSecName;
@@ -702,6 +631,11 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
.Case("debug_loc", &LocSection.Relocs)
.Case("debug_info.dwo", &InfoDWOSection.Relocs)
.Case("debug_line", &LineSection.Relocs)
+ .Case("apple_names", &AppleNamesSection.Relocs)
+ .Case("apple_types", &AppleTypesSection.Relocs)
+ .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
+ .Case("apple_namespac", &AppleNamespacesSection.Relocs)
+ .Case("apple_objc", &AppleObjCSection.Relocs)
.Default(nullptr);
if (!Map) {
// Find debug_types relocs by section rather than name as there are
@@ -715,23 +649,19 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
}
if (Section.relocation_begin() != Section.relocation_end()) {
- uint64_t SectionSize;
- RelocatedSection->getSize(SectionSize);
+ uint64_t SectionSize = RelocatedSection->getSize();
for (const RelocationRef &Reloc : Section.relocations()) {
uint64_t Address;
Reloc.getOffset(Address);
uint64_t Type;
Reloc.getType(Type);
uint64_t SymAddr = 0;
- // ELF relocations may need the symbol address
- if (Obj->isELF()) {
- object::symbol_iterator Sym = Reloc.getSymbol();
+ object::symbol_iterator Sym = Reloc.getSymbol();
+ if (Sym != Obj.symbol_end())
Sym->getAddress(SymAddr);
- }
- object::RelocVisitor V(Obj->getFileFormatName());
- // The section address is always 0 for debug sections.
- object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
+ object::RelocVisitor V(Obj);
+ object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
if (V.error()) {
SmallString<32> Name;
std::error_code ec(Reloc.getTypeName(Name));
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index 6d1ae92..dd3fcc7 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===/
-#ifndef LLVM_DEBUGINFO_DWARFCONTEXT_H
-#define LLVM_DEBUGINFO_DWARFCONTEXT_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
+#define LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
#include "DWARFCompileUnit.h"
#include "DWARFDebugAranges.h"
@@ -16,10 +16,12 @@
#include "DWARFDebugLine.h"
#include "DWARFDebugLoc.h"
#include "DWARFDebugRangeList.h"
+#include "DWARFSection.h"
#include "DWARFTypeUnit.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/DIContext.h"
+#include <vector>
namespace llvm {
@@ -28,19 +30,17 @@ namespace llvm {
/// information parsing. The actual data is supplied through pure virtual
/// methods that a concrete implementation provides.
class DWARFContext : public DIContext {
- typedef SmallVector<std::unique_ptr<DWARFCompileUnit>, 1> CUVector;
- typedef SmallVector<std::unique_ptr<DWARFTypeUnit>, 1> TUVector;
- CUVector CUs;
- TUVector TUs;
+ DWARFUnitSection<DWARFCompileUnit> CUs;
+ std::vector<DWARFUnitSection<DWARFTypeUnit>> TUs;
std::unique_ptr<DWARFDebugAbbrev> Abbrev;
std::unique_ptr<DWARFDebugLoc> Loc;
std::unique_ptr<DWARFDebugAranges> Aranges;
std::unique_ptr<DWARFDebugLine> Line;
std::unique_ptr<DWARFDebugFrame> DebugFrame;
- CUVector DWOCUs;
- TUVector DWOTUs;
+ DWARFUnitSection<DWARFCompileUnit> DWOCUs;
+ std::vector<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
@@ -64,11 +64,6 @@ class DWARFContext : public DIContext {
void parseDWOTypeUnits();
public:
- struct Section {
- StringRef Data;
- RelocAddrMap Relocs;
- };
-
DWARFContext() : DIContext(CK_DWARF) {}
static bool classof(const DIContext *DICtx) {
@@ -77,8 +72,9 @@ public:
void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
- typedef iterator_range<CUVector::iterator> cu_iterator_range;
- typedef iterator_range<TUVector::iterator> tu_iterator_range;
+ typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
+ typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
+ typedef iterator_range<std::vector<DWARFUnitSection<DWARFTypeUnit>>::iterator> tu_section_iterator_range;
/// Get compile units in this context.
cu_iterator_range compile_units() {
@@ -87,9 +83,9 @@ public:
}
/// Get type units in this context.
- tu_iterator_range type_units() {
+ tu_section_iterator_range type_unit_sections() {
parseTypeUnits();
- return tu_iterator_range(TUs.begin(), TUs.end());
+ return tu_section_iterator_range(TUs.begin(), TUs.end());
}
/// Get compile units in the DWO context.
@@ -99,9 +95,9 @@ public:
}
/// Get type units in the DWO context.
- tu_iterator_range dwo_type_units() {
+ tu_section_iterator_range dwo_type_unit_sections() {
parseDWOTypeUnits();
- return tu_iterator_range(DWOTUs.begin(), DWOTUs.end());
+ return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end());
}
/// Get the number of compile units in this context.
@@ -159,8 +155,7 @@ public:
const DWARFDebugFrame *getDebugFrame();
/// Get a pointer to a parsed line table corresponding to a compile unit.
- const DWARFDebugLine::LineTable *
- getLineTableForCompileUnit(DWARFCompileUnit *cu);
+ const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
DILineInfo getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
@@ -171,17 +166,15 @@ public:
virtual bool isLittleEndian() const = 0;
virtual uint8_t getAddressSize() const = 0;
- virtual const Section &getInfoSection() = 0;
- typedef MapVector<object::SectionRef, Section,
- std::map<object::SectionRef, unsigned> > TypeSectionMap;
+ virtual const DWARFSection &getInfoSection() = 0;
+ typedef MapVector<object::SectionRef, DWARFSection,
+ std::map<object::SectionRef, unsigned>> TypeSectionMap;
virtual const TypeSectionMap &getTypesSections() = 0;
virtual StringRef getAbbrevSection() = 0;
- virtual const Section &getLocSection() = 0;
- virtual const Section &getLocDWOSection() = 0;
+ virtual const DWARFSection &getLocSection() = 0;
virtual StringRef getARangeSection() = 0;
virtual StringRef getDebugFrameSection() = 0;
- virtual const Section &getLineSection() = 0;
- virtual const Section &getLineDWOSection() = 0;
+ virtual const DWARFSection &getLineSection() = 0;
virtual StringRef getStringSection() = 0;
virtual StringRef getRangeSection() = 0;
virtual StringRef getPubNamesSection() = 0;
@@ -190,13 +183,19 @@ public:
virtual StringRef getGnuPubTypesSection() = 0;
// Sections for DWARF5 split dwarf proposal.
- virtual const Section &getInfoDWOSection() = 0;
+ virtual const DWARFSection &getInfoDWOSection() = 0;
virtual const TypeSectionMap &getTypesDWOSections() = 0;
virtual StringRef getAbbrevDWOSection() = 0;
+ virtual const DWARFSection &getLineDWOSection() = 0;
+ virtual const DWARFSection &getLocDWOSection() = 0;
virtual StringRef getStringDWOSection() = 0;
virtual StringRef getStringOffsetDWOSection() = 0;
virtual StringRef getRangeDWOSection() = 0;
virtual StringRef getAddrSection() = 0;
+ virtual const DWARFSection& getAppleNamesSection() = 0;
+ virtual const DWARFSection& getAppleTypesSection() = 0;
+ virtual const DWARFSection& getAppleNamespacesSection() = 0;
+ virtual const DWARFSection& getAppleObjCSection() = 0;
static bool isSupportedVersion(unsigned version) {
return version == 2 || version == 3 || version == 4;
@@ -217,15 +216,13 @@ class DWARFContextInMemory : public DWARFContext {
virtual void anchor();
bool IsLittleEndian;
uint8_t AddressSize;
- Section InfoSection;
+ DWARFSection InfoSection;
TypeSectionMap TypesSections;
StringRef AbbrevSection;
- Section LocSection;
- Section LocDWOSection;
+ DWARFSection LocSection;
StringRef ARangeSection;
StringRef DebugFrameSection;
- Section LineSection;
- Section LineDWOSection;
+ DWARFSection LineSection;
StringRef StringSection;
StringRef RangeSection;
StringRef PubNamesSection;
@@ -234,42 +231,52 @@ class DWARFContextInMemory : public DWARFContext {
StringRef GnuPubTypesSection;
// Sections for DWARF5 split dwarf proposal.
- Section InfoDWOSection;
+ DWARFSection InfoDWOSection;
TypeSectionMap TypesDWOSections;
StringRef AbbrevDWOSection;
+ DWARFSection LineDWOSection;
+ DWARFSection LocDWOSection;
StringRef StringDWOSection;
StringRef StringOffsetDWOSection;
StringRef RangeDWOSection;
StringRef AddrSection;
+ DWARFSection AppleNamesSection;
+ DWARFSection AppleTypesSection;
+ DWARFSection AppleNamespacesSection;
+ DWARFSection AppleObjCSection;
SmallVector<SmallString<32>, 4> UncompressedSections;
public:
- DWARFContextInMemory(object::ObjectFile *);
+ DWARFContextInMemory(const object::ObjectFile &Obj);
bool isLittleEndian() const override { return IsLittleEndian; }
uint8_t getAddressSize() const override { return AddressSize; }
- const Section &getInfoSection() override { return InfoSection; }
+ const DWARFSection &getInfoSection() override { return InfoSection; }
const TypeSectionMap &getTypesSections() override { return TypesSections; }
StringRef getAbbrevSection() override { return AbbrevSection; }
- const Section &getLocSection() override { return LocSection; }
- const Section &getLocDWOSection() override { return LocDWOSection; }
+ const DWARFSection &getLocSection() override { return LocSection; }
StringRef getARangeSection() override { return ARangeSection; }
StringRef getDebugFrameSection() override { return DebugFrameSection; }
- const Section &getLineSection() override { return LineSection; }
- const Section &getLineDWOSection() override { return LineDWOSection; }
+ const DWARFSection &getLineSection() override { return LineSection; }
StringRef getStringSection() override { return StringSection; }
StringRef getRangeSection() override { return RangeSection; }
StringRef getPubNamesSection() override { return PubNamesSection; }
StringRef getPubTypesSection() override { return PubTypesSection; }
StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
+ const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; }
+ const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; }
+ const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
+ const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
// Sections for DWARF5 split dwarf proposal.
- const Section &getInfoDWOSection() override { return InfoDWOSection; }
+ const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
const TypeSectionMap &getTypesDWOSections() override {
return TypesDWOSections;
}
StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
+ const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
+ const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
StringRef getStringDWOSection() override { return StringDWOSection; }
StringRef getStringOffsetDWOSection() override {
return StringOffsetDWOSection;
diff --git a/lib/DebugInfo/DWARFDebugAbbrev.cpp b/lib/DebugInfo/DWARFDebugAbbrev.cpp
index 8426bf9..c1a088e 100644
--- a/lib/DebugInfo/DWARFDebugAbbrev.cpp
+++ b/lib/DebugInfo/DWARFDebugAbbrev.cpp
@@ -30,7 +30,6 @@ bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
DWARFAbbreviationDeclaration AbbrDecl;
uint32_t PrevAbbrCode = 0;
while (AbbrDecl.extract(Data, OffsetPtr)) {
- Decls.push_back(AbbrDecl);
if (FirstAbbrCode == 0) {
FirstAbbrCode = AbbrDecl.getCode();
} else {
@@ -40,6 +39,7 @@ bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
}
}
PrevAbbrCode = AbbrDecl.getCode();
+ Decls.push_back(std::move(AbbrDecl));
}
return BeginOffset != *OffsetPtr;
}
@@ -82,7 +82,7 @@ void DWARFDebugAbbrev::extract(DataExtractor Data) {
uint32_t CUAbbrOffset = Offset;
if (!AbbrDecls.extract(Data, &Offset))
break;
- AbbrDeclSets[CUAbbrOffset] = AbbrDecls;
+ AbbrDeclSets[CUAbbrOffset] = std::move(AbbrDecls);
}
}
diff --git a/lib/DebugInfo/DWARFDebugAbbrev.h b/lib/DebugInfo/DWARFDebugAbbrev.h
index 3a9adba..4b3b814 100644
--- a/lib/DebugInfo/DWARFDebugAbbrev.h
+++ b/lib/DebugInfo/DWARFDebugAbbrev.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGABBREV_H
-#define LLVM_DEBUGINFO_DWARFDEBUGABBREV_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H
#include "DWARFAbbreviationDeclaration.h"
#include <list>
diff --git a/lib/DebugInfo/DWARFDebugArangeSet.h b/lib/DebugInfo/DWARFDebugArangeSet.h
index d6c2d8b..837a8e6 100644
--- a/lib/DebugInfo/DWARFDebugArangeSet.h
+++ b/lib/DebugInfo/DWARFDebugArangeSet.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
-#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/DataExtractor.h"
diff --git a/lib/DebugInfo/DWARFDebugAranges.h b/lib/DebugInfo/DWARFDebugAranges.h
index a9f37fe..791f010 100644
--- a/lib/DebugInfo/DWARFDebugAranges.h
+++ b/lib/DebugInfo/DWARFDebugAranges.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
-#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/DataExtractor.h"
diff --git a/lib/DebugInfo/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARFDebugFrame.cpp
index a33548e..dfa7e82 100644
--- a/lib/DebugInfo/DWARFDebugFrame.cpp
+++ b/lib/DebugInfo/DWARFDebugFrame.cpp
@@ -202,7 +202,8 @@ public:
SmallString<8> Augmentation, uint64_t CodeAlignmentFactor,
int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
: FrameEntry(FK_CIE, Offset, Length), Version(Version),
- Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor),
+ Augmentation(std::move(Augmentation)),
+ CodeAlignmentFactor(CodeAlignmentFactor),
DataAlignmentFactor(DataAlignmentFactor),
ReturnAddressRegister(ReturnAddressRegister) {}
diff --git a/lib/DebugInfo/DWARFDebugFrame.h b/lib/DebugInfo/DWARFDebugFrame.h
index bd4ef45..be925cb 100644
--- a/lib/DebugInfo/DWARFDebugFrame.h
+++ b/lib/DebugInfo/DWARFDebugFrame.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGFRAME_H
-#define LLVM_DEBUGINFO_DWARFDEBUGFRAME_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index 2e7a54a..583e700 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -12,15 +12,26 @@
#include "DWARFContext.h"
#include "DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARFFormValue.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace dwarf;
-typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
-void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
+// Small helper to extract a DIE pointed by a reference
+// attribute. It looks up the Unit containing the DIE and calls
+// DIE.extractFast with the right unit. Returns new unit on success,
+// nullptr otherwise.
+static const DWARFUnit *findUnitAndExtractFast(DWARFDebugInfoEntryMinimal &DIE,
+ const DWARFUnit *Unit,
+ uint32_t *Offset) {
+ Unit = Unit->getUnitSection().getUnitForOffset(*Offset);
+ return (Unit && DIE.extractFast(Unit, Offset)) ? Unit : nullptr;
+}
+
+void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u,
unsigned recurseDepth,
unsigned indent) const {
DataExtractor debug_info_data = u->getDebugInfoExtractor();
@@ -62,12 +73,42 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
}
}
+static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
+ OS << " (";
+ do {
+ uint64_t Bit = 1ULL << countTrailingZeros(Val);
+ if (const char *PropName = ApplePropertyString(Bit))
+ OS << PropName;
+ else
+ OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
+ if (!(Val ^= Bit))
+ break;
+ OS << ", ";
+ } while (true);
+ OS << ")";
+}
+
+static void dumpRanges(raw_ostream &OS, const DWARFAddressRangesVector& Ranges,
+ unsigned AddressSize, unsigned Indent) {
+ if (Ranges.empty())
+ return;
+
+ for (const auto &Range: Ranges) {
+ OS << '\n';
+ OS.indent(Indent);
+ OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")",
+ AddressSize*2, Range.first,
+ AddressSize*2, Range.second);
+ }
+}
+
void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
- const DWARFUnit *u,
+ DWARFUnit *u,
uint32_t *offset_ptr,
uint16_t attr, uint16_t form,
unsigned indent) const {
- OS << " ";
+ const char BaseIndent[] = " ";
+ OS << BaseIndent;
OS.indent(indent+2);
const char *attrString = AttributeString(attr);
if (attrString)
@@ -86,7 +127,48 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
return;
OS << "\t(";
- formValue.dump(OS, u);
+
+ const char *Name = nullptr;
+ std::string File;
+ if (attr == DW_AT_decl_file || attr == DW_AT_call_file) {
+ if (const auto *LT = u->getContext().getLineTableForUnit(u))
+ if (LT->getFileNameByIndex(
+ formValue.getAsUnsignedConstant().getValue(),
+ u->getCompilationDir(),
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
+ File = '"' + File + '"';
+ Name = File.c_str();
+ }
+ } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
+ Name = AttributeValueString(attr, *Val);
+
+ if (Name) {
+ OS << Name;
+ } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) {
+ OS << *formValue.getAsUnsignedConstant();
+ } else {
+ formValue.dump(OS, u);
+ }
+
+ // We have dumped the attribute raw value. For some attributes
+ // having both the raw value and the pretty-printed value is
+ // interesting. These attributes are handled below.
+ if ((attr == DW_AT_specification || attr == DW_AT_abstract_origin) &&
+ // The signature references aren't handled.
+ formValue.getForm() != DW_FORM_ref_sig8) {
+ uint32_t Ref = formValue.getAsReference(u).getValue();
+ DWARFDebugInfoEntryMinimal DIE;
+ if (const DWARFUnit *RefU = findUnitAndExtractFast(DIE, u, &Ref))
+ if (const char *Ref = DIE.getName(RefU, DINameKind::LinkageName))
+ OS << " \"" << Ref << '\"';
+ } else if (attr == DW_AT_APPLE_property_attribute) {
+ if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
+ dumpApplePropertyAttribute(OS, *OptVal);
+ } else if (attr == DW_AT_ranges) {
+ dumpRanges(OS, getAddressRanges(u), u->getAddressByteSize(),
+ sizeof(BaseIndent)+indent+4);
+ }
+
OS << ")\n";
}
@@ -284,11 +366,19 @@ bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
const char *
DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
- FunctionNameKind Kind) const {
- if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
+ DINameKind Kind) const {
+ if (!isSubroutineDIE())
+ return nullptr;
+ return getName(U, Kind);
+}
+
+const char *
+DWARFDebugInfoEntryMinimal::getName(const DWARFUnit *U,
+ DINameKind Kind) const {
+ if (Kind == DINameKind::None)
return nullptr;
// Try to get mangled name only if it was asked for.
- if (Kind == FunctionNameKind::LinkageName) {
+ if (Kind == DINameKind::LinkageName) {
if (const char *name =
getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
return name;
@@ -303,8 +393,8 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
getAttributeValueAsReference(U, DW_AT_specification, -1U);
if (spec_ref != -1U) {
DWARFDebugInfoEntryMinimal spec_die;
- if (spec_die.extractFast(U, &spec_ref)) {
- if (const char *name = spec_die.getSubroutineName(U, Kind))
+ if (const DWARFUnit *RefU = findUnitAndExtractFast(spec_die, U, &spec_ref)) {
+ if (const char *name = spec_die.getName(RefU, Kind))
return name;
}
}
@@ -313,8 +403,9 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
if (abs_origin_ref != -1U) {
DWARFDebugInfoEntryMinimal abs_origin_die;
- if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
- if (const char *name = abs_origin_die.getSubroutineName(U, Kind))
+ if (const DWARFUnit *RefU = findUnitAndExtractFast(abs_origin_die, U,
+ &abs_origin_ref)) {
+ if (const char *name = abs_origin_die.getName(RefU, Kind))
return name;
}
}
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.h b/lib/DebugInfo/DWARFDebugInfoEntry.h
index cc58eb6..7e7efb9 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.h
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
-#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H
#include "DWARFAbbreviationDeclaration.h"
#include "DWARFDebugRangeList.h"
@@ -38,9 +38,9 @@ public:
DWARFDebugInfoEntryMinimal()
: Offset(0), SiblingIdx(0), AbbrevDecl(nullptr) {}
- void dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth,
+ void dump(raw_ostream &OS, DWARFUnit *u, unsigned recurseDepth,
unsigned indent = 0) const;
- void dumpAttribute(raw_ostream &OS, const DWARFUnit *u, uint32_t *offset_ptr,
+ void dumpAttribute(raw_ostream &OS, DWARFUnit *u, uint32_t *offset_ptr,
uint16_t attr, uint16_t form, unsigned indent = 0) const;
/// Extracts a debug info entry, which is a child of a given unit,
@@ -125,9 +125,12 @@ public:
/// returns its mangled name (or short name, if mangled is missing).
/// This name may be fetched from specification or abstract origin
/// for this subprogram. Returns null if no name is found.
- const char *
- getSubroutineName(const DWARFUnit *U,
- DILineInfoSpecifier::FunctionNameKind Kind) const;
+ const char *getSubroutineName(const DWARFUnit *U, DINameKind Kind) const;
+
+ /// Return the DIE name resolving DW_AT_sepcification or
+ /// DW_AT_abstract_origin references if necessary.
+ /// Returns null if no name is found.
+ const char *getName(const DWARFUnit *U, DINameKind Kind) const;
/// Retrieves values of DW_AT_call_file, DW_AT_call_line and
/// DW_AT_call_column from DIE (or zeroes if they are missing).
diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp
index ce87635..a6ee461 100644
--- a/lib/DebugInfo/DWARFDebugLine.cpp
+++ b/lib/DebugInfo/DWARFDebugLine.cpp
@@ -644,6 +644,7 @@ bool DWARFDebugLine::LineTable::lookupAddressRange(
bool
DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
+ const char *CompDir,
FileLineInfoKind Kind,
std::string &Result) const {
if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
@@ -656,15 +657,42 @@ DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
Result = FileName;
return true;
}
+
SmallString<16> FilePath;
uint64_t IncludeDirIndex = Entry.DirIdx;
+ const char *IncludeDir = "";
// Be defensive about the contents of Entry.
if (IncludeDirIndex > 0 &&
- IncludeDirIndex <= Prologue.IncludeDirectories.size()) {
- const char *IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1];
- sys::path::append(FilePath, IncludeDir);
- }
- sys::path::append(FilePath, FileName);
+ IncludeDirIndex <= Prologue.IncludeDirectories.size())
+ IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1];
+
+ // We may still need to append compilation directory of compile unit.
+ // We know that FileName is not absolute, the only way to have an
+ // absolute path at this point would be if IncludeDir is absolute.
+ if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath &&
+ sys::path::is_relative(IncludeDir))
+ sys::path::append(FilePath, CompDir);
+
+ // sys::path::append skips empty strings.
+ sys::path::append(FilePath, IncludeDir, FileName);
Result = FilePath.str();
return true;
}
+
+bool
+DWARFDebugLine::LineTable::getFileLineInfoForAddress(uint64_t Address,
+ const char *CompDir,
+ FileLineInfoKind Kind,
+ DILineInfo &Result) const {
+ // Get the index of row we're looking for in the line table.
+ uint32_t RowIndex = lookupAddress(Address);
+ if (RowIndex == -1U)
+ return false;
+ // Take file number and line/column from the row.
+ const auto &Row = Rows[RowIndex];
+ if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
+ return false;
+ Result.Line = Row.Line;
+ Result.Column = Row.Column;
+ return true;
+}
diff --git a/lib/DebugInfo/DWARFDebugLine.h b/lib/DebugInfo/DWARFDebugLine.h
index c7b7ec2..7a6f1bd 100644
--- a/lib/DebugInfo/DWARFDebugLine.h
+++ b/lib/DebugInfo/DWARFDebugLine.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H
-#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H
#include "DWARFRelocMap.h"
#include "llvm/DebugInfo/DIContext.h"
@@ -179,10 +179,16 @@ public:
// Extracts filename by its index in filename table in prologue.
// Returns true on success.
- bool getFileNameByIndex(uint64_t FileIndex,
+ bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
std::string &Result) const;
+ // Fills the Result argument with the file and line information
+ // corresponding to Address. Returns true on success.
+ bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir,
+ DILineInfoSpecifier::FileLineInfoKind Kind,
+ DILineInfo &Result) const;
+
void dump(raw_ostream &OS) const;
void clear();
diff --git a/lib/DebugInfo/DWARFDebugLoc.h b/lib/DebugInfo/DWARFDebugLoc.h
index 663acbb4..50110b3 100644
--- a/lib/DebugInfo/DWARFDebugLoc.h
+++ b/lib/DebugInfo/DWARFDebugLoc.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGLOC_H
-#define LLVM_DEBUGINFO_DWARFDEBUGLOC_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H
#include "DWARFRelocMap.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/lib/DebugInfo/DWARFDebugRangeList.h b/lib/DebugInfo/DWARFDebugRangeList.h
index 587b550..4ee3bda 100644
--- a/lib/DebugInfo/DWARFDebugRangeList.h
+++ b/lib/DebugInfo/DWARFDebugRangeList.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H
-#define LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H
+#define LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H
#include "llvm/Support/DataExtractor.h"
#include <vector>
diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp
index 8d0f966..69b9771 100644
--- a/lib/DebugInfo/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARFFormValue.cpp
@@ -139,6 +139,8 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
switch (Form) {
case DW_FORM_addr:
case DW_FORM_ref_addr: {
+ if (!cu)
+ return false;
uint16_t AddrSize =
(Form == DW_FORM_addr)
? cu->getAddressByteSize()
@@ -179,8 +181,10 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
break;
case DW_FORM_data4:
case DW_FORM_ref4: {
- RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
Value.uval = data.getU32(offset_ptr);
+ if (!cu)
+ break;
+ RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
if (AI != cu->getRelocMap()->end())
Value.uval += AI->second.second;
break;
@@ -193,13 +197,12 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
Value.sval = data.getSLEB128(offset_ptr);
break;
case DW_FORM_strp: {
- RelocAddrMap::const_iterator AI
- = cu->getRelocMap()->find(*offset_ptr);
- if (AI != cu->getRelocMap()->end()) {
- const std::pair<uint8_t, int64_t> &R = AI->second;
- Value.uval = data.getU32(offset_ptr) + R.second;
- } else
- Value.uval = data.getU32(offset_ptr);
+ Value.uval = data.getU32(offset_ptr);
+ if (!cu)
+ break;
+ RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
+ if (AI != cu->getRelocMap()->end())
+ Value.uval += AI->second.second;
break;
}
case DW_FORM_udata:
@@ -215,13 +218,12 @@ bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
break;
case DW_FORM_sec_offset: {
// FIXME: This is 64-bit for DWARF64.
- RelocAddrMap::const_iterator AI
- = cu->getRelocMap()->find(*offset_ptr);
- if (AI != cu->getRelocMap()->end()) {
- const std::pair<uint8_t, int64_t> &R = AI->second;
- Value.uval = data.getU32(offset_ptr) + R.second;
- } else
- Value.uval = data.getU32(offset_ptr);
+ Value.uval = data.getU32(offset_ptr);
+ if (!cu)
+ break;
+ RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4);
+ if (AI != cu->getRelocMap()->end())
+ Value.uval += AI->second.second;
break;
}
case DW_FORM_flag_present:
@@ -360,8 +362,6 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
void
DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const {
- DataExtractor debug_str_data(cu->getStringSection(), true, 0);
- DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0);
uint64_t uvalue = Value.uval;
bool cu_relative_offset = false;
@@ -543,7 +543,15 @@ Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
}
Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
- if (!isFormClass(FC_Constant) || Form == DW_FORM_sdata)
+ if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag))
+ || Form == DW_FORM_sdata)
return None;
return Value.uval;
}
+
+Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
+ if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc))
+ return None;
+ return ArrayRef<uint8_t>(Value.data, Value.uval);
+}
+
diff --git a/lib/DebugInfo/DWARFRelocMap.h b/lib/DebugInfo/DWARFRelocMap.h
index 6929e36..d7fe303 100644
--- a/lib/DebugInfo/DWARFRelocMap.h
+++ b/lib/DebugInfo/DWARFRelocMap.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFRELOCMAP_H
-#define LLVM_DEBUGINFO_DWARFRELOCMAP_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H
+#define LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H
#include "llvm/ADT/DenseMap.h"
@@ -18,5 +18,5 @@ typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
} // namespace llvm
-#endif // LLVM_DEBUGINFO_DWARFRELOCMAP_H
+#endif
diff --git a/lib/DebugInfo/DWARFSection.h b/lib/DebugInfo/DWARFSection.h
new file mode 100644
index 0000000..3aaf0ff
--- /dev/null
+++ b/lib/DebugInfo/DWARFSection.h
@@ -0,0 +1,24 @@
+//===-- DWARFSection.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_LIB_DEBUGINFO_DWARFSECTION_H
+#define LLVM_LIB_DEBUGINFO_DWARFSECTION_H
+
+#include "DWARFRelocMap.h"
+
+namespace llvm {
+
+struct DWARFSection {
+ StringRef Data;
+ RelocAddrMap Relocs;
+};
+
+}
+
+#endif
diff --git a/lib/DebugInfo/DWARFTypeUnit.h b/lib/DebugInfo/DWARFTypeUnit.h
index cf773b8..7471b5a 100644
--- a/lib/DebugInfo/DWARFTypeUnit.h
+++ b/lib/DebugInfo/DWARFTypeUnit.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFTYPEUNIT_H
-#define LLVM_DEBUGINFO_DWARFTYPEUNIT_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H
+#define LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H
#include "DWARFUnit.h"
@@ -19,10 +19,11 @@ private:
uint64_t TypeHash;
uint32_t TypeOffset;
public:
- DWARFTypeUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
- StringRef SS, StringRef SOS, StringRef AOS,
- const RelocAddrMap *M, bool LE)
- : DWARFUnit(DA, IS, RS, SS, SOS, AOS, M, LE) {}
+ DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool LE,
+ const DWARFUnitSectionBase &UnitSection)
+ : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LE, UnitSection) {}
uint32_t getHeaderSize() const override {
return DWARFUnit::getHeaderSize() + 12;
}
diff --git a/lib/DebugInfo/DWARFUnit.cpp b/lib/DebugInfo/DWARFUnit.cpp
index 39d0a0f..82c4529 100644
--- a/lib/DebugInfo/DWARFUnit.cpp
+++ b/lib/DebugInfo/DWARFUnit.cpp
@@ -17,12 +17,26 @@
using namespace llvm;
using namespace dwarf;
-DWARFUnit::DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
- StringRef SS, StringRef SOS, StringRef AOS,
- const RelocAddrMap *M, bool LE)
- : Abbrev(DA), InfoSection(IS), RangeSection(RS), StringSection(SS),
- StringOffsetSection(SOS), AddrOffsetSection(AOS), RelocMap(M),
- isLittleEndian(LE) {
+void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
+ parseImpl(C, Section, C.getDebugAbbrev(), C.getRangeSection(),
+ C.getStringSection(), StringRef(), C.getAddrSection(),
+ C.isLittleEndian());
+}
+
+void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
+ const DWARFSection &DWOSection) {
+ parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), C.getRangeDWOSection(),
+ C.getStringDWOSection(), C.getStringOffsetDWOSection(),
+ C.getAddrSection(), C.isLittleEndian());
+}
+
+DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool LE,
+ const DWARFUnitSectionBase &UnitSection)
+ : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
+ StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
+ isLittleEndian(LE), UnitSection(UnitSection) {
clear();
}
@@ -235,10 +249,14 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
return DieArray.size();
}
-DWARFUnit::DWOHolder::DWOHolder(object::ObjectFile *DWOFile)
- : DWOFile(DWOFile),
- DWOContext(cast<DWARFContext>(DIContext::getDWARFContext(DWOFile))),
- DWOU(nullptr) {
+DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath)
+ : DWOFile(), DWOContext(), DWOU(nullptr) {
+ auto Obj = object::ObjectFile::createObjectFile(DWOPath);
+ if (!Obj)
+ return;
+ DWOFile = std::move(Obj.get());
+ DWOContext.reset(
+ cast<DWARFContext>(DIContext::getDWARFContext(*DWOFile.getBinary())));
if (DWOContext->getNumDWOCompileUnits() > 0)
DWOU = DWOContext->getDWOCompileUnitAtIndex(0);
}
@@ -260,12 +278,7 @@ bool DWARFUnit::parseDWO() {
sys::path::append(AbsolutePath, CompilationDir);
}
sys::path::append(AbsolutePath, DWOFileName);
- ErrorOr<object::ObjectFile *> DWOFile =
- object::ObjectFile::createObjectFile(AbsolutePath);
- if (!DWOFile)
- return false;
- // Reset DWOHolder.
- DWO.reset(new DWOHolder(DWOFile.get()));
+ DWO = llvm::make_unique<DWOHolder>(AbsolutePath);
DWARFUnit *DWOCU = DWO->getUnit();
// Verify that compile unit in .dwo file is valid.
if (!DWOCU || DWOCU->getDWOId() != getDWOId()) {
diff --git a/lib/DebugInfo/DWARFUnit.h b/lib/DebugInfo/DWARFUnit.h
index 471da36..786f00f 100644
--- a/lib/DebugInfo/DWARFUnit.h
+++ b/lib/DebugInfo/DWARFUnit.h
@@ -7,13 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_DWARFUNIT_H
-#define LLVM_DEBUGINFO_DWARFUNIT_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H
+#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugRangeList.h"
#include "DWARFRelocMap.h"
+#include "DWARFSection.h"
#include <vector>
namespace llvm {
@@ -22,21 +23,96 @@ namespace object {
class ObjectFile;
}
+class DWARFContext;
class DWARFDebugAbbrev;
+class DWARFUnit;
class StringRef;
class raw_ostream;
+/// Base class for all DWARFUnitSection classes. This provides the
+/// functionality common to all unit types.
+class DWARFUnitSectionBase {
+public:
+ /// Returns the Unit that contains the given section offset in the
+ /// same section this Unit originated from.
+ virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
+
+ void parse(DWARFContext &C, const DWARFSection &Section);
+ void parseDWO(DWARFContext &C, const DWARFSection &DWOSection);
+
+protected:
+ virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool isLittleEndian) = 0;
+
+ ~DWARFUnitSectionBase() {}
+};
+
+/// Concrete instance of DWARFUnitSection, specialized for one Unit type.
+template<typename UnitType>
+class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
+ public DWARFUnitSectionBase {
+
+ struct UnitOffsetComparator {
+ bool operator()(uint32_t LHS,
+ const std::unique_ptr<UnitType> &RHS) const {
+ return LHS < RHS->getNextUnitOffset();
+ }
+ };
+
+ bool Parsed;
+
+public:
+ DWARFUnitSection() : Parsed(false) {}
+ DWARFUnitSection(DWARFUnitSection &&DUS) :
+ SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)), Parsed(DUS.Parsed) {}
+
+ typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
+ typedef typename UnitVector::iterator iterator;
+ typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
+
+ UnitType *getUnitForOffset(uint32_t Offset) const override {
+ auto *CU = std::upper_bound(this->begin(), this->end(), Offset,
+ UnitOffsetComparator());
+ if (CU != this->end())
+ return CU->get();
+ return nullptr;
+ }
+
+private:
+ void parseImpl(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool LE) override {
+ if (Parsed)
+ return;
+ DataExtractor Data(Section.Data, LE, 0);
+ uint32_t Offset = 0;
+ while (Data.isValidOffset(Offset)) {
+ auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
+ AOS, LE, *this);
+ if (!U->extract(Data, &Offset))
+ break;
+ this->push_back(std::move(U));
+ Offset = this->back()->getNextUnitOffset();
+ }
+ Parsed = true;
+ }
+};
+
class DWARFUnit {
+ DWARFContext &Context;
+ // Section containing this DWARFUnit.
+ const DWARFSection &InfoSection;
+
const DWARFDebugAbbrev *Abbrev;
- StringRef InfoSection;
StringRef RangeSection;
uint32_t RangeSectionBase;
StringRef StringSection;
StringRef StringOffsetSection;
StringRef AddrOffsetSection;
uint32_t AddrOffsetSectionBase;
- const RelocAddrMap *RelocMap;
bool isLittleEndian;
+ const DWARFUnitSectionBase &UnitSection;
uint32_t Offset;
uint32_t Length;
@@ -48,11 +124,11 @@ class DWARFUnit {
std::vector<DWARFDebugInfoEntryMinimal> DieArray;
class DWOHolder {
- std::unique_ptr<object::ObjectFile> DWOFile;
+ object::OwningBinary<object::ObjectFile> DWOFile;
std::unique_ptr<DWARFContext> DWOContext;
DWARFUnit *DWOU;
public:
- DWOHolder(object::ObjectFile *DWOFile);
+ DWOHolder(StringRef DWOPath);
DWARFUnit *getUnit() const { return DWOU; }
};
std::unique_ptr<DWOHolder> DWO;
@@ -63,12 +139,15 @@ protected:
virtual uint32_t getHeaderSize() const { return 11; }
public:
- DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
- StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M,
- bool LE);
+ DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
+ StringRef SOS, StringRef AOS, bool LE,
+ const DWARFUnitSectionBase &UnitSection);
virtual ~DWARFUnit();
+ DWARFContext& getContext() const { return Context; }
+
StringRef getStringSection() const { return StringSection; }
StringRef getStringOffsetSection() const { return StringOffsetSection; }
void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
@@ -85,13 +164,13 @@ public:
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
DataExtractor getDebugInfoExtractor() const {
- return DataExtractor(InfoSection, isLittleEndian, AddrSize);
+ return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
}
DataExtractor getStringExtractor() const {
return DataExtractor(StringSection, false, 0);
}
- const RelocAddrMap *getRelocMap() const { return RelocMap; }
+ const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
@@ -131,6 +210,9 @@ public:
/// chain is valid as long as parsed compile unit DIEs are not cleared.
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
+ /// getUnitSection - Return the DWARFUnitSection containing this unit.
+ const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
+
private:
/// Size in bytes of the .debug_info data associated with this compile unit.
size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }