aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/DebugInfo')
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeViewSymbols.def2
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h13
-rw-r--r--include/llvm/DebugInfo/DIContext.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFContext.h4
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h98
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDie.h129
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