summaryrefslogtreecommitdiff
path: root/lib/DebugInfo/DWARF
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo/DWARF')
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp112
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugFrame.cpp209
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLine.cpp77
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLoc.cpp1
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugMacro.cpp3
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnit.cpp37
-rw-r--r--lib/DebugInfo/DWARF/Makefile14
-rw-r--r--lib/DebugInfo/DWARF/module.modulemap1
8 files changed, 328 insertions, 126 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp
index a4195b75c47d9..e8ea71b325ae3 100644
--- a/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -13,8 +13,11 @@
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/RelocVisitor.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/ELF.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
@@ -72,7 +75,7 @@ static void dumpAccelSection(raw_ostream &OS, StringRef Name,
Accel.dump(OS);
}
-void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
+void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH) {
if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
OS << ".debug_abbrev contents:\n";
getDebugAbbrev()->dump(OS);
@@ -125,6 +128,10 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
OS << "\n.debug_frame contents:\n";
getDebugFrame()->dump(OS);
+ if (DumpEH) {
+ OS << "\n.eh_frame contents:\n";
+ getEHFrame()->dump(OS);
+ }
}
if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
@@ -355,7 +362,18 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
getAddressSize());
- DebugFrame.reset(new DWARFDebugFrame());
+ DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
+ DebugFrame->parse(debugFrameData);
+ return DebugFrame.get();
+}
+
+const DWARFDebugFrame *DWARFContext::getEHFrame() {
+ if (EHFrame)
+ return EHFrame.get();
+
+ DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
+ getAddressSize());
+ DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
}
@@ -575,8 +593,8 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
return InliningInfo;
}
-static bool consumeCompressedDebugSectionHeader(StringRef &data,
- uint64_t &OriginalSize) {
+static bool consumeCompressedGnuHeader(StringRef &data,
+ uint64_t &OriginalSize) {
// Consume "ZLIB" prefix.
if (!data.startswith("ZLIB"))
return false;
@@ -591,6 +609,50 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data,
return true;
}
+static bool consumeCompressedZLibHeader(StringRef &Data, uint64_t &OriginalSize,
+ bool IsLE, bool Is64Bit) {
+ using namespace ELF;
+ uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
+ if (Data.size() < HdrSize)
+ return false;
+
+ DataExtractor Extractor(Data, IsLE, 0);
+ uint32_t Offset = 0;
+ if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
+ : sizeof(Elf32_Word)) !=
+ ELFCOMPRESS_ZLIB)
+ return false;
+
+ // Skip Elf64_Chdr::ch_reserved field.
+ if (Is64Bit)
+ Offset += sizeof(Elf64_Word);
+
+ OriginalSize = Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Xword)
+ : sizeof(Elf32_Word));
+ Data = Data.substr(HdrSize);
+ return true;
+}
+
+static bool tryDecompress(StringRef &Name, StringRef &Data,
+ SmallString<32> &Out, bool ZLibStyle, bool IsLE,
+ bool Is64Bit) {
+ if (!zlib::isAvailable())
+ return false;
+
+ uint64_t OriginalSize;
+ bool Result =
+ ZLibStyle ? consumeCompressedZLibHeader(Data, OriginalSize, IsLE, Is64Bit)
+ : consumeCompressedGnuHeader(Data, OriginalSize);
+
+ if (!Result || zlib::uncompress(Data, Out, OriginalSize) != zlib::StatusOK)
+ return false;
+
+ // gnu-style names are started from "z", consume that.
+ if (!ZLibStyle)
+ Name = Name.substr(1);
+ return true;
+}
+
DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
const LoadedObjectInfo *L)
: IsLittleEndian(Obj.isLittleEndian()),
@@ -616,20 +678,13 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
- // Check if debug info section is compressed with zlib.
- if (name.startswith("zdebug_")) {
- uint64_t OriginalSize;
- if (!zlib::isAvailable() ||
- !consumeCompressedDebugSectionHeader(data, OriginalSize))
- continue;
- UncompressedSections.resize(UncompressedSections.size() + 1);
- if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
- zlib::StatusOK) {
- UncompressedSections.pop_back();
+ bool ZLibStyleCompressed = Section.isCompressed();
+ if (ZLibStyleCompressed || name.startswith("zdebug_")) {
+ SmallString<32> Out;
+ if (!tryDecompress(name, data, Out, ZLibStyleCompressed, IsLittleEndian,
+ AddressSize == 8))
continue;
- }
- // Make data point to uncompressed section contents and save its contents.
- name = name.substr(1);
+ UncompressedSections.emplace_back(std::move(Out));
data = UncompressedSections.back();
}
@@ -641,6 +696,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
.Case("debug_line", &LineSection.Data)
.Case("debug_aranges", &ARangeSection)
.Case("debug_frame", &DebugFrameSection)
+ .Case("eh_frame", &EHFrameSection)
.Case("debug_str", &StringSection)
.Case("debug_ranges", &RangeSection)
.Case("debug_macinfo", &MacinfoSection)
@@ -739,15 +795,29 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
// First calculate the address of the symbol or section as it appears
// in the objct file
if (Sym != Obj.symbol_end()) {
- ErrorOr<uint64_t> SymAddrOrErr = Sym->getAddress();
- if (std::error_code EC = SymAddrOrErr.getError()) {
+ Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
+ if (!SymAddrOrErr) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(SymAddrOrErr.takeError(), OS, "");
+ OS.flush();
errs() << "error: failed to compute symbol address: "
- << EC.message() << '\n';
+ << Buf << '\n';
continue;
}
SymAddr = *SymAddrOrErr;
// Also remember what section this symbol is in for later
- RSec = *Sym->getSection();
+ auto SectOrErr = Sym->getSection();
+ if (!SectOrErr) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(SectOrErr.takeError(), OS, "");
+ OS.flush();
+ errs() << "error: failed to get symbol section: "
+ << Buf << '\n';
+ continue;
+ }
+ RSec = *SectOrErr;
} else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
// MachO also has relocations that point to sections and
// scattered relocations.
diff --git a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 1aa31be71fee0..9b6a9a788230d 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -10,7 +10,9 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Dwarf.h"
@@ -18,6 +20,7 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
+#include <utility>
#include <vector>
using namespace llvm;
@@ -160,18 +163,26 @@ void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
case DW_CFA_offset_extended:
case DW_CFA_register:
case DW_CFA_def_cfa:
- case DW_CFA_val_offset:
+ case DW_CFA_val_offset: {
// Operands: ULEB128, ULEB128
- addInstruction(Opcode, Data.getULEB128(Offset),
- Data.getULEB128(Offset));
+ // Note: We can not embed getULEB128 directly into function
+ // argument list. getULEB128 changes Offset and order of evaluation
+ // for arguments is unspecified.
+ auto op1 = Data.getULEB128(Offset);
+ auto op2 = Data.getULEB128(Offset);
+ addInstruction(Opcode, op1, op2);
break;
+ }
case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
- case DW_CFA_val_offset_sf:
+ case DW_CFA_val_offset_sf: {
// Operands: ULEB128, SLEB128
- addInstruction(Opcode, Data.getULEB128(Offset),
- Data.getSLEB128(Offset));
+ // Note: see comment for the previous case
+ auto op1 = Data.getULEB128(Offset);
+ auto op2 = (uint64_t)Data.getSLEB128(Offset);
+ addInstruction(Opcode, op1, op2);
break;
+ }
case DW_CFA_def_cfa_expression:
case DW_CFA_expression:
case DW_CFA_val_expression:
@@ -191,19 +202,30 @@ public:
CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
SmallString<8> Augmentation, uint8_t AddressSize,
uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
- int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
+ int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
+ SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
+ uint32_t LSDAPointerEncoding)
: FrameEntry(FK_CIE, Offset, Length), Version(Version),
- Augmentation(std::move(Augmentation)),
- AddressSize(AddressSize),
+ Augmentation(std::move(Augmentation)), AddressSize(AddressSize),
SegmentDescriptorSize(SegmentDescriptorSize),
CodeAlignmentFactor(CodeAlignmentFactor),
DataAlignmentFactor(DataAlignmentFactor),
- ReturnAddressRegister(ReturnAddressRegister) {}
+ ReturnAddressRegister(ReturnAddressRegister),
+ AugmentationData(std::move(AugmentationData)),
+ FDEPointerEncoding(FDEPointerEncoding),
+ LSDAPointerEncoding(LSDAPointerEncoding) {}
~CIE() override {}
+ StringRef getAugmentationString() const { return Augmentation; }
uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
+ uint32_t getFDEPointerEncoding() const {
+ return FDEPointerEncoding;
+ }
+ uint32_t getLSDAPointerEncoding() const {
+ return LSDAPointerEncoding;
+ }
void dumpHeader(raw_ostream &OS) const override {
OS << format("%08x %08x %08x CIE",
@@ -223,6 +245,12 @@ public:
(int32_t)DataAlignmentFactor);
OS << format(" Return address column: %d\n",
(int32_t)ReturnAddressRegister);
+ if (!AugmentationData.empty()) {
+ OS << " Augmentation data: ";
+ for (uint8_t Byte : AugmentationData)
+ OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
+ OS << "\n";
+ }
OS << "\n";
}
@@ -239,6 +267,11 @@ private:
uint64_t CodeAlignmentFactor;
int64_t DataAlignmentFactor;
uint64_t ReturnAddressRegister;
+
+ // The following are used when the CIE represents an EH frame entry.
+ SmallString<8> AugmentationData;
+ uint32_t FDEPointerEncoding;
+ uint32_t LSDAPointerEncoding;
};
@@ -423,7 +456,7 @@ void FrameEntry::dumpInstructions(raw_ostream &OS) const {
}
}
-DWARFDebugFrame::DWARFDebugFrame() {
+DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {
}
DWARFDebugFrame::~DWARFDebugFrame() {
@@ -439,6 +472,39 @@ static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
errs() << "\n";
}
+static unsigned getSizeForEncoding(const DataExtractor &Data,
+ unsigned symbolEncoding) {
+ unsigned format = symbolEncoding & 0x0f;
+ switch (format) {
+ default: llvm_unreachable("Unknown Encoding");
+ case dwarf::DW_EH_PE_absptr:
+ case dwarf::DW_EH_PE_signed:
+ return Data.getAddressSize();
+ case dwarf::DW_EH_PE_udata2:
+ case dwarf::DW_EH_PE_sdata2:
+ return 2;
+ case dwarf::DW_EH_PE_udata4:
+ case dwarf::DW_EH_PE_sdata4:
+ return 4;
+ case dwarf::DW_EH_PE_udata8:
+ case dwarf::DW_EH_PE_sdata8:
+ return 8;
+ }
+}
+
+static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset,
+ unsigned Encoding) {
+ switch (getSizeForEncoding(Data, Encoding)) {
+ case 2:
+ return Data.getU16(&Offset);
+ case 4:
+ return Data.getU32(&Offset);
+ case 8:
+ return Data.getU64(&Offset);
+ default:
+ llvm_unreachable("Illegal data size");
+ }
+}
void DWARFDebugFrame::parse(DataExtractor Data) {
uint32_t Offset = 0;
@@ -447,6 +513,14 @@ void DWARFDebugFrame::parse(DataExtractor Data) {
while (Data.isValidOffset(Offset)) {
uint32_t StartOffset = Offset;
+ auto ReportError = [StartOffset](const char *ErrorMsg) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ OS << format(ErrorMsg, StartOffset);
+ OS.flush();
+ report_fatal_error(Str);
+ };
+
bool IsDWARF64 = false;
uint64_t Length = Data.getU32(&Offset);
uint64_t Id;
@@ -465,47 +539,132 @@ void DWARFDebugFrame::parse(DataExtractor Data) {
// read).
// TODO: For honest DWARF64 support, DataExtractor will have to treat
// offset_ptr as uint64_t*
+ uint32_t StartStructureOffset = Offset;
uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
// The Id field's size depends on the DWARF format
- Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
- bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);
+ Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
+ bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||
+ Id == DW_CIE_ID ||
+ (IsEH && !Id));
if (IsCIE) {
uint8_t Version = Data.getU8(&Offset);
const char *Augmentation = Data.getCStr(&Offset);
- uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : Data.getU8(&Offset);
+ StringRef AugmentationString(Augmentation ? Augmentation : "");
+ uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
+ Data.getU8(&Offset);
Data.setAddressSize(AddressSize);
uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
+ // Parse the augmentation data for EH CIEs
+ StringRef AugmentationData("");
+ uint32_t FDEPointerEncoding = DW_EH_PE_omit;
+ uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
+ if (IsEH) {
+ Optional<uint32_t> PersonalityEncoding;
+ Optional<uint64_t> Personality;
+
+ Optional<uint64_t> AugmentationLength;
+ uint32_t StartAugmentationOffset;
+ uint32_t EndAugmentationOffset;
+
+ // Walk the augmentation string to get all the augmentation data.
+ for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
+ switch (AugmentationString[i]) {
+ default:
+ ReportError("Unknown augmentation character in entry at %lx");
+ case 'L':
+ LSDAPointerEncoding = Data.getU8(&Offset);
+ break;
+ case 'P': {
+ if (Personality)
+ ReportError("Duplicate personality in entry at %lx");
+ PersonalityEncoding = Data.getU8(&Offset);
+ Personality = readPointer(Data, Offset, *PersonalityEncoding);
+ break;
+ }
+ case 'R':
+ FDEPointerEncoding = Data.getU8(&Offset);
+ break;
+ case 'z':
+ if (i)
+ ReportError("'z' must be the first character at %lx");
+ // Parse the augmentation length first. We only parse it if
+ // the string contains a 'z'.
+ AugmentationLength = Data.getULEB128(&Offset);
+ StartAugmentationOffset = Offset;
+ EndAugmentationOffset = Offset +
+ static_cast<uint32_t>(*AugmentationLength);
+ }
+ }
+
+ if (AugmentationLength.hasValue()) {
+ if (Offset != EndAugmentationOffset)
+ ReportError("Parsing augmentation data at %lx failed");
+
+ AugmentationData = Data.getData().slice(StartAugmentationOffset,
+ EndAugmentationOffset);
+ }
+ }
+
auto Cie = make_unique<CIE>(StartOffset, Length, Version,
- StringRef(Augmentation), AddressSize,
+ AugmentationString, AddressSize,
SegmentDescriptorSize, CodeAlignmentFactor,
- DataAlignmentFactor, ReturnAddressRegister);
+ DataAlignmentFactor, ReturnAddressRegister,
+ AugmentationData, FDEPointerEncoding,
+ LSDAPointerEncoding);
CIEs[StartOffset] = Cie.get();
Entries.emplace_back(std::move(Cie));
} else {
// FDE
uint64_t CIEPointer = Id;
- uint64_t InitialLocation = Data.getAddress(&Offset);
- uint64_t AddressRange = Data.getAddress(&Offset);
+ uint64_t InitialLocation = 0;
+ uint64_t AddressRange = 0;
+ CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
+
+ if (IsEH) {
+ // The address size is encoded in the CIE we reference.
+ if (!Cie)
+ ReportError("Parsing FDE data at %lx failed due to missing CIE");
+
+ InitialLocation = readPointer(Data, Offset,
+ Cie->getFDEPointerEncoding());
+ AddressRange = readPointer(Data, Offset,
+ Cie->getFDEPointerEncoding());
+
+ StringRef AugmentationString = Cie->getAugmentationString();
+ if (!AugmentationString.empty()) {
+ // Parse the augmentation length and data for this FDE.
+ uint64_t AugmentationLength = Data.getULEB128(&Offset);
+
+ uint32_t EndAugmentationOffset =
+ Offset + static_cast<uint32_t>(AugmentationLength);
+
+ // Decode the LSDA if the CIE augmentation string said we should.
+ if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit)
+ readPointer(Data, Offset, Cie->getLSDAPointerEncoding());
+
+ if (Offset != EndAugmentationOffset)
+ ReportError("Parsing augmentation data at %lx failed");
+ }
+ } else {
+ InitialLocation = Data.getAddress(&Offset);
+ AddressRange = Data.getAddress(&Offset);
+ }
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
InitialLocation, AddressRange,
- CIEs[CIEPointer]));
+ Cie));
}
Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
- if (Offset != EndStructureOffset) {
- std::string Str;
- raw_string_ostream OS(Str);
- OS << format("Parsing entry instructions at %lx failed", StartOffset);
- report_fatal_error(Str);
- }
+ if (Offset != EndStructureOffset)
+ ReportError("Parsing entry instructions at %lx failed");
}
}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index a0bee0da17656..30cb83398dd40 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -17,9 +17,7 @@ using namespace llvm;
using namespace dwarf;
typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
-DWARFDebugLine::Prologue::Prologue() {
- clear();
-}
+DWARFDebugLine::Prologue::Prologue() { clear(); }
void DWARFDebugLine::Prologue::clear() {
TotalLength = Version = PrologueLength = 0;
@@ -44,12 +42,12 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
<< format(" opcode_base: %u\n", OpcodeBase);
for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i)
- OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i+1),
+ OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i + 1),
StandardOpcodeLengths[i]);
if (!IncludeDirectories.empty())
for (uint32_t i = 0; i < IncludeDirectories.size(); ++i)
- OS << format("include_directories[%3u] = '", i+1)
+ OS << format("include_directories[%3u] = '", i + 1)
<< IncludeDirectories[i] << "'\n";
if (!FileNames.empty()) {
@@ -57,10 +55,10 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
<< " ---- ---------- ---------- -----------"
"----------------\n";
for (uint32_t i = 0; i < FileNames.size(); ++i) {
- const FileNameEntry& fileEntry = FileNames[i];
- OS << format("file_names[%3u] %4" PRIu64 " ", i+1, fileEntry.DirIdx)
- << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ",
- fileEntry.ModTime, fileEntry.Length)
+ const FileNameEntry &fileEntry = FileNames[i];
+ OS << format("file_names[%3u] %4" PRIu64 " ", i + 1, fileEntry.DirIdx)
+ << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", fileEntry.ModTime,
+ fileEntry.Length)
<< fileEntry.Name << '\n';
}
}
@@ -82,8 +80,8 @@ bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
if (Version < 2)
return false;
- PrologueLength = debug_line_data.getUnsigned(offset_ptr,
- sizeofPrologueLength());
+ PrologueLength =
+ debug_line_data.getUnsigned(offset_ptr, sizeofPrologueLength());
const uint64_t end_prologue_offset = PrologueLength + *offset_ptr;
MinInstLength = debug_line_data.getU8(offset_ptr);
if (Version >= 4)
@@ -131,9 +129,7 @@ bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
return true;
}
-DWARFDebugLine::Row::Row(bool default_is_stmt) {
- reset(default_is_stmt);
-}
+DWARFDebugLine::Row::Row(bool default_is_stmt) { reset(default_is_stmt); }
void DWARFDebugLine::Row::postAppend() {
BasicBlock = false;
@@ -158,17 +154,13 @@ void DWARFDebugLine::Row::reset(bool default_is_stmt) {
void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
<< format(" %6u %3u %13u ", File, Isa, Discriminator)
- << (IsStmt ? " is_stmt" : "")
- << (BasicBlock ? " basic_block" : "")
+ << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
<< (PrologueEnd ? " prologue_end" : "")
<< (EpilogueBegin ? " epilogue_begin" : "")
- << (EndSequence ? " end_sequence" : "")
- << '\n';
+ << (EndSequence ? " end_sequence" : "") << '\n';
}
-DWARFDebugLine::Sequence::Sequence() {
- reset();
-}
+DWARFDebugLine::Sequence::Sequence() { reset(); }
void DWARFDebugLine::Sequence::reset() {
LowPC = 0;
@@ -178,9 +170,7 @@ void DWARFDebugLine::Sequence::reset() {
Empty = true;
}
-DWARFDebugLine::LineTable::LineTable() {
- clear();
-}
+DWARFDebugLine::LineTable::LineTable() { clear(); }
void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
Prologue.dump(OS);
@@ -244,7 +234,7 @@ const DWARFDebugLine::LineTable *
DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
uint32_t offset) {
std::pair<LineTableIter, bool> pos =
- LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
+ LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
LineTable *LT = &pos.first->second;
if (pos.second) {
if (!LT->parse(debug_line_data, RelocMap, &offset))
@@ -266,8 +256,8 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
return false;
}
- const uint32_t end_offset = debug_line_offset + Prologue.TotalLength +
- Prologue.sizeofTotalLength();
+ const uint32_t end_offset =
+ debug_line_offset + Prologue.TotalLength + Prologue.sizeofTotalLength();
ParsingState State(this);
@@ -307,9 +297,9 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
// If this address is in our relocation map, apply the relocation.
RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
if (AI != RMap->end()) {
- const std::pair<uint8_t, int64_t> &R = AI->second;
- State.Row.Address =
- debug_line_data.getAddress(offset_ptr) + R.second;
+ const std::pair<uint8_t, int64_t> &R = AI->second;
+ State.Row.Address =
+ debug_line_data.getAddress(offset_ptr) + R.second;
} else
State.Row.Address = debug_line_data.getAddress(offset_ptr);
}
@@ -509,6 +499,8 @@ bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
State.Row.Line += line_offset;
State.Row.Address += addr_offset;
State.appendRowToMatrix(*offset_ptr);
+ // Reset discriminator to 0.
+ State.Row.Discriminator = 0;
}
}
@@ -566,8 +558,8 @@ uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
sequence.LowPC = address;
SequenceIter first_seq = Sequences.begin();
SequenceIter last_seq = Sequences.end();
- SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence,
- DWARFDebugLine::Sequence::orderByLowPC);
+ SequenceIter seq_pos = std::lower_bound(
+ first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC);
DWARFDebugLine::Sequence found_seq;
if (seq_pos == last_seq) {
found_seq = Sequences.back();
@@ -591,8 +583,8 @@ bool DWARFDebugLine::LineTable::lookupAddressRange(
sequence.LowPC = address;
SequenceIter first_seq = Sequences.begin();
SequenceIter last_seq = Sequences.end();
- SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence,
- DWARFDebugLine::Sequence::orderByLowPC);
+ SequenceIter seq_pos = std::lower_bound(
+ first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC);
if (seq_pos == last_seq || seq_pos->LowPC != address) {
if (seq_pos == first_seq)
return false;
@@ -632,11 +624,10 @@ bool DWARFDebugLine::LineTable::lookupAddressRange(
return true;
}
-bool
-DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
- const char *CompDir,
- FileLineInfoKind Kind,
- std::string &Result) const {
+bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
+ const char *CompDir,
+ FileLineInfoKind Kind,
+ std::string &Result) const {
if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
Kind == FileLineInfoKind::None)
return false;
@@ -669,11 +660,9 @@ DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
return true;
}
-bool
-DWARFDebugLine::LineTable::getFileLineInfoForAddress(uint64_t Address,
- const char *CompDir,
- FileLineInfoKind Kind,
- DILineInfo &Result) const {
+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)
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index cd6fbefd05dd1..a7b46b842feec 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index b6555fa6272e3..375ff7c99a044 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -7,9 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "SyntaxHighlighting.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
-#include "llvm/Support/Compiler.h"
+#include "SyntaxHighlighting.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 92ca2d4c3ff05..13c2b508bfa3b 100644
--- a/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -20,7 +20,7 @@ using namespace dwarf;
void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
parseImpl(C, Section, C.getDebugAbbrev(), C.getRangeSection(),
C.getStringSection(), StringRef(), C.getAddrSection(),
- C.getLineSection().Data, C.isLittleEndian());
+ C.getLineSection().Data, C.isLittleEndian(), false);
}
void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
@@ -28,13 +28,14 @@ void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
DWARFUnitIndex *Index) {
parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), C.getRangeDWOSection(),
C.getStringDWOSection(), C.getStringOffsetDWOSection(),
- C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian());
+ C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian(),
+ true);
}
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
StringRef SOS, StringRef AOS, StringRef LS, bool LE,
- const DWARFUnitSectionBase &UnitSection,
+ bool IsDWO, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry)
: Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
LineSection(LS), StringSection(SS), StringOffsetSection([&]() {
@@ -43,8 +44,8 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
return SOS.slice(C->Offset, C->Offset + C->Length);
return SOS;
}()),
- AddrOffsetSection(AOS), isLittleEndian(LE), UnitSection(UnitSection),
- IndexEntry(IndexEntry) {
+ AddrOffsetSection(AOS), isLittleEndian(LE), isDWO(IsDWO),
+ UnitSection(UnitSection), IndexEntry(IndexEntry) {
clear();
}
@@ -268,8 +269,11 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath)
: DWOFile(), DWOContext(), DWOU(nullptr) {
auto Obj = object::ObjectFile::createObjectFile(DWOPath);
- if (!Obj)
+ if (!Obj) {
+ // TODO: Actually report errors helpfully.
+ consumeError(Obj.takeError());
return;
+ }
DWOFile = std::move(Obj.get());
DWOContext.reset(
cast<DWARFContext>(new DWARFContextInMemory(*DWOFile.getBinary())));
@@ -278,6 +282,8 @@ DWARFUnit::DWOHolder::DWOHolder(StringRef DWOPath)
}
bool DWARFUnit::parseDWO() {
+ if (isDWO)
+ return false;
if (DWO.get())
return false;
extractDIEsIfNeeded(true);
@@ -375,19 +381,14 @@ DWARFUnit::getInlinedChainForAddress(uint64_t Address) {
// First, find a subprogram that contains the given address (the root
// of inlined chain).
const DWARFUnit *ChainCU = nullptr;
- const DWARFDebugInfoEntryMinimal *SubprogramDIE =
- getSubprogramForAddress(Address);
- if (SubprogramDIE) {
+ const DWARFDebugInfoEntryMinimal *SubprogramDIE;
+ // Try to look for subprogram DIEs in the DWO file.
+ parseDWO();
+ if (DWO) {
+ if ((SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address)))
+ ChainCU = DWO->getUnit();
+ } else if ((SubprogramDIE = getSubprogramForAddress(Address)))
ChainCU = this;
- } else {
- // Try to look for subprogram DIEs in the DWO file.
- parseDWO();
- if (DWO.get()) {
- SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
- if (SubprogramDIE)
- ChainCU = DWO->getUnit();
- }
- }
// Get inlined chain rooted at this subprogram DIE.
if (!SubprogramDIE)
diff --git a/lib/DebugInfo/DWARF/Makefile b/lib/DebugInfo/DWARF/Makefile
deleted file mode 100644
index 863337353d0ab..0000000000000
--- a/lib/DebugInfo/DWARF/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/DebugInfo/DWARF/Makefile ------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMDebugInfoDWARF
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/lib/DebugInfo/DWARF/module.modulemap b/lib/DebugInfo/DWARF/module.modulemap
deleted file mode 100644
index c2f624fd4b6c3..0000000000000
--- a/lib/DebugInfo/DWARF/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module DebugInfoDWARF { requires cplusplus umbrella "." module * { export * } }