Skip to content

Commit c8c1032

Browse files
author
Greg Clayton
committed
Make a DWARFDIE class that can help avoid using the wrong DWARFUnit when extracting attributes
Many places pass around a DWARFDebugInfoEntryMinimal and a DWARFUnit. It is easy to get things wrong by using the wrong DWARFUnit with a DWARFDebugInfoEntryMinimal. This patch creates a DWARFDie class that contains the DWARFUnit and DWARFDebugInfoEntryMinimal objects so that they can't get out of sync. All attribute extraction has been moved out of DWARFDebugInfoEntryMinimal and into DWARFDie. DWARFDebugInfoEntryMinimal was also renamed to DWARFDebugInfoEntry. DWARFDie objects are temporary objects that are used by clients and contain 2 pointers that you always need to have anyway. Keeping them grouped will avoid errors and simplify many of the attribute extracting APIs by not having to pass in a DWARFUnit. Differential Revision: https://reviews.llvm.org/D27634 llvm-svn: 289565
1 parent c21b3c9 commit c8c1032

File tree

13 files changed

+1041
-848
lines changed

13 files changed

+1041
-848
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h

Lines changed: 7 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class DWARFContext;
2626
class DWARFFormValue;
2727
struct DWARFDebugInfoEntryInlinedChain;
2828

29-
/// DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
30-
class DWARFDebugInfoEntryMinimal {
29+
/// DWARFDebugInfoEntry - A DIE with only the minimum required data.
30+
class DWARFDebugInfoEntry {
3131
/// Offset within the .debug_info of the start of this entry.
3232
uint32_t Offset;
3333

@@ -36,15 +36,9 @@ class DWARFDebugInfoEntryMinimal {
3636

3737
const DWARFAbbreviationDeclaration *AbbrevDecl;
3838
public:
39-
DWARFDebugInfoEntryMinimal()
39+
DWARFDebugInfoEntry()
4040
: Offset(0), SiblingIdx(0), AbbrevDecl(nullptr) {}
4141

42-
void dump(raw_ostream &OS, DWARFUnit *u, unsigned recurseDepth,
43-
unsigned indent = 0) const;
44-
void dumpAttribute(raw_ostream &OS, DWARFUnit *u, uint32_t *offset_ptr,
45-
dwarf::Attribute attr, dwarf::Form form,
46-
unsigned indent = 0) const;
47-
4842
/// Extracts a debug info entry, which is a child of a given unit,
4943
/// starting at a given offset. If DIE can't be extracted, returns false and
5044
/// doesn't change OffsetPtr.
@@ -53,35 +47,23 @@ class DWARFDebugInfoEntryMinimal {
5347
bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr,
5448
const DataExtractor &DebugInfoData, uint32_t UEndOffset);
5549

56-
dwarf::Tag getTag() const {
57-
return AbbrevDecl ? AbbrevDecl->getTag() : dwarf::DW_TAG_null;
58-
}
59-
60-
bool isNULL() const { return AbbrevDecl == nullptr; }
61-
62-
/// Returns true if DIE represents a subprogram (not inlined).
63-
bool isSubprogramDIE() const;
64-
/// Returns true if DIE represents a subprogram or an inlined
65-
/// subroutine.
66-
bool isSubroutineDIE() const;
67-
6850
uint32_t getOffset() const { return Offset; }
69-
bool hasChildren() const { return !isNULL() && AbbrevDecl->hasChildren(); }
51+
bool hasChildren() const { return AbbrevDecl && AbbrevDecl->hasChildren(); }
7052

7153
// We know we are kept in a vector of contiguous entries, so we know
7254
// our sibling will be some index after "this".
73-
const DWARFDebugInfoEntryMinimal *getSibling() const {
55+
const DWARFDebugInfoEntry *getSibling() const {
7456
return SiblingIdx > 0 ? this + SiblingIdx : nullptr;
7557
}
7658

7759
// We know we are kept in a vector of contiguous entries, so we know
7860
// we don't need to store our child pointer, if we have a child it will
7961
// be the next entry in the list...
80-
const DWARFDebugInfoEntryMinimal *getFirstChild() const {
62+
const DWARFDebugInfoEntry *getFirstChild() const {
8163
return hasChildren() ? this + 1 : nullptr;
8264
}
8365

84-
void setSibling(const DWARFDebugInfoEntryMinimal *Sibling) {
66+
void setSibling(const DWARFDebugInfoEntry *Sibling) {
8567
if (Sibling) {
8668
// We know we are kept in a vector of contiguous entries, so we know
8769
// our sibling will be some index after "this".
@@ -93,81 +75,6 @@ class DWARFDebugInfoEntryMinimal {
9375
const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const {
9476
return AbbrevDecl;
9577
}
96-
97-
bool getAttributeValue(const DWARFUnit *U, dwarf::Attribute Attr,
98-
DWARFFormValue &FormValue) const;
99-
100-
const char *getAttributeValueAsString(const DWARFUnit *U,
101-
dwarf::Attribute Attr,
102-
const char *FailValue) const;
103-
104-
uint64_t getAttributeValueAsAddress(const DWARFUnit *U,
105-
dwarf::Attribute Attr,
106-
uint64_t FailValue) const;
107-
108-
int64_t getAttributeValueAsSignedConstant(const DWARFUnit *U,
109-
dwarf::Attribute Attr,
110-
int64_t FailValue) const;
111-
112-
uint64_t getAttributeValueAsUnsignedConstant(const DWARFUnit *U,
113-
dwarf::Attribute Attr,
114-
uint64_t FailValue) const;
115-
116-
uint64_t getAttributeValueAsReference(const DWARFUnit *U,
117-
dwarf::Attribute Attr,
118-
uint64_t FailValue) const;
119-
120-
uint64_t getAttributeValueAsSectionOffset(const DWARFUnit *U,
121-
dwarf::Attribute Attr,
122-
uint64_t FailValue) const;
123-
124-
uint64_t getRangesBaseAttribute(const DWARFUnit *U, uint64_t FailValue) const;
125-
126-
/// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
127-
/// Returns true if both attributes are present.
128-
bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC,
129-
uint64_t &HighPC) const;
130-
131-
DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const;
132-
133-
void collectChildrenAddressRanges(const DWARFUnit *U,
134-
DWARFAddressRangesVector &Ranges) const;
135-
136-
bool addressRangeContainsAddress(const DWARFUnit *U,
137-
const uint64_t Address) const;
138-
139-
/// If a DIE represents a subprogram (or inlined subroutine),
140-
/// returns its mangled name (or short name, if mangled is missing).
141-
/// This name may be fetched from specification or abstract origin
142-
/// for this subprogram. Returns null if no name is found.
143-
const char *getSubroutineName(const DWARFUnit *U, DINameKind Kind) const;
144-
145-
/// Return the DIE name resolving DW_AT_sepcification or
146-
/// DW_AT_abstract_origin references if necessary.
147-
/// Returns null if no name is found.
148-
const char *getName(const DWARFUnit *U, DINameKind Kind) const;
149-
150-
/// Retrieves values of DW_AT_call_file, DW_AT_call_line and
151-
/// DW_AT_call_column from DIE (or zeroes if they are missing).
152-
void getCallerFrame(const DWARFUnit *U, uint32_t &CallFile,
153-
uint32_t &CallLine, uint32_t &CallColumn) const;
154-
155-
/// Get inlined chain for a given address, rooted at the current DIE.
156-
/// Returns empty chain if address is not contained in address range
157-
/// of current DIE.
158-
DWARFDebugInfoEntryInlinedChain
159-
getInlinedChainForAddress(const DWARFUnit *U, const uint64_t Address) const;
160-
};
161-
162-
/// DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine
163-
/// DIEs, (possibly ending with subprogram DIE), all of which are contained
164-
/// in some concrete inlined instance tree. Address range for each DIE
165-
/// (except the last DIE) in this chain is contained in address
166-
/// range for next DIE in the chain.
167-
struct DWARFDebugInfoEntryInlinedChain {
168-
DWARFDebugInfoEntryInlinedChain() : U(nullptr) {}
169-
SmallVector<DWARFDebugInfoEntryMinimal, 4> DIEs;
170-
const DWARFUnit *U;
17178
};
17279

17380
}

0 commit comments

Comments
 (0)