diff options
Diffstat (limited to 'contrib/llvm/lib/DebugInfo')
32 files changed, 549 insertions, 1662 deletions
diff --git a/contrib/llvm/lib/DebugInfo/DIContext.cpp b/contrib/llvm/lib/DebugInfo/DIContext.cpp index 49a4409..20bc01f 100644 --- a/contrib/llvm/lib/DebugInfo/DIContext.cpp +++ b/contrib/llvm/lib/DebugInfo/DIContext.cpp @@ -8,11 +8,11 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DIContext.h" -#include "DWARFContext.h" +#include "llvm/DebugInfo/DWARFContext.h" 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/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp b/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp index c3e570e..2c9eff6 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFAbbreviationDeclaration.h" +#include "llvm/DebugInfo/DWARFAbbreviationDeclaration.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h b/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h deleted file mode 100644 index b86b9ec..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFAbbreviationDeclaration.h +++ /dev/null @@ -1,60 +0,0 @@ -//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H -#define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H - -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/DataExtractor.h" - -namespace llvm { - -class raw_ostream; - -class DWARFAbbreviationDeclaration { - uint32_t Code; - uint32_t Tag; - bool HasChildren; - - struct AttributeSpec { - AttributeSpec(uint16_t Attr, uint16_t Form) : Attr(Attr), Form(Form) {} - uint16_t Attr; - uint16_t Form; - }; - typedef SmallVector<AttributeSpec, 8> AttributeSpecVector; - AttributeSpecVector AttributeSpecs; -public: - DWARFAbbreviationDeclaration(); - - uint32_t getCode() const { return Code; } - uint32_t getTag() const { return Tag; } - bool hasChildren() const { return HasChildren; } - - typedef iterator_range<AttributeSpecVector::const_iterator> - attr_iterator_range; - - attr_iterator_range attributes() const { - return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end()); - } - - uint16_t getFormByIndex(uint32_t idx) const { - return idx < AttributeSpecs.size() ? AttributeSpecs[idx].Form : 0; - } - - uint32_t findAttributeIndex(uint16_t attr) const; - bool extract(DataExtractor Data, uint32_t* OffsetPtr); - void dump(raw_ostream &OS) const; - -private: - void clear(); -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp b/contrib/llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp new file mode 100644 index 0000000..cbdde6a --- /dev/null +++ b/contrib/llvm/lib/DebugInfo/DWARFAcceleratorTable.cpp @@ -0,0 +1,132 @@ +//===--- DWARFAcceleratorTable.cpp ----------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/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/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.cpp b/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.cpp index 33869d8..3ec2cf5 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFCompileUnit.h" +#include "llvm/DebugInfo/DWARFCompileUnit.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h b/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h deleted file mode 100644 index 2ed188e..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFCompileUnit.h +++ /dev/null @@ -1,30 +0,0 @@ -//===-- DWARFCompileUnit.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H -#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H - -#include "DWARFUnit.h" - -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) {} - void dump(raw_ostream &OS); - // VTable anchor. - ~DWARFCompileUnit() override; -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFContext.cpp b/contrib/llvm/lib/DebugInfo/DWARFContext.cpp index 3961905..3844cde 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFContext.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFContext.cpp @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "DWARFContext.h" -#include "DWARFDebugArangeSet.h" - +#include "llvm/DebugInfo/DWARFContext.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/DebugInfo/DWARFAcceleratorTable.h" +#include "llvm/DebugInfo/DWARFDebugArangeSet.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" @@ -59,6 +59,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 +98,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 +230,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 +321,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 +342,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 +379,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 +409,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 +436,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 +447,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 +475,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 +496,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 +537,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 +593,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 +615,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 +630,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 +648,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/contrib/llvm/lib/DebugInfo/DWARFContext.h b/contrib/llvm/lib/DebugInfo/DWARFContext.h deleted file mode 100644 index 6d1ae92..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFContext.h +++ /dev/null @@ -1,285 +0,0 @@ -//===-- DWARFContext.h ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===/ - -#ifndef LLVM_DEBUGINFO_DWARFCONTEXT_H -#define LLVM_DEBUGINFO_DWARFCONTEXT_H - -#include "DWARFCompileUnit.h" -#include "DWARFDebugAranges.h" -#include "DWARFDebugFrame.h" -#include "DWARFDebugLine.h" -#include "DWARFDebugLoc.h" -#include "DWARFDebugRangeList.h" -#include "DWARFTypeUnit.h" -#include "llvm/ADT/MapVector.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/DIContext.h" - -namespace llvm { - -/// DWARFContext -/// This data structure is the top level entity that deals with dwarf debug -/// 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; - 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; - std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO; - std::unique_ptr<DWARFDebugLocDWO> LocDWO; - - DWARFContext(DWARFContext &) LLVM_DELETED_FUNCTION; - DWARFContext &operator=(DWARFContext &) LLVM_DELETED_FUNCTION; - - /// Read compile units from the debug_info section (if necessary) - /// and store them in CUs. - void parseCompileUnits(); - - /// Read type units from the debug_types sections (if necessary) - /// and store them in TUs. - void parseTypeUnits(); - - /// Read compile units from the debug_info.dwo section (if necessary) - /// and store them in DWOCUs. - void parseDWOCompileUnits(); - - /// Read type units from the debug_types.dwo section (if necessary) - /// and store them in DWOTUs. - void parseDWOTypeUnits(); - -public: - struct Section { - StringRef Data; - RelocAddrMap Relocs; - }; - - DWARFContext() : DIContext(CK_DWARF) {} - - static bool classof(const DIContext *DICtx) { - return DICtx->getKind() == CK_DWARF; - } - - 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; - - /// Get compile units in this context. - cu_iterator_range compile_units() { - parseCompileUnits(); - return cu_iterator_range(CUs.begin(), CUs.end()); - } - - /// Get type units in this context. - tu_iterator_range type_units() { - parseTypeUnits(); - return tu_iterator_range(TUs.begin(), TUs.end()); - } - - /// Get compile units in the DWO context. - cu_iterator_range dwo_compile_units() { - parseDWOCompileUnits(); - return cu_iterator_range(DWOCUs.begin(), DWOCUs.end()); - } - - /// Get type units in the DWO context. - tu_iterator_range dwo_type_units() { - parseDWOTypeUnits(); - return tu_iterator_range(DWOTUs.begin(), DWOTUs.end()); - } - - /// Get the number of compile units in this context. - unsigned getNumCompileUnits() { - parseCompileUnits(); - return CUs.size(); - } - - /// Get the number of compile units in this context. - unsigned getNumTypeUnits() { - parseTypeUnits(); - return TUs.size(); - } - - /// Get the number of compile units in the DWO context. - unsigned getNumDWOCompileUnits() { - parseDWOCompileUnits(); - return DWOCUs.size(); - } - - /// Get the number of compile units in the DWO context. - unsigned getNumDWOTypeUnits() { - parseDWOTypeUnits(); - return DWOTUs.size(); - } - - /// Get the compile unit at the specified index for this compile unit. - DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { - parseCompileUnits(); - return CUs[index].get(); - } - - /// Get the compile unit at the specified index for the DWO compile units. - DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { - parseDWOCompileUnits(); - return DWOCUs[index].get(); - } - - /// Get a pointer to the parsed DebugAbbrev object. - const DWARFDebugAbbrev *getDebugAbbrev(); - - /// Get a pointer to the parsed DebugLoc object. - const DWARFDebugLoc *getDebugLoc(); - - /// Get a pointer to the parsed dwo abbreviations object. - const DWARFDebugAbbrev *getDebugAbbrevDWO(); - - /// Get a pointer to the parsed DebugLoc object. - const DWARFDebugLocDWO *getDebugLocDWO(); - - /// Get a pointer to the parsed DebugAranges object. - const DWARFDebugAranges *getDebugAranges(); - - /// Get a pointer to the parsed frame information object. - const DWARFDebugFrame *getDebugFrame(); - - /// Get a pointer to a parsed line table corresponding to a compile unit. - const DWARFDebugLine::LineTable * - getLineTableForCompileUnit(DWARFCompileUnit *cu); - - DILineInfo getLineInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; - DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, - DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; - DIInliningInfo getInliningInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; - - 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 TypeSectionMap &getTypesSections() = 0; - virtual StringRef getAbbrevSection() = 0; - virtual const Section &getLocSection() = 0; - virtual const Section &getLocDWOSection() = 0; - virtual StringRef getARangeSection() = 0; - virtual StringRef getDebugFrameSection() = 0; - virtual const Section &getLineSection() = 0; - virtual const Section &getLineDWOSection() = 0; - virtual StringRef getStringSection() = 0; - virtual StringRef getRangeSection() = 0; - virtual StringRef getPubNamesSection() = 0; - virtual StringRef getPubTypesSection() = 0; - virtual StringRef getGnuPubNamesSection() = 0; - virtual StringRef getGnuPubTypesSection() = 0; - - // Sections for DWARF5 split dwarf proposal. - virtual const Section &getInfoDWOSection() = 0; - virtual const TypeSectionMap &getTypesDWOSections() = 0; - virtual StringRef getAbbrevDWOSection() = 0; - virtual StringRef getStringDWOSection() = 0; - virtual StringRef getStringOffsetDWOSection() = 0; - virtual StringRef getRangeDWOSection() = 0; - virtual StringRef getAddrSection() = 0; - - static bool isSupportedVersion(unsigned version) { - return version == 2 || version == 3 || version == 4; - } -private: - /// Return the compile unit that includes an offset (relative to .debug_info). - DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); - - /// Return the compile unit which contains instruction with provided - /// address. - DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); -}; - -/// DWARFContextInMemory is the simplest possible implementation of a -/// DWARFContext. It assumes all content is available in memory and stores -/// pointers to it. -class DWARFContextInMemory : public DWARFContext { - virtual void anchor(); - bool IsLittleEndian; - uint8_t AddressSize; - Section InfoSection; - TypeSectionMap TypesSections; - StringRef AbbrevSection; - Section LocSection; - Section LocDWOSection; - StringRef ARangeSection; - StringRef DebugFrameSection; - Section LineSection; - Section LineDWOSection; - StringRef StringSection; - StringRef RangeSection; - StringRef PubNamesSection; - StringRef PubTypesSection; - StringRef GnuPubNamesSection; - StringRef GnuPubTypesSection; - - // Sections for DWARF5 split dwarf proposal. - Section InfoDWOSection; - TypeSectionMap TypesDWOSections; - StringRef AbbrevDWOSection; - StringRef StringDWOSection; - StringRef StringOffsetDWOSection; - StringRef RangeDWOSection; - StringRef AddrSection; - - SmallVector<SmallString<32>, 4> UncompressedSections; - -public: - DWARFContextInMemory(object::ObjectFile *); - bool isLittleEndian() const override { return IsLittleEndian; } - uint8_t getAddressSize() const override { return AddressSize; } - const Section &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; } - StringRef getARangeSection() override { return ARangeSection; } - StringRef getDebugFrameSection() override { return DebugFrameSection; } - const Section &getLineSection() override { return LineSection; } - const Section &getLineDWOSection() override { return LineDWOSection; } - 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; } - - // Sections for DWARF5 split dwarf proposal. - const Section &getInfoDWOSection() override { return InfoDWOSection; } - const TypeSectionMap &getTypesDWOSections() override { - return TypesDWOSections; - } - StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; } - StringRef getStringDWOSection() override { return StringDWOSection; } - StringRef getStringOffsetDWOSection() override { - return StringOffsetDWOSection; - } - StringRef getRangeDWOSection() override { return RangeDWOSection; } - StringRef getAddrSection() override { - return AddrSection; - } -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp index 8426bf9..6c9c9eb 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugAbbrev.h" +#include "llvm/DebugInfo/DWARFDebugAbbrev.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -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/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h b/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h deleted file mode 100644 index 3a9adba..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugAbbrev.h +++ /dev/null @@ -1,63 +0,0 @@ -//===-- DWARFDebugAbbrev.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGABBREV_H -#define LLVM_DEBUGINFO_DWARFDEBUGABBREV_H - -#include "DWARFAbbreviationDeclaration.h" -#include <list> -#include <map> -#include <vector> - -namespace llvm { - -class DWARFAbbreviationDeclarationSet { - uint32_t Offset; - /// Code of the first abbreviation, if all abbreviations in the set have - /// consecutive codes. UINT32_MAX otherwise. - uint32_t FirstAbbrCode; - std::vector<DWARFAbbreviationDeclaration> Decls; - -public: - DWARFAbbreviationDeclarationSet(); - - uint32_t getOffset() const { return Offset; } - void dump(raw_ostream &OS) const; - bool extract(DataExtractor Data, uint32_t *OffsetPtr); - - const DWARFAbbreviationDeclaration * - getAbbreviationDeclaration(uint32_t AbbrCode) const; - -private: - void clear(); -}; - -class DWARFDebugAbbrev { - typedef std::map<uint64_t, DWARFAbbreviationDeclarationSet> - DWARFAbbreviationDeclarationSetMap; - - DWARFAbbreviationDeclarationSetMap AbbrDeclSets; - mutable DWARFAbbreviationDeclarationSetMap::const_iterator PrevAbbrOffsetPos; - -public: - DWARFDebugAbbrev(); - - const DWARFAbbreviationDeclarationSet * - getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const; - - void dump(raw_ostream &OS) const; - void extract(DataExtractor Data); - -private: - void clear(); -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp index c0a33ce..d4bff90 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugArangeSet.h" +#include "llvm/DebugInfo/DWARFDebugArangeSet.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h b/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h deleted file mode 100644 index d6c2d8b..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugArangeSet.h +++ /dev/null @@ -1,70 +0,0 @@ -//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H -#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H - -#include "llvm/ADT/iterator_range.h" -#include "llvm/Support/DataExtractor.h" -#include <vector> - -namespace llvm { - -class raw_ostream; - -class DWARFDebugArangeSet { -public: - struct Header { - // The total length of the entries for that set, not including the length - // field itself. - uint32_t Length; - // The offset from the beginning of the .debug_info section of the - // compilation unit entry referenced by the table. - uint32_t CuOffset; - // The DWARF version number. - uint16_t Version; - // The size in bytes of an address on the target architecture. For segmented - // addressing, this is the size of the offset portion of the address. - uint8_t AddrSize; - // The size in bytes of a segment descriptor on the target architecture. - // If the target system uses a flat address space, this value is 0. - uint8_t SegSize; - }; - - struct Descriptor { - uint64_t Address; - uint64_t Length; - uint64_t getEndAddress() const { return Address + Length; } - }; - -private: - typedef std::vector<Descriptor> DescriptorColl; - typedef iterator_range<DescriptorColl::const_iterator> desc_iterator_range; - - uint32_t Offset; - Header HeaderData; - DescriptorColl ArangeDescriptors; - -public: - DWARFDebugArangeSet() { clear(); } - void clear(); - bool extract(DataExtractor data, uint32_t *offset_ptr); - void dump(raw_ostream &OS) const; - - uint32_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; } - - desc_iterator_range descriptors() const { - return desc_iterator_range(ArangeDescriptors.begin(), - ArangeDescriptors.end()); - } -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp index fe7e46d..b825d83 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugAranges.h" -#include "DWARFCompileUnit.h" -#include "DWARFContext.h" -#include "DWARFDebugArangeSet.h" +#include "llvm/DebugInfo/DWARFDebugAranges.h" +#include "llvm/DebugInfo/DWARFCompileUnit.h" +#include "llvm/DebugInfo/DWARFContext.h" +#include "llvm/DebugInfo/DWARFDebugArangeSet.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h b/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h deleted file mode 100644 index a9f37fe..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugAranges.h +++ /dev/null @@ -1,87 +0,0 @@ -//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H -#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H - -#include "llvm/ADT/DenseSet.h" -#include "llvm/Support/DataExtractor.h" -#include <vector> - -namespace llvm { - -class DWARFContext; - -class DWARFDebugAranges { -public: - void generate(DWARFContext *CTX); - uint32_t findAddress(uint64_t Address) const; - -private: - void clear(); - void extract(DataExtractor DebugArangesData); - - // Call appendRange multiple times and then call construct. - void appendRange(uint32_t CUOffset, uint64_t LowPC, uint64_t HighPC); - void construct(); - - struct Range { - explicit Range(uint64_t LowPC = -1ULL, uint64_t HighPC = -1ULL, - uint32_t CUOffset = -1U) - : LowPC(LowPC), Length(HighPC - LowPC), CUOffset(CUOffset) {} - - void setHighPC(uint64_t HighPC) { - if (HighPC == -1ULL || HighPC <= LowPC) - Length = 0; - else - Length = HighPC - LowPC; - } - uint64_t HighPC() const { - if (Length) - return LowPC + Length; - return -1ULL; - } - - bool containsAddress(uint64_t Address) const { - return LowPC <= Address && Address < HighPC(); - } - bool operator<(const Range &other) const { - return LowPC < other.LowPC; - } - - uint64_t LowPC; // Start of address range. - uint32_t Length; // End of address range (not including this address). - uint32_t CUOffset; // Offset of the compile unit or die. - }; - - struct RangeEndpoint { - uint64_t Address; - uint32_t CUOffset; - bool IsRangeStart; - - RangeEndpoint(uint64_t Address, uint32_t CUOffset, bool IsRangeStart) - : Address(Address), CUOffset(CUOffset), IsRangeStart(IsRangeStart) {} - - bool operator<(const RangeEndpoint &Other) const { - return Address < Other.Address; - } - }; - - - typedef std::vector<Range> RangeColl; - typedef RangeColl::const_iterator RangeCollIterator; - - std::vector<RangeEndpoint> Endpoints; - RangeColl Aranges; - DenseSet<uint32_t> ParsedCUOffsets; -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp index a33548e..968a0ce 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugFrame.h" +#include "llvm/DebugInfo/DWARFDebugFrame.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Dwarf.h" @@ -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/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h b/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h deleted file mode 100644 index bd4ef45..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugFrame.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGFRAME_H -#define LLVM_DEBUGINFO_DWARFDEBUGFRAME_H - -#include "llvm/Support/DataExtractor.h" -#include "llvm/Support/raw_ostream.h" -#include <memory> -#include <vector> - -namespace llvm { - -class FrameEntry; - -/// \brief A parsed .debug_frame section -/// -class DWARFDebugFrame { -public: - DWARFDebugFrame(); - ~DWARFDebugFrame(); - - /// \brief Dump the section data into the given stream. - void dump(raw_ostream &OS) const; - - /// \brief Parse the section from raw data. - /// data is assumed to be pointing to the beginning of the section. - void parse(DataExtractor Data); - -private: - std::vector<std::unique_ptr<FrameEntry>> Entries; -}; - - -} // namespace llvm - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp index 2e7a54a..01ff52f 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -7,20 +7,33 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugInfoEntry.h" -#include "DWARFCompileUnit.h" -#include "DWARFContext.h" -#include "DWARFDebugAbbrev.h" +#include "SyntaxHighlighting.h" +#include "llvm/DebugInfo/DWARFCompileUnit.h" +#include "llvm/DebugInfo/DWARFContext.h" +#include "llvm/DebugInfo/DWARFDebugAbbrev.h" +#include "llvm/DebugInfo/DWARFDebugInfoEntry.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; +using namespace syntax; + +// 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, const DWARFUnit *u, +void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u, unsigned recurseDepth, unsigned indent) const { DataExtractor debug_info_data = u->getDebugInfoExtractor(); @@ -28,15 +41,17 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, if (debug_info_data.isValidOffset(offset)) { uint32_t abbrCode = debug_info_data.getULEB128(&offset); + WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset); - OS << format("\n0x%8.8x: ", Offset); if (abbrCode) { if (AbbrevDecl) { - const char *tagString = TagString(getTag()); - if (tagString) - OS.indent(indent) << tagString; - else - OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); + const char *tagString = TagString(getTag()); + if (tagString) + WithColor(OS, syntax::Tag).get().indent(indent) << tagString; + else + WithColor(OS, syntax::Tag).get().indent(indent) << + format("DW_TAG_Unknown_%x", getTag()); + OS << format(" [%u] %c\n", abbrCode, AbbrevDecl->hasChildren() ? '*' : ' '); @@ -62,18 +77,51 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, } } +static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) { + OS << " ("; + do { + uint64_t Shift = countTrailingZeros(Val); + assert(Shift < 64 && "undefined behavior"); + uint64_t Bit = 1ULL << Shift; + 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) - OS << attrString; + WithColor(OS, syntax::Attribute) << attrString; else - OS << format("DW_AT_Unknown_%x", attr); + WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", attr); + const char *formString = FormEncodingString(form); if (formString) OS << " [" << formString << ']'; @@ -86,7 +134,49 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, return; OS << "\t("; - formValue.dump(OS, u); + + const char *Name = nullptr; + std::string File; + auto Color = syntax::Enumerator; + if (attr == DW_AT_decl_file || attr == DW_AT_call_file) { + Color = syntax::String; + 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) + WithColor(OS, Color) << 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 +374,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 +401,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 +411,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/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h b/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h deleted file mode 100644 index cc58eb6..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h +++ /dev/null @@ -1,157 +0,0 @@ -//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H -#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H - -#include "DWARFAbbreviationDeclaration.h" -#include "DWARFDebugRangeList.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/DIContext.h" -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -class DWARFDebugAranges; -class DWARFCompileUnit; -class DWARFUnit; -class DWARFContext; -class DWARFFormValue; -struct DWARFDebugInfoEntryInlinedChain; - -/// DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data. -class DWARFDebugInfoEntryMinimal { - /// Offset within the .debug_info of the start of this entry. - uint32_t Offset; - - /// How many to add to "this" to get the sibling. - uint32_t SiblingIdx; - - const DWARFAbbreviationDeclaration *AbbrevDecl; -public: - DWARFDebugInfoEntryMinimal() - : Offset(0), SiblingIdx(0), AbbrevDecl(nullptr) {} - - void dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth, - unsigned indent = 0) const; - void dumpAttribute(raw_ostream &OS, const 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, - /// starting at a given offset. If DIE can't be extracted, returns false and - /// doesn't change OffsetPtr. - bool extractFast(const DWARFUnit *U, uint32_t *OffsetPtr); - - uint32_t getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : 0; } - bool isNULL() const { return AbbrevDecl == nullptr; } - - /// Returns true if DIE represents a subprogram (not inlined). - bool isSubprogramDIE() const; - /// Returns true if DIE represents a subprogram or an inlined - /// subroutine. - bool isSubroutineDIE() const; - - uint32_t getOffset() const { return Offset; } - bool hasChildren() const { return !isNULL() && AbbrevDecl->hasChildren(); } - - // We know we are kept in a vector of contiguous entries, so we know - // our sibling will be some index after "this". - const DWARFDebugInfoEntryMinimal *getSibling() const { - return SiblingIdx > 0 ? this + SiblingIdx : nullptr; - } - - // We know we are kept in a vector of contiguous entries, so we know - // we don't need to store our child pointer, if we have a child it will - // be the next entry in the list... - const DWARFDebugInfoEntryMinimal *getFirstChild() const { - return hasChildren() ? this + 1 : nullptr; - } - - void setSibling(const DWARFDebugInfoEntryMinimal *Sibling) { - if (Sibling) { - // We know we are kept in a vector of contiguous entries, so we know - // our sibling will be some index after "this". - SiblingIdx = Sibling - this; - } else - SiblingIdx = 0; - } - - const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const { - return AbbrevDecl; - } - - bool getAttributeValue(const DWARFUnit *U, const uint16_t Attr, - DWARFFormValue &FormValue) const; - - const char *getAttributeValueAsString(const DWARFUnit *U, const uint16_t Attr, - const char *FailValue) const; - - uint64_t getAttributeValueAsAddress(const DWARFUnit *U, const uint16_t Attr, - uint64_t FailValue) const; - - uint64_t getAttributeValueAsUnsignedConstant(const DWARFUnit *U, - const uint16_t Attr, - uint64_t FailValue) const; - - uint64_t getAttributeValueAsReference(const DWARFUnit *U, const uint16_t Attr, - uint64_t FailValue) const; - - uint64_t getAttributeValueAsSectionOffset(const DWARFUnit *U, - const uint16_t Attr, - uint64_t FailValue) const; - - uint64_t getRangesBaseAttribute(const DWARFUnit *U, uint64_t FailValue) const; - - /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU. - /// Returns true if both attributes are present. - bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC, - uint64_t &HighPC) const; - - DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const; - - void collectChildrenAddressRanges(const DWARFUnit *U, - DWARFAddressRangesVector &Ranges) const; - - bool addressRangeContainsAddress(const DWARFUnit *U, - const uint64_t Address) const; - - /// If a DIE represents a subprogram (or inlined subroutine), - /// 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; - - /// Retrieves values of DW_AT_call_file, DW_AT_call_line and - /// DW_AT_call_column from DIE (or zeroes if they are missing). - void getCallerFrame(const DWARFUnit *U, uint32_t &CallFile, - uint32_t &CallLine, uint32_t &CallColumn) const; - - /// Get inlined chain for a given address, rooted at the current DIE. - /// Returns empty chain if address is not contained in address range - /// of current DIE. - DWARFDebugInfoEntryInlinedChain - getInlinedChainForAddress(const DWARFUnit *U, const uint64_t Address) const; -}; - -/// DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine -/// DIEs, (possibly ending with subprogram DIE), all of which are contained -/// in some concrete inlined instance tree. Address range for each DIE -/// (except the last DIE) in this chain is contained in address -/// range for next DIE in the chain. -struct DWARFDebugInfoEntryInlinedChain { - DWARFDebugInfoEntryInlinedChain() : U(nullptr) {} - SmallVector<DWARFDebugInfoEntryMinimal, 4> DIEs; - const DWARFUnit *U; -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp index ce87635..365a522 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugLine.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugLine.h" +#include "llvm/DebugInfo/DWARFDebugLine.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" @@ -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/contrib/llvm/lib/DebugInfo/DWARFDebugLine.h b/contrib/llvm/lib/DebugInfo/DWARFDebugLine.h deleted file mode 100644 index c7b7ec2..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugLine.h +++ /dev/null @@ -1,232 +0,0 @@ -//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H -#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H - -#include "DWARFRelocMap.h" -#include "llvm/DebugInfo/DIContext.h" -#include "llvm/Support/DataExtractor.h" -#include <map> -#include <string> -#include <vector> - -namespace llvm { - -class raw_ostream; - -class DWARFDebugLine { -public: - DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {} - struct FileNameEntry { - FileNameEntry() : Name(nullptr), DirIdx(0), ModTime(0), Length(0) {} - - const char *Name; - uint64_t DirIdx; - uint64_t ModTime; - uint64_t Length; - }; - - struct Prologue { - Prologue(); - - // The size in bytes of the statement information for this compilation unit - // (not including the total_length field itself). - uint32_t TotalLength; - // Version identifier for the statement information format. - uint16_t Version; - // The number of bytes following the prologue_length field to the beginning - // of the first byte of the statement program itself. - uint32_t PrologueLength; - // The size in bytes of the smallest target machine instruction. Statement - // program opcodes that alter the address register first multiply their - // operands by this value. - uint8_t MinInstLength; - // The maximum number of individual operations that may be encoded in an - // instruction. - uint8_t MaxOpsPerInst; - // The initial value of theis_stmtregister. - uint8_t DefaultIsStmt; - // This parameter affects the meaning of the special opcodes. See below. - int8_t LineBase; - // This parameter affects the meaning of the special opcodes. See below. - uint8_t LineRange; - // The number assigned to the first special opcode. - uint8_t OpcodeBase; - std::vector<uint8_t> StandardOpcodeLengths; - std::vector<const char*> IncludeDirectories; - std::vector<FileNameEntry> FileNames; - - // Length of the prologue in bytes. - uint32_t getLength() const { - return PrologueLength + sizeof(TotalLength) + sizeof(Version) + - sizeof(PrologueLength); - } - // Length of the line table data in bytes (not including the prologue). - uint32_t getStatementTableLength() const { - return TotalLength + sizeof(TotalLength) - getLength(); - } - int32_t getMaxLineIncrementForSpecialOpcode() const { - return LineBase + (int8_t)LineRange - 1; - } - - void clear(); - void dump(raw_ostream &OS) const; - bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr); - }; - - // Standard .debug_line state machine structure. - struct Row { - explicit Row(bool default_is_stmt = false); - - /// Called after a row is appended to the matrix. - void postAppend(); - void reset(bool default_is_stmt); - void dump(raw_ostream &OS) const; - - static bool orderByAddress(const Row& LHS, const Row& RHS) { - return LHS.Address < RHS.Address; - } - - // The program-counter value corresponding to a machine instruction - // generated by the compiler. - uint64_t Address; - // An unsigned integer indicating a source line number. Lines are numbered - // beginning at 1. The compiler may emit the value 0 in cases where an - // instruction cannot be attributed to any source line. - uint32_t Line; - // An unsigned integer indicating a column number within a source line. - // Columns are numbered beginning at 1. The value 0 is reserved to indicate - // that a statement begins at the 'left edge' of the line. - uint16_t Column; - // An unsigned integer indicating the identity of the source file - // corresponding to a machine instruction. - uint16_t File; - // An unsigned integer whose value encodes the applicable instruction set - // architecture for the current instruction. - uint8_t Isa; - // An unsigned integer representing the DWARF path discriminator value - // for this location. - uint32_t Discriminator; - // A boolean indicating that the current instruction is the beginning of a - // statement. - uint8_t IsStmt:1, - // A boolean indicating that the current instruction is the - // beginning of a basic block. - BasicBlock:1, - // A boolean indicating that the current address is that of the - // first byte after the end of a sequence of target machine - // instructions. - EndSequence:1, - // A boolean indicating that the current address is one (of possibly - // many) where execution should be suspended for an entry breakpoint - // of a function. - PrologueEnd:1, - // A boolean indicating that the current address is one (of possibly - // many) where execution should be suspended for an exit breakpoint - // of a function. - EpilogueBegin:1; - }; - - // Represents a series of contiguous machine instructions. Line table for each - // compilation unit may consist of multiple sequences, which are not - // guaranteed to be in the order of ascending instruction address. - struct Sequence { - // Sequence describes instructions at address range [LowPC, HighPC) - // and is described by line table rows [FirstRowIndex, LastRowIndex). - uint64_t LowPC; - uint64_t HighPC; - unsigned FirstRowIndex; - unsigned LastRowIndex; - bool Empty; - - Sequence(); - void reset(); - - static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) { - return LHS.LowPC < RHS.LowPC; - } - bool isValid() const { - return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex); - } - bool containsPC(uint64_t pc) const { - return (LowPC <= pc && pc < HighPC); - } - }; - - struct LineTable { - LineTable(); - - void appendRow(const DWARFDebugLine::Row &R) { - Rows.push_back(R); - } - void appendSequence(const DWARFDebugLine::Sequence &S) { - Sequences.push_back(S); - } - - // Returns the index of the row with file/line info for a given address, - // or -1 if there is no such row. - uint32_t lookupAddress(uint64_t address) const; - - bool lookupAddressRange(uint64_t address, uint64_t size, - std::vector<uint32_t> &result) const; - - // Extracts filename by its index in filename table in prologue. - // Returns true on success. - bool getFileNameByIndex(uint64_t FileIndex, - DILineInfoSpecifier::FileLineInfoKind Kind, - std::string &Result) const; - - void dump(raw_ostream &OS) const; - void clear(); - - /// Parse prologue and all rows. - bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap, - uint32_t *offset_ptr); - - struct Prologue Prologue; - typedef std::vector<Row> RowVector; - typedef RowVector::const_iterator RowIter; - typedef std::vector<Sequence> SequenceVector; - typedef SequenceVector::const_iterator SequenceIter; - RowVector Rows; - SequenceVector Sequences; - }; - - const LineTable *getLineTable(uint32_t offset) const; - const LineTable *getOrParseLineTable(DataExtractor debug_line_data, - uint32_t offset); - -private: - struct ParsingState { - ParsingState(struct LineTable *LT); - - void resetRowAndSequence(); - void appendRowToMatrix(uint32_t offset); - - // Line table we're currently parsing. - struct LineTable *LineTable; - // The row number that starts at zero for the prologue, and increases for - // each row added to the matrix. - unsigned RowNumber; - struct Row Row; - struct Sequence Sequence; - }; - - typedef std::map<uint32_t, LineTable> LineTableMapTy; - typedef LineTableMapTy::iterator LineTableIter; - typedef LineTableMapTy::const_iterator LineTableConstIter; - - const RelocAddrMap *RelocMap; - LineTableMapTy LineTableMap; -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp index e4aa5dc..bc0133d 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.cpp @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugLoc.h" +#include "llvm/DebugInfo/DWARFDebugLoc.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Dwarf.h" using namespace llvm; diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h b/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h deleted file mode 100644 index 663acbb..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugLoc.h +++ /dev/null @@ -1,81 +0,0 @@ -//===-- DWARFDebugLoc.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGLOC_H -#define LLVM_DEBUGINFO_DWARFDEBUGLOC_H - -#include "DWARFRelocMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/DataExtractor.h" - -namespace llvm { - -class raw_ostream; - -class DWARFDebugLoc { - /// A single location within a location list. - struct Entry { - /// The beginning address of the instruction range. - uint64_t Begin; - /// The ending address of the instruction range. - uint64_t End; - /// The location of the variable within the specified range. - SmallVector<unsigned char, 4> Loc; - }; - - /// A list of locations that contain one variable. - struct LocationList { - /// The beginning offset where this location list is stored in the debug_loc - /// section. - unsigned Offset; - /// All the locations in which the variable is stored. - SmallVector<Entry, 2> Entries; - }; - - typedef SmallVector<LocationList, 4> LocationLists; - - /// A list of all the variables in the debug_loc section, each one describing - /// the locations in which the variable is stored. - LocationLists Locations; - - /// A map used to resolve binary relocations. - const RelocAddrMap &RelocMap; - -public: - DWARFDebugLoc(const RelocAddrMap &LocRelocMap) : RelocMap(LocRelocMap) {} - /// Print the location lists found within the debug_loc section. - void dump(raw_ostream &OS) const; - /// Parse the debug_loc section accessible via the 'data' parameter using the - /// specified address size to interpret the address ranges. - void parse(DataExtractor data, unsigned AddressSize); -}; - -class DWARFDebugLocDWO { - struct Entry { - uint64_t Start; - uint32_t Length; - SmallVector<unsigned char, 4> Loc; - }; - - struct LocationList { - unsigned Offset; - SmallVector<Entry, 2> Entries; - }; - - typedef SmallVector<LocationList, 4> LocationLists; - - LocationLists Locations; - -public: - void parse(DataExtractor data); - void dump(raw_ostream &OS) const; -}; -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp b/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp index 07b23b3..ce60deb 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFDebugRangeList.h" +#include "llvm/DebugInfo/DWARFDebugRangeList.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h b/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h deleted file mode 100644 index 587b550..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFDebugRangeList.h +++ /dev/null @@ -1,77 +0,0 @@ -//===-- DWARFDebugRangeList.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H -#define LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H - -#include "llvm/Support/DataExtractor.h" -#include <vector> - -namespace llvm { - -class raw_ostream; - -/// DWARFAddressRangesVector - represents a set of absolute address ranges. -typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector; - -class DWARFDebugRangeList { -public: - struct RangeListEntry { - // A beginning address offset. This address offset has the size of an - // address and is relative to the applicable base address of the - // compilation unit referencing this range list. It marks the beginning - // of an address range. - uint64_t StartAddress; - // An ending address offset. This address offset again has the size of - // an address and is relative to the applicable base address of the - // compilation unit referencing this range list. It marks the first - // address past the end of the address range. The ending address must - // be greater than or equal to the beginning address. - uint64_t EndAddress; - // The end of any given range list is marked by an end of list entry, - // which consists of a 0 for the beginning address offset - // and a 0 for the ending address offset. - bool isEndOfListEntry() const { - return (StartAddress == 0) && (EndAddress == 0); - } - // A base address selection entry consists of: - // 1. The value of the largest representable address offset - // (for example, 0xffffffff when the size of an address is 32 bits). - // 2. An address, which defines the appropriate base address for - // use in interpreting the beginning and ending address offsets of - // subsequent entries of the location list. - bool isBaseAddressSelectionEntry(uint8_t AddressSize) const { - assert(AddressSize == 4 || AddressSize == 8); - if (AddressSize == 4) - return StartAddress == -1U; - else - return StartAddress == -1ULL; - } - }; - -private: - // Offset in .debug_ranges section. - uint32_t Offset; - uint8_t AddressSize; - std::vector<RangeListEntry> Entries; - -public: - DWARFDebugRangeList() { clear(); } - void clear(); - void dump(raw_ostream &OS) const; - bool extract(DataExtractor data, uint32_t *offset_ptr); - /// getAbsoluteRanges - Returns absolute address ranges defined by this range - /// list. Has to be passed base address of the compile unit referencing this - /// range list. - DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const; -}; - -} // namespace llvm - -#endif // LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H diff --git a/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp b/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp index 8d0f966..d784bfc 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFFormValue.cpp @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DebugInfo/DWARFFormValue.h" -#include "DWARFCompileUnit.h" -#include "DWARFContext.h" +#include "SyntaxHighlighting.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/DWARFCompileUnit.h" +#include "llvm/DebugInfo/DWARFContext.h" +#include "llvm/DebugInfo/DWARFFormValue.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" @@ -19,6 +20,7 @@ #include <cassert> using namespace llvm; using namespace dwarf; +using namespace syntax; namespace { uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { @@ -139,6 +141,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 +183,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 +199,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 +220,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 +364,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; @@ -423,9 +425,10 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); Optional<const char *> DbgStr = getAsCString(cu); if (DbgStr.hasValue()) { - OS << '"'; - OS.write_escaped(DbgStr.getValue()); - OS << '"'; + raw_ostream &COS = WithColor(OS, syntax::String); + COS << '"'; + COS.write_escaped(DbgStr.getValue()); + COS << '"'; } break; } @@ -433,9 +436,10 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue); Optional<const char *> DbgStr = getAsCString(cu); if (DbgStr.hasValue()) { - OS << '"'; - OS.write_escaped(DbgStr.getValue()); - OS << '"'; + raw_ostream &COS = WithColor(OS, syntax::String); + COS << '"'; + COS.write_escaped(DbgStr.getValue()); + COS << '"'; } break; } @@ -479,8 +483,12 @@ DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { break; } - if (cu_relative_offset) - OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0)); + if (cu_relative_offset) { + OS << " => {"; + WithColor(OS, syntax::Address).get() + << format("0x%8.8" PRIx64, uvalue + (cu ? cu->getOffset() : 0)); + OS << "}"; + } } Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const { @@ -543,7 +551,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/contrib/llvm/lib/DebugInfo/DWARFRelocMap.h b/contrib/llvm/lib/DebugInfo/DWARFRelocMap.h deleted file mode 100644 index 6929e36..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFRelocMap.h +++ /dev/null @@ -1,22 +0,0 @@ -//===-- DWARFRelocMap.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFRELOCMAP_H -#define LLVM_DEBUGINFO_DWARFRELOCMAP_H - -#include "llvm/ADT/DenseMap.h" - -namespace llvm { - -typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap; - -} // namespace llvm - -#endif // LLVM_DEBUGINFO_DWARFRELOCMAP_H - diff --git a/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.cpp b/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.cpp index 303bf70..6e93e28 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "DWARFTypeUnit.h" +#include "llvm/DebugInfo/DWARFTypeUnit.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" diff --git a/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h b/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h deleted file mode 100644 index cf773b8..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFTypeUnit.h +++ /dev/null @@ -1,37 +0,0 @@ -//===-- DWARFTypeUnit.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFTYPEUNIT_H -#define LLVM_DEBUGINFO_DWARFTYPEUNIT_H - -#include "DWARFUnit.h" - -namespace llvm { - -class DWARFTypeUnit : public DWARFUnit { -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) {} - uint32_t getHeaderSize() const override { - return DWARFUnit::getHeaderSize() + 12; - } - void dump(raw_ostream &OS); -protected: - bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override; -}; - -} - -#endif - diff --git a/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp b/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp index 39d0a0f..395a179 100644 --- a/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp +++ b/contrib/llvm/lib/DebugInfo/DWARFUnit.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#include "DWARFUnit.h" -#include "DWARFContext.h" +#include "llvm/DebugInfo/DWARFUnit.h" +#include "llvm/DebugInfo/DWARFContext.h" #include "llvm/DebugInfo/DWARFFormValue.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Path.h" @@ -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/contrib/llvm/lib/DebugInfo/DWARFUnit.h b/contrib/llvm/lib/DebugInfo/DWARFUnit.h deleted file mode 100644 index 471da36..0000000 --- a/contrib/llvm/lib/DebugInfo/DWARFUnit.h +++ /dev/null @@ -1,163 +0,0 @@ -//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_DWARFUNIT_H -#define LLVM_DEBUGINFO_DWARFUNIT_H - -#include "DWARFDebugAbbrev.h" -#include "DWARFDebugInfoEntry.h" -#include "DWARFDebugRangeList.h" -#include "DWARFRelocMap.h" -#include <vector> - -namespace llvm { - -namespace object { -class ObjectFile; -} - -class DWARFDebugAbbrev; -class StringRef; -class raw_ostream; - -class DWARFUnit { - const DWARFDebugAbbrev *Abbrev; - StringRef InfoSection; - StringRef RangeSection; - uint32_t RangeSectionBase; - StringRef StringSection; - StringRef StringOffsetSection; - StringRef AddrOffsetSection; - uint32_t AddrOffsetSectionBase; - const RelocAddrMap *RelocMap; - bool isLittleEndian; - - uint32_t Offset; - uint32_t Length; - uint16_t Version; - const DWARFAbbreviationDeclarationSet *Abbrevs; - uint8_t AddrSize; - uint64_t BaseAddr; - // The compile unit debug information entry items. - std::vector<DWARFDebugInfoEntryMinimal> DieArray; - - class DWOHolder { - std::unique_ptr<object::ObjectFile> DWOFile; - std::unique_ptr<DWARFContext> DWOContext; - DWARFUnit *DWOU; - public: - DWOHolder(object::ObjectFile *DWOFile); - DWARFUnit *getUnit() const { return DWOU; } - }; - std::unique_ptr<DWOHolder> DWO; - -protected: - virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr); - /// Size in bytes of the unit header. - 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); - - virtual ~DWARFUnit(); - - StringRef getStringSection() const { return StringSection; } - StringRef getStringOffsetSection() const { return StringOffsetSection; } - void setAddrOffsetSection(StringRef AOS, uint32_t Base) { - AddrOffsetSection = AOS; - AddrOffsetSectionBase = Base; - } - void setRangesSection(StringRef RS, uint32_t Base) { - RangeSection = RS; - RangeSectionBase = Base; - } - - bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const; - // FIXME: Result should be uint64_t in DWARF64. - bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const; - - DataExtractor getDebugInfoExtractor() const { - return DataExtractor(InfoSection, isLittleEndian, AddrSize); - } - DataExtractor getStringExtractor() const { - return DataExtractor(StringSection, false, 0); - } - - const RelocAddrMap *getRelocMap() const { return RelocMap; } - - bool extract(DataExtractor debug_info, uint32_t* offset_ptr); - - /// extractRangeList - extracts the range list referenced by this compile - /// unit from .debug_ranges section. Returns true on success. - /// Requires that compile unit is already extracted. - bool extractRangeList(uint32_t RangeListOffset, - DWARFDebugRangeList &RangeList) const; - void clear(); - uint32_t getOffset() const { return Offset; } - uint32_t getNextUnitOffset() const { return Offset + Length + 4; } - uint32_t getLength() const { return Length; } - uint16_t getVersion() const { return Version; } - const DWARFAbbreviationDeclarationSet *getAbbreviations() const { - return Abbrevs; - } - uint8_t getAddressByteSize() const { return AddrSize; } - uint64_t getBaseAddress() const { return BaseAddr; } - - void setBaseAddress(uint64_t base_addr) { - BaseAddr = base_addr; - } - - const DWARFDebugInfoEntryMinimal * - getCompileUnitDIE(bool extract_cu_die_only = true) { - extractDIEsIfNeeded(extract_cu_die_only); - return DieArray.empty() ? nullptr : &DieArray[0]; - } - - const char *getCompilationDir(); - uint64_t getDWOId(); - - void collectAddressRanges(DWARFAddressRangesVector &CURanges); - - /// getInlinedChainForAddress - fetches inlined chain for a given address. - /// Returns empty chain if there is no subprogram containing address. The - /// chain is valid as long as parsed compile unit DIEs are not cleared. - DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address); - -private: - /// Size in bytes of the .debug_info data associated with this compile unit. - size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); } - - /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it - /// hasn't already been done. Returns the number of DIEs parsed at this call. - size_t extractDIEsIfNeeded(bool CUDieOnly); - /// extractDIEsToVector - Appends all parsed DIEs to a vector. - void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs, - std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const; - /// setDIERelations - We read in all of the DIE entries into our flat list - /// of DIE entries and now we need to go back through all of them and set the - /// parent, sibling and child pointers for quick DIE navigation. - void setDIERelations(); - /// clearDIEs - Clear parsed DIEs to keep memory usage low. - void clearDIEs(bool KeepCUDie); - - /// parseDWO - Parses .dwo file for current compile unit. Returns true if - /// it was actually constructed. - bool parseDWO(); - - /// getSubprogramForAddress - Returns subprogram DIE with address range - /// encompassing the provided address. The pointer is alive as long as parsed - /// compile unit DIEs are not cleared. - const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address); -}; - -} - -#endif diff --git a/contrib/llvm/lib/DebugInfo/SyntaxHighlighting.cpp b/contrib/llvm/lib/DebugInfo/SyntaxHighlighting.cpp new file mode 100644 index 0000000..a6b4c65 --- /dev/null +++ b/contrib/llvm/lib/DebugInfo/SyntaxHighlighting.cpp @@ -0,0 +1,37 @@ +//===-- SyntaxHighlighting.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SyntaxHighlighting.h" +#include "llvm/Support/CommandLine.h" +using namespace llvm; +using namespace dwarf; +using namespace syntax; + +static cl::opt<cl::boolOrDefault> + UseColor("color", + cl::desc("use colored syntax highlighting (default=autodetect)"), + cl::init(cl::BOU_UNSET)); + +WithColor::WithColor(llvm::raw_ostream &OS, enum HighlightColor Type) : OS(OS) { + // Detect color from terminal type unless the user passed the --color option. + if (UseColor == cl::BOU_UNSET ? OS.has_colors() : UseColor == cl::BOU_TRUE) { + switch (Type) { + case Address: OS.changeColor(llvm::raw_ostream::YELLOW); break; + case String: OS.changeColor(llvm::raw_ostream::GREEN); break; + case Tag: OS.changeColor(llvm::raw_ostream::BLUE); break; + case Attribute: OS.changeColor(llvm::raw_ostream::CYAN); break; + case Enumerator: OS.changeColor(llvm::raw_ostream::MAGENTA); break; + } + } +} + +WithColor::~WithColor() { + if (UseColor == cl::BOU_UNSET ? OS.has_colors() : UseColor == cl::BOU_TRUE) + OS.resetColor(); +} diff --git a/contrib/llvm/lib/DebugInfo/SyntaxHighlighting.h b/contrib/llvm/lib/DebugInfo/SyntaxHighlighting.h new file mode 100644 index 0000000..946a313 --- /dev/null +++ b/contrib/llvm/lib/DebugInfo/SyntaxHighlighting.h @@ -0,0 +1,39 @@ +//===-- SyntaxHighlighting.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_SYNTAXHIGHLIGHTING_H +#define LLVM_LIB_DEBUGINFO_SYNTAXHIGHLIGHTING_H + +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +namespace dwarf { +namespace syntax { + +// Symbolic names for various syntax elements. +enum HighlightColor { Address, String, Tag, Attribute, Enumerator }; + +/// An RAII object that temporarily switches an output stream to a +/// specific color. +class WithColor { + llvm::raw_ostream &OS; + +public: + /// To be used like this: WithColor(OS, syntax::String) << "text"; + WithColor(llvm::raw_ostream &OS, enum HighlightColor Type); + ~WithColor(); + + llvm::raw_ostream& get() { return OS; } + operator llvm::raw_ostream& () { return OS; } +}; +} +} +} + +#endif |