diff options
Diffstat (limited to 'lib/DebugInfo/DWARF')
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFContext.cpp | 112 | ||||
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 209 | ||||
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 77 | ||||
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 1 | ||||
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFDebugMacro.cpp | 3 | ||||
-rw-r--r-- | lib/DebugInfo/DWARF/DWARFUnit.cpp | 37 | ||||
-rw-r--r-- | lib/DebugInfo/DWARF/Makefile | 14 | ||||
-rw-r--r-- | lib/DebugInfo/DWARF/module.modulemap | 1 |
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 * } } |