diff options
Diffstat (limited to 'include/llvm/DebugInfo/DWARF')
| -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 | 
4 files changed, 219 insertions, 14 deletions
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  | 
