diff options
Diffstat (limited to 'include/llvm/DebugInfo')
-rw-r--r-- | include/llvm/DebugInfo/CodeView/CodeViewSymbols.def | 2 | ||||
-rw-r--r-- | include/llvm/DebugInfo/CodeView/SymbolRecord.h | 13 | ||||
-rw-r--r-- | include/llvm/DebugInfo/DIContext.h | 2 | ||||
-rw-r--r-- | include/llvm/DebugInfo/DWARF/DWARFContext.h | 4 | ||||
-rw-r--r-- | include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h | 2 | ||||
-rw-r--r-- | include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h | 98 | ||||
-rw-r--r-- | include/llvm/DebugInfo/DWARF/DWARFDie.h | 129 |
7 files changed, 235 insertions, 15 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def b/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def index 41c538076798..b5f1cc0198dc 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def +++ b/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def @@ -143,7 +143,6 @@ CV_SYMBOL(S_MANSLOT , 0x1120) CV_SYMBOL(S_MANMANYREG , 0x1121) CV_SYMBOL(S_MANREGREL , 0x1122) CV_SYMBOL(S_MANMANYREG2 , 0x1123) -CV_SYMBOL(S_UNAMESPACE , 0x1124) CV_SYMBOL(S_DATAREF , 0x1126) CV_SYMBOL(S_ANNOTATIONREF , 0x1128) CV_SYMBOL(S_TOKENREF , 0x1129) @@ -255,6 +254,7 @@ SYMBOL_RECORD_ALIAS(S_GMANDATA , 0x111d, ManagedGlobalData, DataSym) SYMBOL_RECORD(S_LTHREAD32 , 0x1112, ThreadLocalDataSym) SYMBOL_RECORD_ALIAS(S_GTHREAD32 , 0x1113, GlobalTLS, ThreadLocalDataSym) +SYMBOL_RECORD(S_UNAMESPACE , 0x1124, UsingNamespaceSym) #undef CV_SYMBOL #undef SYMBOL_RECORD diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index cf267f23967b..93306824012e 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -942,6 +942,19 @@ public: uint32_t RecordOffset; }; +// S_UNAMESPACE +class UsingNamespaceSym : public SymbolRecord { +public: + explicit UsingNamespaceSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {} + explicit UsingNamespaceSym(uint32_t RecordOffset) + : SymbolRecord(SymbolRecordKind::RegRelativeSym), + RecordOffset(RecordOffset) {} + + StringRef Name; + + uint32_t RecordOffset; +}; + // S_ANNOTATION using CVSymbol = CVRecord<SymbolKind>; diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index f89eb34fdd77..bbdd5e0d9c3f 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -154,6 +154,8 @@ enum DIDumpType : unsigned { struct DIDumpOptions { unsigned DumpType = DIDT_All; unsigned RecurseDepth = -1U; + uint16_t Version = 0; // DWARF version to assume when extracting. + uint8_t AddrSize = 4; // Address byte size to assume when extracting. bool ShowAddresses = true; bool ShowChildren = false; bool ShowParents = false; diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index fe7430c9f04c..f5419fe02421 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -323,6 +323,10 @@ public: /// have initialized the relevant target descriptions. Error loadRegisterInfo(const object::ObjectFile &Obj); + /// Get address size from CUs. + /// TODO: refactor compile_units() to make this const. + uint8_t getCUAddrSize(); + private: /// Return the compile unit which contains instruction with provided /// address. diff --git a/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h index 10e146b70ec7..1ed087520b30 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h @@ -51,6 +51,8 @@ public: /// reflect the absolute address of this pointer. Optional<uint64_t> getEncodedPointer(uint32_t *Offset, uint8_t Encoding, uint64_t AbsPosOffset = 0) const; + + size_t size() const { return Section == nullptr ? 0 : Section->Data.size(); } }; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h new file mode 100644 index 000000000000..ffbd1b06d1e2 --- /dev/null +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h @@ -0,0 +1,98 @@ +//===- DWARFDebugAddr.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_DWARFDEBUGADDR_H +#define LLVM_DEBUGINFO_DWARFDEBUGADDR_H + +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <map> +#include <vector> + +namespace llvm { + +class Error; +class raw_ostream; + +/// A class representing an address table as specified in DWARF v5. +/// The table consists of a header followed by an array of address values from +/// .debug_addr section. +class DWARFDebugAddrTable { +public: + struct Header { + /// The total length of the entries for this table, not including the length + /// field itself. + uint32_t Length = 0; + /// The DWARF version number. + uint16_t Version = 5; + /// 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 selector on the target architecture. + /// If the target system uses a flat address space, this value is 0. + uint8_t SegSize = 0; + }; + +private: + dwarf::DwarfFormat Format; + uint32_t HeaderOffset; + Header HeaderData; + uint32_t DataSize = 0; + std::vector<uint64_t> Addrs; + +public: + void clear(); + + /// Extract an entire table, including all addresses. + Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr, + uint16_t Version, uint8_t AddrSize, + std::function<void(Error)> WarnCallback); + + uint32_t getHeaderOffset() const { return HeaderOffset; } + uint8_t getAddrSize() const { return HeaderData.AddrSize; } + void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const; + + /// Return the address based on a given index. + Expected<uint64_t> getAddrEntry(uint32_t Index) const; + + /// Return the size of the table header including the length + /// but not including the addresses. + uint8_t getHeaderSize() const { + switch (Format) { + case dwarf::DwarfFormat::DWARF32: + return 8; // 4 + 2 + 1 + 1 + case dwarf::DwarfFormat::DWARF64: + return 16; // 12 + 2 + 1 + 1 + } + llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64)"); + } + + /// Returns the length of this table, including the length field, or 0 if the + /// length has not been determined (e.g. because the table has not yet been + /// parsed, or there was a problem in parsing). + uint32_t getLength() const; + + /// Verify that the given length is valid for this table. + bool hasValidLength() const { return getLength() != 0; } + + /// Invalidate Length field to stop further processing. + void invalidateLength() { HeaderData.Length = 0; } + + /// Returns the length of the array of addresses. + uint32_t getDataSize() const; +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARFDEBUGADDR_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h index 6e6b57cbcbd4..c77034f6348f 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -46,7 +46,7 @@ class DWARFDie { public: DWARFDie() = default; - DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {} + DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry *D) : U(Unit), Die(D) {} bool isValid() const { return U && Die; } explicit operator bool() const { return isValid(); } @@ -82,9 +82,7 @@ public: } /// Returns true for a valid DIE that terminates a sibling chain. - bool isNULL() const { - return getAbbreviationDeclarationPtr() == nullptr; - } + bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; } /// Returns true if DIE represents a subprogram (not inlined). bool isSubprogramDIE() const; @@ -129,7 +127,6 @@ public: void dump(raw_ostream &OS, unsigned indent = 0, DIDumpOptions DumpOpts = DIDumpOptions()) const; - /// Convenience zero-argument overload for debugging. LLVM_DUMP_METHOD void dump() const; @@ -275,12 +272,16 @@ public: iterator begin() const; iterator end() const; + + std::reverse_iterator<iterator> rbegin() const; + std::reverse_iterator<iterator> rend() const; + iterator_range<iterator> children() const; }; -class DWARFDie::attribute_iterator : - public iterator_facade_base<attribute_iterator, std::forward_iterator_tag, - const DWARFAttribute> { +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->(). @@ -288,6 +289,9 @@ class DWARFDie::attribute_iterator : /// The attribute index within the abbreviation declaration in Die. uint32_t Index; + friend bool operator==(const attribute_iterator &LHS, + const attribute_iterator &RHS); + /// 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 @@ -303,12 +307,21 @@ public: 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::attribute_iterator &LHS, + const DWARFDie::attribute_iterator &RHS) { + return LHS.Index == RHS.Index; +} + +inline bool operator!=(const DWARFDie::attribute_iterator &LHS, + const DWARFDie::attribute_iterator &RHS) { + return !(LHS == RHS); +} + inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) { return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() && - LHS.getDwarfUnit() == RHS.getDwarfUnit(); + LHS.getDwarfUnit() == RHS.getDwarfUnit(); } inline bool operator!=(const DWARFDie &LHS, const DWARFDie &RHS) { @@ -323,11 +336,15 @@ class DWARFDie::iterator : public iterator_facade_base<iterator, std::bidirectional_iterator_tag, const DWARFDie> { DWARFDie Die; + + friend std::reverse_iterator<llvm::DWARFDie::iterator>; + friend bool operator==(const DWARFDie::iterator &LHS, + const DWARFDie::iterator &RHS); + public: iterator() = default; - explicit iterator(DWARFDie D) : Die(D) { - } + explicit iterator(DWARFDie D) : Die(D) {} iterator &operator++() { Die = Die.getSibling(); @@ -339,11 +356,19 @@ public: 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; } }; +inline bool operator==(const DWARFDie::iterator &LHS, + const DWARFDie::iterator &RHS) { + return LHS.Die == RHS.Die; +} + +inline bool operator!=(const DWARFDie::iterator &LHS, + const DWARFDie::iterator &RHS) { + return !(LHS == RHS); +} + // These inline functions must follow the DWARFDie::iterator definition above // as they use functions from that class. inline DWARFDie::iterator DWARFDie::begin() const { @@ -360,4 +385,80 @@ inline iterator_range<DWARFDie::iterator> DWARFDie::children() const { } // end namespace llvm +namespace std { + +template <> +class reverse_iterator<llvm::DWARFDie::iterator> + : public llvm::iterator_facade_base< + reverse_iterator<llvm::DWARFDie::iterator>, + bidirectional_iterator_tag, const llvm::DWARFDie> { + +private: + llvm::DWARFDie Die; + bool AtEnd; + +public: + reverse_iterator(llvm::DWARFDie::iterator It) + : Die(It.Die), AtEnd(!It.Die.getPreviousSibling()) { + if (!AtEnd) + Die = Die.getPreviousSibling(); + } + + reverse_iterator<llvm::DWARFDie::iterator> &operator++() { + assert(!AtEnd && "Incrementing rend"); + llvm::DWARFDie D = Die.getPreviousSibling(); + if (D) + Die = D; + else + AtEnd = true; + return *this; + } + + reverse_iterator<llvm::DWARFDie::iterator> &operator--() { + if (AtEnd) { + AtEnd = false; + return *this; + } + Die = Die.getSibling(); + assert(!Die.isNULL() && "Decrementing rbegin"); + return *this; + } + + const llvm::DWARFDie &operator*() const { + assert(Die.isValid()); + return Die; + } + + // FIXME: We should be able to specify the equals operator as a friend, but + // that causes the compiler to think the operator overload is ambiguous + // with the friend declaration and the actual definition as candidates. + bool equals(const reverse_iterator<llvm::DWARFDie::iterator> &RHS) const { + return Die == RHS.Die && AtEnd == RHS.AtEnd; + } +}; + +} // namespace std + +namespace llvm { + +inline bool operator==(const std::reverse_iterator<DWARFDie::iterator> &LHS, + const std::reverse_iterator<DWARFDie::iterator> &RHS) { + return LHS.equals(RHS); +} + +inline bool operator!=(const std::reverse_iterator<DWARFDie::iterator> &LHS, + const std::reverse_iterator<DWARFDie::iterator> &RHS) { + return !(LHS == RHS); +} + +inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rbegin() const { + return llvm::make_reverse_iterator(end()); +} + +inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rend() const { + return llvm::make_reverse_iterator(begin()); +} + +} // end namespace llvm + #endif // LLVM_DEBUGINFO_DWARFDIE_H |