diff options
Diffstat (limited to 'include/llvm/DebugInfo/DWARF')
23 files changed, 587 insertions, 245 deletions
diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h index db9bd506be897..7324f6e3eb387 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -1,4 +1,4 @@ -//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===// +//===- DWARFAbbreviationDeclaration.h ---------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,22 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H -#define LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H +#ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H +#define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Dwarf.h" +#include <cassert> +#include <cstddef> +#include <cstdint> + namespace llvm { -class DWARFUnit; class DWARFFormValue; +class DWARFUnit; class raw_ostream; class DWARFAbbreviationDeclaration { @@ -25,6 +30,7 @@ public: struct AttributeSpec { AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional<int64_t> V) : Attr(A), Form(F), ByteSizeOrValue(V) {} + dwarf::Attribute Attr; dwarf::Form Form; /// The following field is used for ByteSize for non-implicit_const @@ -41,9 +47,11 @@ public: /// * Form == DW_FORM_implicit_const: /// ByteSizeOrValue contains value for the implicit_const attribute. Optional<int64_t> ByteSizeOrValue; + bool isImplicitConst() const { return Form == dwarf::DW_FORM_implicit_const; } + /// Get the fixed byte size of this Form if possible. This function might /// use the DWARFUnit to calculate the size of the Form, like for /// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for @@ -55,6 +63,7 @@ public: DWARFAbbreviationDeclaration(); uint32_t getCode() const { return Code; } + uint8_t getCodeByteSize() const { return CodeByteSize; } dwarf::Tag getTag() const { return Tag; } bool hasChildren() const { return HasChildren; } @@ -66,9 +75,17 @@ public: } dwarf::Form getFormByIndex(uint32_t idx) const { - if (idx < AttributeSpecs.size()) - return AttributeSpecs[idx].Form; - return dwarf::Form(0); + assert(idx < AttributeSpecs.size()); + return AttributeSpecs[idx].Form; + } + + size_t getNumAttributes() const { + return AttributeSpecs.size(); + } + + dwarf::Attribute getAttrByIndex(uint32_t idx) const { + assert(idx < AttributeSpecs.size()); + return AttributeSpecs[idx].Attr; } /// Get the index of the specified attribute. @@ -109,16 +126,16 @@ private: /// abbreviation declaration. struct FixedSizeInfo { /// The fixed byte size for fixed size forms. - uint16_t NumBytes; + uint16_t NumBytes = 0; /// Number of DW_FORM_address forms in this abbrevation declaration. - uint8_t NumAddrs; + uint8_t NumAddrs = 0; /// Number of DW_FORM_ref_addr forms in this abbrevation declaration. - uint8_t NumRefAddrs; + uint8_t NumRefAddrs = 0; /// Number of 4 byte in DWARF32 and 8 byte in DWARF64 forms. - uint8_t NumDwarfOffsets; - /// Constructor - FixedSizeInfo() - : NumBytes(0), NumAddrs(0), NumRefAddrs(0), NumDwarfOffsets(0) {} + uint8_t NumDwarfOffsets = 0; + + FixedSizeInfo() = default; + /// Calculate the fixed size in bytes given a DWARFUnit. /// /// \param U the DWARFUnit to use when determing the byte size. @@ -138,6 +155,6 @@ private: Optional<FixedSizeInfo> FixedAttributeSize; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index 63343728fa99a..f95a013d75523 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -1,4 +1,4 @@ -//===--- DWARFAcceleratorTable.h --------------------------------*- C++ -*-===// +//===- DWARFAcceleratorTable.h ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,19 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H -#define LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H +#ifndef LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H +#define LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H #include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" +#include "llvm/Support/DataExtractor.h" #include "llvm/Support/Dwarf.h" #include <cstdint> +#include <utility> namespace llvm { -class DWARFAcceleratorTable { +class raw_ostream; +class DWARFAcceleratorTable { struct Header { uint32_t Magic; uint16_t Version; @@ -41,6 +43,7 @@ class DWARFAcceleratorTable { DataExtractor AccelSection; DataExtractor StringSection; const RelocAddrMap& Relocs; + public: DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection, const RelocAddrMap &Relocs) @@ -50,6 +53,6 @@ public: void dump(raw_ostream &OS) const; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFAttribute.h b/include/llvm/DebugInfo/DWARF/DWARFAttribute.h new file mode 100644 index 0000000000000..5919aaddea409 --- /dev/null +++ b/include/llvm/DebugInfo/DWARF/DWARFAttribute.h @@ -0,0 +1,56 @@ +//===- DWARFAttribute.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_DWARFATTRIBUTE_H +#define LLVM_DEBUGINFO_DWARFATTRIBUTE_H + +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" +#include "llvm/Support/Dwarf.h" +#include <cstdint> + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// Encapsulates a DWARF attribute value and all of the data required to +/// describe the attribute value. +/// +/// This class is designed to be used by clients that want to iterate across all +/// attributes in a DWARFDie. +struct DWARFAttribute { + /// The debug info/types offset for this attribute. + uint32_t Offset = 0; + /// The debug info/types section byte size of the data for this attribute. + uint32_t ByteSize = 0; + /// The attribute enumeration of this attribute. + dwarf::Attribute Attr; + /// The form and value for this attribute. + DWARFFormValue Value; + + DWARFAttribute(uint32_t O, dwarf::Attribute A = dwarf::Attribute(0), + dwarf::Form F = dwarf::Form(0)) : Attr(A), Value(F) {} + + bool isValid() const { + return Offset != 0 && Attr != dwarf::Attribute(0); + } + + explicit operator bool() const { + return isValid(); + } + + void clear() { + Offset = 0; + ByteSize = 0; + Attr = dwarf::Attribute(0); + Value = DWARFFormValue(); + } +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARFATTRIBUTE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index bba3abe6e9e96..b2a4d247ccc6b 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -1,4 +1,4 @@ -//===-- DWARFCompileUnit.h --------------------------------------*- C++ -*-===// +//===- DWARFCompileUnit.h ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H -#define LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H +#ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H +#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H #include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" namespace llvm { @@ -23,12 +24,15 @@ public: const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} - void dump(raw_ostream &OS); - static const DWARFSectionKind Section = DW_SECT_INFO; + // VTable anchor. ~DWARFCompileUnit() override; + + void dump(raw_ostream &OS); + + static const DWARFSectionKind Section = DW_SECT_INFO; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index ef310e7040054..f941cdd1060a5 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -1,4 +1,4 @@ -//===-- DWARFContext.h ------------------------------------------*- C++ -*-===// +//===- DWARFContext.h -------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,15 @@ // //===----------------------------------------------------------------------===/ -#ifndef LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H -#define LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H +#define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" @@ -30,6 +31,7 @@ #include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Host.h" #include <cstdint> #include <deque> #include <map> @@ -38,6 +40,9 @@ namespace llvm { +class MemoryBuffer; +class raw_ostream; + // In place of applying the relocations to the data we've read from disk we use // a separate mapping table to the side and checking that at locations in the // dwarf where we expect relocated values. This adds a bit of complexity to the @@ -293,10 +298,16 @@ class DWARFContextInMemory : public DWARFContext { SmallVector<SmallString<32>, 4> UncompressedSections; + StringRef *MapSectionToMember(StringRef Name); + public: DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr); + DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, + uint8_t AddrSize, + bool isLittleEndian = sys::IsLittleEndianHost); + bool isLittleEndian() const override { return IsLittleEndian; } uint8_t getAddressSize() const override { return AddressSize; } const DWARFSection &getInfoSection() override { return InfoSection; } @@ -321,20 +332,26 @@ public: // Sections for DWARF5 split dwarf proposal. const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; } + const TypeSectionMap &getTypesDWOSections() override { return TypesDWOSections; } + StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; } const DWARFSection &getLineDWOSection() override { return LineDWOSection; } const DWARFSection &getLocDWOSection() override { return LocDWOSection; } StringRef getStringDWOSection() override { return StringDWOSection; } + StringRef getStringOffsetDWOSection() override { return StringOffsetDWOSection; } + StringRef getRangeDWOSection() override { return RangeDWOSection; } + StringRef getAddrSection() override { return AddrSection; } + StringRef getCUIndexSection() override { return CUIndexSection; } StringRef getGdbIndexSection() override { return GdbIndexSection; } StringRef getTUIndexSection() override { return TUIndexSection; } @@ -342,4 +359,4 @@ public: } // end namespace llvm -#endif // LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H +#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h index f732deef548c8..9f86fe5083896 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugAbbrev.h --------------------------------------*- C++ -*-===// +//===- DWARFDebugAbbrev.h ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGABBREV_H +#define LLVM_DEBUGINFO_DWARFDEBUGABBREV_H #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" +#include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <map> #include <vector> @@ -76,6 +78,6 @@ private: void clear(); }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGABBREV_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h index 5a602392add81..40eb7e9a88364 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===// +//===- DWARFDebugArangeSet.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H +#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H #include "llvm/ADT/iterator_range.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <vector> namespace llvm { @@ -40,6 +41,7 @@ public: struct Descriptor { uint64_t Address; uint64_t Length; + uint64_t getEndAddress() const { return Address + Length; } }; @@ -53,6 +55,7 @@ private: public: DWARFDebugArangeSet() { clear(); } + void clear(); bool extract(DataExtractor data, uint32_t *offset_ptr); void dump(raw_ostream &OS) const; @@ -67,6 +70,6 @@ public: } }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h index 791f010a8892b..c06771d6afb43 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===// +//===- DWARFDebugAranges.h --------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H +#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H #include "llvm/ADT/DenseSet.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <vector> namespace llvm { @@ -42,6 +43,7 @@ private: else Length = HighPC - LowPC; } + uint64_t HighPC() const { if (Length) return LowPC + Length; @@ -51,6 +53,7 @@ private: bool containsAddress(uint64_t Address) const { return LowPC <= Address && Address < HighPC(); } + bool operator<(const Range &other) const { return LowPC < other.LowPC; } @@ -73,7 +76,6 @@ private: } }; - typedef std::vector<Range> RangeColl; typedef RangeColl::const_iterator RangeCollIterator; @@ -82,6 +84,6 @@ private: DenseSet<uint32_t> ParsedCUOffsets; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGARANGES_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h index cd76c909ddaef..e0a779bb81823 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===// +//===- DWARFDebugFrame.h - Parsing of .debug_frame --------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,23 +7,24 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/raw_ostream.h" #include <memory> #include <vector> namespace llvm { class FrameEntry; +class raw_ostream; /// \brief A parsed .debug_frame or .eh_frame section /// class DWARFDebugFrame { // True if this is parsing an eh_frame section. bool IsEH; + public: DWARFDebugFrame(bool IsEH); ~DWARFDebugFrame(); @@ -39,7 +40,6 @@ private: std::vector<std::unique_ptr<FrameEntry>> Entries; }; +} // end namespace llvm -} // namespace llvm - -#endif +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h index f36f470980b1a..fc2423a2708b8 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===// +//===- DWARFDebugInfoEntry.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,43 +7,37 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H +#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H -#include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" -#include "llvm/Support/DataTypes.h" #include "llvm/Support/Dwarf.h" +#include <cstdint> namespace llvm { -class DWARFDebugAranges; -class DWARFCompileUnit; +class DataExtractor; class DWARFUnit; -class DWARFContext; -class DWARFFormValue; -struct DWARFDebugInfoEntryInlinedChain; /// DWARFDebugInfoEntry - A DIE with only the minimum required data. class DWARFDebugInfoEntry { /// Offset within the .debug_info of the start of this entry. - uint32_t Offset; + uint32_t Offset = 0; /// The integer depth of this DIE within the compile unit DIEs where the /// compile/type unit DIE has a depth of zero. - uint32_t Depth; + uint32_t Depth = 0; + + const DWARFAbbreviationDeclaration *AbbrevDecl = nullptr; - const DWARFAbbreviationDeclaration *AbbrevDecl; public: - DWARFDebugInfoEntry() - : Offset(0), Depth(0), AbbrevDecl(nullptr) {} + DWARFDebugInfoEntry() = default; /// 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); + /// High performance extraction should use this call. bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr, const DataExtractor &DebugInfoData, @@ -52,15 +46,18 @@ public: uint32_t getOffset() const { return Offset; } uint32_t getDepth() const { return Depth; } + dwarf::Tag getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : dwarf::DW_TAG_null; } + bool hasChildren() const { return AbbrevDecl && AbbrevDecl->hasChildren(); } + const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const { return AbbrevDecl; } }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 878f1c76ebf67..e5bb24707b638 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// +//===- DWARFDebugLine.h -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H +#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <map> #include <string> #include <vector> @@ -24,13 +25,14 @@ class raw_ostream; class DWARFDebugLine { public: DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {} + struct FileNameEntry { - FileNameEntry() : Name(nullptr), DirIdx(0), ModTime(0), Length(0) {} + FileNameEntry() = default; - const char *Name; - uint64_t DirIdx; - uint64_t ModTime; - uint64_t Length; + const char *Name = nullptr; + uint64_t DirIdx = 0; + uint64_t ModTime = 0; + uint64_t Length = 0; }; struct Prologue { @@ -64,9 +66,11 @@ public: std::vector<FileNameEntry> FileNames; bool IsDWARF64; + uint32_t sizeofTotalLength() const { return IsDWARF64 ? 12 : 4; } + uint32_t sizeofPrologueLength() const { return IsDWARF64 ? 8 : 4; } @@ -76,10 +80,12 @@ public: return PrologueLength + sizeofTotalLength() + sizeof(Version) + sizeofPrologueLength(); } + // Length of the line table data in bytes (not including the prologue). uint32_t getStatementTableLength() const { return TotalLength + sizeofTotalLength() - getLength(); } + int32_t getMaxLineIncrementForSpecialOpcode() const { return LineBase + (int8_t)LineRange - 1; } @@ -146,6 +152,8 @@ public: // compilation unit may consist of multiple sequences, which are not // guaranteed to be in the order of ascending instruction address. struct Sequence { + Sequence(); + // Sequence describes instructions at address range [LowPC, HighPC) // and is described by line table rows [FirstRowIndex, LastRowIndex). uint64_t LowPC; @@ -154,15 +162,16 @@ public: 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); } @@ -177,6 +186,7 @@ public: void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); } + void appendSequence(const DWARFDebugLine::Sequence &S) { Sequences.push_back(S); } @@ -249,6 +259,7 @@ private: const RelocAddrMap *RelocMap; LineTableMapTy LineTableMap; }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARFDEBUGLINE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index bd44c2e5aab9b..6d4cd8d1b5a3c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugLoc.h -----------------------------------------*- C++ -*-===// +//===- DWARFDebugLoc.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> namespace llvm { @@ -49,8 +50,10 @@ class DWARFDebugLoc { 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); @@ -76,6 +79,7 @@ public: void parse(DataExtractor data); void dump(raw_ostream &OS) const; }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h index 5a0352dacdb9e..85d98b45afcd5 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugMacro.h ---------------------------------------*- C++ -*-===// +//===- DWARFDebugMacro.h ----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -50,6 +50,7 @@ public: /// Print the macro list found within the debug_macinfo section. void dump(raw_ostream &OS) const; + /// Parse the debug_macinfo section accessible via the 'data' parameter. void parse(DataExtractor data); }; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h index 2b23837e32d69..9d36bb7ad211c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugPubTable.h ------------------------------------*- C++ -*-===// +//===- DWARFDebugPubTable.h -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/DataExtractor.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Dwarf.h" +#include <cstdint> #include <vector> namespace llvm { @@ -28,7 +28,7 @@ public: uint32_t SecOffset; /// An entry of the various gnu_pub* debug sections. - llvm::dwarf::PubIndexEntryDescriptor Descriptor; + dwarf::PubIndexEntryDescriptor Descriptor; /// The name of the object as given by the DW_AT_name attribute of the /// referenced DIE. @@ -68,10 +68,12 @@ private: public: DWARFDebugPubTable(StringRef Data, bool LittleEndian, bool GnuStyle); + void dump(StringRef Name, raw_ostream &OS) const; ArrayRef<Set> getData() { return Sets; } }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index c930bd603d4d5..018a049a3ed81 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugRangeList.h -----------------------------------*- C++ -*-===// +//===- DWARFDebugRangeList.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H #include "llvm/Support/DataExtractor.h" +#include <cassert> +#include <cstdint> +#include <utility> #include <vector> namespace llvm { @@ -34,12 +37,14 @@ public: // 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). @@ -63,6 +68,7 @@ private: public: DWARFDebugRangeList() { clear(); } + void clear(); void dump(raw_ostream &OS) const; bool extract(DataExtractor data, uint32_t *offset_ptr); @@ -74,6 +80,6 @@ public: DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const; }; -} // namespace llvm +} // end namespace llvm -#endif // LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h index e335e28b39d73..33e24fe3adc90 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -1,4 +1,4 @@ -//===-- DWARFDie.h --------------------------------------------------------===// +//===- DWARFDie.h -----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,18 +7,25 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDIE_H -#define LLVM_LIB_DEBUGINFO_DWARFDIE_H +#ifndef LLVM_DEBUGINFO_DWARFDIE_H +#define LLVM_DEBUGINFO_DWARFDIE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFAttribute.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" +#include "llvm/Support/Dwarf.h" +#include <cassert> +#include <cstdint> +#include <iterator> namespace llvm { class DWARFUnit; -class DWARFDebugInfoEntry; class raw_ostream; //===----------------------------------------------------------------------===// @@ -34,10 +41,11 @@ class raw_ostream; /// also simplifies the attribute extraction calls by not having to specify the /// DWARFUnit for each call. class DWARFDie { - DWARFUnit *U; - const DWARFDebugInfoEntry *Die; + DWARFUnit *U = nullptr; + const DWARFDebugInfoEntry *Die = nullptr; + public: - DWARFDie() : U(nullptr), Die(nullptr) {} + DWARFDie() = default; DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {} bool isValid() const { return U && Die; } @@ -45,7 +53,6 @@ public: const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; } DWARFUnit *getDwarfUnit() const { return U; } - /// Get the abbreviation declaration for this DIE. /// /// \returns the abbreviation declaration or NULL for null tags. @@ -78,6 +85,7 @@ public: bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; } + /// Returns true if DIE represents a subprogram (not inlined). bool isSubprogramDIE() const; @@ -123,76 +131,33 @@ public: /// \param Attr the attribute to extract. /// \returns an optional DWARFFormValue that will have the form value if the /// attribute was successfully extracted. - Optional<DWARFFormValue> getAttributeValue(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as a C string. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \param FailValue the value to return if this DIE doesn't have this - /// attribute. - /// \returns the NULL terminated C string value owned by the DWARF section - /// that contains the string or FailValue if the attribute doesn't exist or - /// if the attribute's form isn't a form that describes an string. - const char *getAttributeValueAsString(dwarf::Attribute Attr, - const char *FailValue) const; + Optional<DWARFFormValue> find(dwarf::Attribute Attr) const; - /// Extract the specified attribute from this DIE as an address. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> getAttributeValueAsAddress(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as a signed integer. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<int64_t> - getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as an unsigned integer. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> - getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const; + /// Extract the first value of any attribute in Attrs from this DIE. + /// + /// Extract the first attribute that matches from this DIE only. This call + /// doesn't look for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. The attributes will be searched + /// linearly in the order they are specified within Attrs. + /// + /// \param Attrs an array of DWARF attribute to look for. + /// \returns an optional that has a valid DWARFFormValue for the first + /// matching attribute in Attrs, or None if none of the attributes in Attrs + /// exist in this DIE. + Optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const; + + /// Extract the first value of any attribute in Attrs from this DIE and + /// recurse into any DW_AT_specification or DW_AT_abstract_origin referenced + /// DIEs. + /// + /// \param Attrs an array of DWARF attribute to look for. + /// \returns an optional that has a valid DWARFFormValue for the first + /// matching attribute in Attrs, or None if none of the attributes in Attrs + /// exist in this DIE or in any DW_AT_specification or DW_AT_abstract_origin + /// DIEs. + Optional<DWARFFormValue> + findRecursively(ArrayRef<dwarf::Attribute> Attrs) const; - /// Extract the specified attribute from this DIE as absolute DIE Offset. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> getAttributeValueAsReference(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as absolute section offset. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> - getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const; - /// Extract the specified attribute from this DIE as the referenced DIE. /// /// Regardless of the reference type, return the correct DWARFDie instance if @@ -266,6 +231,12 @@ public: /// references if necessary. Returns null if no name is found. const char *getName(DINameKind Kind) const; + /// Returns the declaration line (start line) for a DIE, assuming it specifies + /// a subprogram. This may be fetched from specification or abstract origin + /// for this subprogram by resolving DW_AT_sepcification or + /// DW_AT_abstract_origin references if necessary. + uint64_t getDeclLine() 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). This function looks for /// DW_AT_call attributes in this DIE only, it will not resolve the attribute @@ -286,14 +257,47 @@ public: getInlinedChainForAddress(const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const; + class attribute_iterator; + + /// Get an iterator range to all attributes in the current DIE only. + /// + /// \returns an iterator range for the attributes of the current DIE. + iterator_range<attribute_iterator> attributes() const; + class iterator; iterator begin() const; iterator end() const; iterator_range<iterator> children() const; }; - +class DWARFDie::attribute_iterator : + public iterator_facade_base<attribute_iterator, std::forward_iterator_tag, + const DWARFAttribute> { + /// The DWARF DIE we are extracting attributes from. + DWARFDie Die; + /// The value vended to clients via the operator*() or operator->(). + DWARFAttribute AttrValue; + /// The attribute index within the abbreviation declaration in Die. + uint32_t Index; + + /// Update the attribute index and attempt to read the attribute value. If the + /// attribute is able to be read, update AttrValue and the Index member + /// variable. If the attribute value is not able to be read, an appropriate + /// error will be set if the Err member variable is non-NULL and the iterator + /// will be set to the end value so iteration stops. + void updateForIndex(const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I); + +public: + attribute_iterator() = delete; + explicit attribute_iterator(DWARFDie D, bool End); + + attribute_iterator &operator++(); + explicit operator bool() const { return AttrValue.isValid(); } + const DWARFAttribute &operator*() const { return AttrValue; } + bool operator==(const attribute_iterator &X) const { return Index == X.Index; } +}; + inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) { return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() && LHS.getDwarfUnit() == RHS.getDwarfUnit(); @@ -313,16 +317,19 @@ class DWARFDie::iterator : public iterator_facade_base<iterator, } public: iterator() = default; + explicit iterator(DWARFDie D) : Die(D) { // If we start out with only a Null DIE then invalidate. skipNull(); } + iterator &operator++() { Die = Die.getSibling(); // Don't include the NULL die when iterating. skipNull(); return *this; } + explicit operator bool() const { return Die.isValid(); } const DWARFDie &operator*() const { return Die; } bool operator==(const iterator &X) const { return Die == X.Die; } @@ -344,4 +351,4 @@ inline iterator_range<DWARFDie::iterator> DWARFDie::children() const { } // end namespace llvm -#endif // LLVM_LIB_DEBUGINFO_DWARFDIE_H +#endif // LLVM_DEBUGINFO_DWARFDIE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 1b7659dfb04ac..c8d7a0c1ac7a3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -1,4 +1,4 @@ -//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===// +//===- DWARFFormValue.h -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,13 +10,15 @@ #ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H #define LLVM_DEBUGINFO_DWARFFORMVALUE_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Dwarf.h" +#include <cstdint> namespace llvm { -template <typename T> class ArrayRef; class DWARFUnit; class raw_ostream; @@ -37,7 +39,7 @@ public: private: struct ValueType { - ValueType() : data(nullptr) { + ValueType() { uval = 0; } @@ -46,20 +48,27 @@ private: int64_t sval; const char* cstr; }; - const uint8_t* data; + const uint8_t* data = nullptr; }; dwarf::Form Form; // Form for this value. ValueType Value; // Contains all data for the form. - const DWARFUnit *U; // Remember the DWARFUnit at extract time. + const DWARFUnit *U = nullptr; // Remember the DWARFUnit at extract time. public: - DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F), U(nullptr) {} + DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {} + dwarf::Form getForm() const { return Form; } void setForm(dwarf::Form F) { Form = F; } void setUValue(uint64_t V) { Value.uval = V; } void setSValue(int64_t V) { Value.sval = V; } void setPValue(const char *V) { Value.cstr = V; } + + void setBlockValue(const ArrayRef<uint8_t> &Data) { + Value.data = Data.data(); + setUValue(Data.size()); + } + bool isFormClass(FormClass FC) const; const DWARFUnit *getUnit() const { return U; } void dump(raw_ostream &OS) const; @@ -72,6 +81,7 @@ public: /// \returns whether the extraction succeeded. bool extractValue(const DataExtractor &Data, uint32_t *OffsetPtr, const DWARFUnit *U); + bool isInlinedCStr() const { return Value.data != nullptr && Value.data == (const uint8_t*)Value.cstr; } @@ -87,6 +97,7 @@ public: Optional<ArrayRef<uint8_t>> getAsBlock() const; Optional<uint64_t> getAsCStringOffset() const; Optional<uint64_t> getAsReferenceUVal() const; + /// Get the fixed byte size for a given form. /// /// If the form always has a fixed valid byte size that doesn't depend on a @@ -105,6 +116,7 @@ public: /// and was needed to calculate the byte size. static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const DWARFUnit *U = nullptr); + /// Get the fixed byte size for a given form. /// /// If the form has a fixed byte size given a valid DWARF version and address @@ -133,6 +145,7 @@ public: /// \returns true on success, false if the form was not skipped. bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr, const DWARFUnit *U) const; + /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr. /// /// Skips the bytes for this form in the debug info and updates the offset. @@ -145,6 +158,7 @@ public: /// \returns true on success, false if the form was not skipped. static bool skipValue(dwarf::Form form, DataExtractor debug_info_data, uint32_t *offset_ptr, const DWARFUnit *U); + /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr. /// /// Skips the bytes for this form in the debug info and updates the offset. @@ -164,6 +178,154 @@ private: void dumpString(raw_ostream &OS) const; }; -} +namespace dwarf { + + /// Take an optional DWARFFormValue and try to extract a string value from it. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and was a string. + inline Optional<const char*> toString(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsCString(); + return None; + } + + /// Take an optional DWARFFormValue and extract a string value from it. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the string value or Default if the V doesn't have a value or the + /// form value's encoding wasn't a string. + inline const char* + toString(const Optional<DWARFFormValue>& V, const char *Default) { + return toString(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an unsigned constant. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a unsigned constant form. + inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsUnsignedConstant(); + return None; + } + + /// Take an optional DWARFFormValue and extract a unsigned constant. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted unsigned value or Default if the V doesn't have a + /// value or the form value's encoding wasn't an unsigned constant form. + inline uint64_t + toUnsigned(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toUnsigned(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an reference. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a reference form. + inline Optional<uint64_t> toReference(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsReference(); + return None; + } + + /// Take an optional DWARFFormValue and extract a reference. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted reference value or Default if the V doesn't have a + /// value or the form value's encoding wasn't a reference form. + inline uint64_t + toReference(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toReference(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an signed constant. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a signed constant form. + inline Optional<int64_t> toSigned(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsSignedConstant(); + return None; + } + + /// Take an optional DWARFFormValue and extract a signed integer. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted signed integer value or Default if the V doesn't + /// have a value or the form value's encoding wasn't a signed integer form. + inline int64_t + toSigned(const Optional<DWARFFormValue>& V, int64_t Default) { + return toSigned(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an address. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a address form. + inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsAddress(); + return None; + } + + /// Take an optional DWARFFormValue and extract a address. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted address value or Default if the V doesn't have a + /// value or the form value's encoding wasn't an address form. + inline uint64_t + toAddress(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toAddress(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an section offset. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a section offset form. + inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsSectionOffset(); + return None; + } + + /// Take an optional DWARFFormValue and extract a section offset. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted section offset value or Default if the V doesn't + /// have a value or the form value's encoding wasn't a section offset form. + inline uint64_t + toSectionOffset(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toSectionOffset(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract block data. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a block form. + inline Optional<ArrayRef<uint8_t>> + toBlock(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsBlock(); + return None; + } + +} // end namespace dwarf + +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h b/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h index 66041be965661..7a52218663b9d 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h +++ b/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h @@ -1,4 +1,4 @@ -//===-- DWARFGdbIndex.h -----------------------------------------*- C++ -*-===// +//===- DWARFGdbIndex.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H -#define LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H +#define LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/raw_ostream.h" +#include <cstdint> +#include <utility> namespace llvm { + +class raw_ostream; + class DWARFGdbIndex { uint32_t Version; @@ -63,6 +68,7 @@ public: bool HasContent = false; bool HasError = false; }; -} -#endif // LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h index d7fe3032e5054..af01bddeed153 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h +++ b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h @@ -1,4 +1,4 @@ -//===-- DWARFRelocMap.h -----------------------------------------*- C++ -*-===// +//===- DWARFRelocMap.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,16 +7,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H -#define LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H +#define LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H #include "llvm/ADT/DenseMap.h" +#include <cstdint> +#include <utility> namespace llvm { -typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap; +typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap; -} // namespace llvm - -#endif +} // end namespace llvm +#endif // LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFSection.h b/include/llvm/DebugInfo/DWARF/DWARFSection.h index 3e27b529e97bf..2b8a53a4c93ea 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFSection.h +++ b/include/llvm/DebugInfo/DWARF/DWARFSection.h @@ -1,4 +1,4 @@ -//===-- DWARFSection.h ------------------------------------------*- C++ -*-===// +//===- DWARFSection.h -------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFSECTION_H -#define LLVM_LIB_DEBUGINFO_DWARFSECTION_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFSECTION_H +#define LLVM_DEBUGINFO_DWARF_DWARFSECTION_H -#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" namespace llvm { @@ -20,6 +20,6 @@ struct DWARFSection { RelocAddrMap Relocs; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index 4f1e1292a1f1b..703316005887c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -1,4 +1,4 @@ -//===-- DWARFTypeUnit.h -----------------------------------------*- C++ -*-===// +//===- DWARFTypeUnit.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,27 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H -#define LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H +#define LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H +#include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/Support/DataExtractor.h" +#include <cstdint> namespace llvm { +class DWARFContext; +class DWARFDebugAbbrev; +struct DWARFSection; +class raw_ostream; + class DWARFTypeUnit : public DWARFUnit { private: uint64_t TypeHash; uint32_t TypeOffset; + public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, @@ -26,9 +36,11 @@ public: const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} + uint32_t getHeaderSize() const override { return DWARFUnit::getHeaderSize() + 12; } + void dump(raw_ostream &OS, bool Brief = false); static const DWARFSectionKind Section = DW_SECT_TYPES; @@ -36,7 +48,6 @@ protected: bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override; }; -} - -#endif +} // end namespace llvm +#endif // LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index db7b59be90c2a..40eb4434bd61e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -1,4 +1,4 @@ -//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===// +//===- DWARFUnit.h ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,32 +7,37 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H -#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H +#define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H -#include "llvm/ADT/Optional.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" +#include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Dwarf.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <memory> #include <vector> namespace llvm { -namespace object { -class ObjectFile; -} - +class DWARFAbbreviationDeclarationSet; class DWARFContext; class DWARFDebugAbbrev; class DWARFUnit; -class StringRef; -class raw_ostream; /// Base class for all DWARFUnitSection classes. This provides the /// functionality common to all unit types. @@ -47,12 +52,12 @@ public: DWARFUnitIndex *Index = nullptr); protected: + ~DWARFUnitSectionBase() = default; + virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, bool isLittleEndian, bool isDWO) = 0; - - ~DWARFUnitSectionBase() = default; }; const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, @@ -65,7 +70,7 @@ class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, bool Parsed = false; public: - typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector; + typedef SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector; typedef typename UnitVector::iterator iterator; typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range; @@ -122,8 +127,9 @@ class DWARFUnit { uint32_t Offset; uint32_t Length; - uint16_t Version; const DWARFAbbreviationDeclarationSet *Abbrevs; + uint16_t Version; + uint8_t UnitType; uint8_t AddrSize; uint64_t BaseAddr; // The compile unit debug information entry items. @@ -134,9 +140,11 @@ class DWARFUnit { class DWOHolder { object::OwningBinary<object::ObjectFile> DWOFile; std::unique_ptr<DWARFContext> DWOContext; - DWARFUnit *DWOU; + DWARFUnit *DWOU = nullptr; + public: DWOHolder(StringRef DWOPath); + DWARFUnit *getUnit() const { return DWOU; } }; std::unique_ptr<DWOHolder> DWO; @@ -151,8 +159,9 @@ class DWARFUnit { 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; } + virtual uint32_t getHeaderSize() const { return Version <= 4 ? 11 : 12; } public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, @@ -168,10 +177,12 @@ public: StringRef getLineSection() const { return LineSection; } 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; @@ -184,6 +195,7 @@ public: DataExtractor getDebugInfoExtractor() const { return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize); } + DataExtractor getStringExtractor() const { return DataExtractor(StringSection, false, 0); } @@ -202,23 +214,30 @@ public: uint32_t getNextUnitOffset() const { return Offset + Length + 4; } uint32_t getLength() const { return Length; } uint16_t getVersion() const { return Version; } + dwarf::DwarfFormat getFormat() const { return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64. } + const DWARFAbbreviationDeclarationSet *getAbbreviations() const { return Abbrevs; } + + uint8_t getUnitType() const { return UnitType; } uint8_t getAddressByteSize() const { return AddrSize; } + uint8_t getRefAddrByteSize() const { if (Version == 2) return AddrSize; return getDwarfOffsetByteSize(); } + uint8_t getDwarfOffsetByteSize() const { if (getFormat() == dwarf::DwarfFormat::DWARF64) return 8; return 4; } + uint64_t getBaseAddress() const { return BaseAddr; } void setBaseAddress(uint64_t base_addr) { @@ -308,9 +327,11 @@ private: /// 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<DWARFDebugInfoEntry> &DIEs) const; + /// clearDIEs - Clear parsed DIEs to keep memory usage low. void clearDIEs(bool KeepCUDie); @@ -324,6 +345,6 @@ private: DWARFDie getSubprogramForAddress(uint64_t Address); }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h index 9f051cd7081c6..8e2ce023695bf 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h @@ -1,4 +1,4 @@ -//===-- DWARFUnitIndex.h --------------------------------------------------===// +//===- DWARFUnitIndex.h -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H -#define LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H +#define LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/raw_ostream.h" #include <cstdint> +#include <memory> namespace llvm { +class raw_ostream; + enum DWARFSectionKind { DW_SECT_INFO = 1, DW_SECT_TYPES, @@ -57,9 +59,11 @@ public: public: const SectionContribution *getOffset(DWARFSectionKind Sec) const; const SectionContribution *getOffset() const; + const SectionContribution *getOffsets() const { return Contributions.get(); } + uint64_t getSignature() const { return Signature; } }; @@ -72,21 +76,26 @@ private: std::unique_ptr<Entry[]> Rows; static StringRef getColumnHeader(DWARFSectionKind DS); + bool parseImpl(DataExtractor IndexData); public: - bool parse(DataExtractor IndexData); DWARFUnitIndex(DWARFSectionKind InfoColumnKind) : InfoColumnKind(InfoColumnKind) {} + + bool parse(DataExtractor IndexData); void dump(raw_ostream &OS) const; const Entry *getFromOffset(uint32_t Offset) const; + ArrayRef<DWARFSectionKind> getColumnKinds() const { return makeArrayRef(ColumnKinds.get(), Header.NumColumns); } + ArrayRef<Entry> getRows() const { return makeArrayRef(Rows.get(), Header.NumBuckets); } }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H |