172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===//
272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//                     The LLVM Compiler Infrastructure
472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source
672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details.
772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#ifndef LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H
1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFAbbreviationDeclaration.h"
14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "DWARFDebugRangeList.h"
155eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov#include "llvm/ADT/SmallVector.h"
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/DebugInfo/DIContext.h"
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/DataTypes.h"
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramernamespace llvm {
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2110df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramerclass DWARFDebugAranges;
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFCompileUnit;
23cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass DWARFUnit;
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFContext;
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFFormValue;
26e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonovstruct DWARFDebugInfoEntryInlinedChain;
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer/// DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFDebugInfoEntryMinimal {
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// Offset within the .debug_info of the start of this entry.
3180cc2598f89d09a6df2b84a5f8cea813b280b17bBenjamin Kramer  uint32_t Offset;
3272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// How many to add to "this" to get the sibling.
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t SiblingIdx;
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFAbbreviationDeclaration *AbbrevDecl;
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerpublic:
3815ec085c40cf45726a5c8925706795b52fd231bdBenjamin Kramer  DWARFDebugInfoEntryMinimal()
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : Offset(0), SiblingIdx(0), AbbrevDecl(nullptr) {}
4015ec085c40cf45726a5c8925706795b52fd231bdBenjamin Kramer
41cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth,
42cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie            unsigned indent = 0) const;
43cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void dumpAttribute(raw_ostream &OS, const DWARFUnit *u, uint32_t *offset_ptr,
44cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                     uint16_t attr, uint16_t form, unsigned indent = 0) const;
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
466faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov  /// Extracts a debug info entry, which is a child of a given unit,
47d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  /// starting at a given offset. If DIE can't be extracted, returns false and
48d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  /// doesn't change OffsetPtr.
496faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov  bool extractFast(const DWARFUnit *U, uint32_t *OffsetPtr);
5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : 0; }
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isNULL() const { return AbbrevDecl == nullptr; }
535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
545eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns true if DIE represents a subprogram (not inlined).
555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  bool isSubprogramDIE() const;
565eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns true if DIE represents a subprogram or an inlined
575eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// subroutine.
585eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  bool isSubroutineDIE() const;
595eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
6080cc2598f89d09a6df2b84a5f8cea813b280b17bBenjamin Kramer  uint32_t getOffset() const { return Offset; }
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  bool hasChildren() const { return !isNULL() && AbbrevDecl->hasChildren(); }
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We know we are kept in a vector of contiguous entries, so we know
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // our sibling will be some index after "this".
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFDebugInfoEntryMinimal *getSibling() const {
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return SiblingIdx > 0 ? this + SiblingIdx : nullptr;
6772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We know we are kept in a vector of contiguous entries, so we know
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // we don't need to store our child pointer, if we have a child it will
7172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // be the next entry in the list...
7272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFDebugInfoEntryMinimal *getFirstChild() const {
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return hasChildren() ? this + 1 : nullptr;
7472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void setSibling(const DWARFDebugInfoEntryMinimal *Sibling) {
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Sibling) {
7872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // We know we are kept in a vector of contiguous entries, so we know
7972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // our sibling will be some index after "this".
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      SiblingIdx = Sibling - this;
814aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    } else
8272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      SiblingIdx = 0;
8372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const {
8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return AbbrevDecl;
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
892e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  bool getAttributeValue(const DWARFUnit *U, const uint16_t Attr,
902e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov                         DWARFFormValue &FormValue) const;
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
922e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  const char *getAttributeValueAsString(const DWARFUnit *U, const uint16_t Attr,
932e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov                                        const char *FailValue) const;
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
95cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint64_t getAttributeValueAsAddress(const DWARFUnit *U, const uint16_t Attr,
9663fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov                                      uint64_t FailValue) const;
9763fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov
98c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  uint64_t getAttributeValueAsUnsignedConstant(const DWARFUnit *U,
99c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov                                               const uint16_t Attr,
100c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov                                               uint64_t FailValue) const;
10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1022e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov  uint64_t getAttributeValueAsReference(const DWARFUnit *U, const uint16_t Attr,
1032e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov                                        uint64_t FailValue) const;
10410df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
105c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov  uint64_t getAttributeValueAsSectionOffset(const DWARFUnit *U,
106c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov                                            const uint16_t Attr,
107c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov                                            uint64_t FailValue) const;
108c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov
109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  uint64_t getRangesBaseAttribute(const DWARFUnit *U, uint64_t FailValue) const;
110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1115eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
1125eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns true if both attributes are present.
113cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC,
114cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                       uint64_t &HighPC) const;
1155eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const;
117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void collectChildrenAddressRanges(const DWARFUnit *U,
119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    DWARFAddressRangesVector &Ranges) const;
1205eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
121cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool addressRangeContainsAddress(const DWARFUnit *U,
1225eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                   const uint64_t Address) const;
1235eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1245eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// If a DIE represents a subprogram (or inlined subroutine),
1255eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// returns its mangled name (or short name, if mangled is missing).
1265eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// This name may be fetched from specification or abstract origin
1275eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// for this subprogram. Returns null if no name is found.
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const char *
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getSubroutineName(const DWARFUnit *U,
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    DILineInfoSpecifier::FunctionNameKind Kind) const;
1315eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1325eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Retrieves values of DW_AT_call_file, DW_AT_call_line and
1335eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// DW_AT_call_column from DIE (or zeroes if they are missing).
134cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void getCallerFrame(const DWARFUnit *U, uint32_t &CallFile,
1355eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                      uint32_t &CallLine, uint32_t &CallColumn) const;
1365eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1375eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Get inlined chain for a given address, rooted at the current DIE.
1385eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns empty chain if address is not contained in address range
1395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// of current DIE.
140e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  DWARFDebugInfoEntryInlinedChain
141cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  getInlinedChainForAddress(const DWARFUnit *U, const uint64_t Address) const;
142e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov};
143e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov
144e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine
145e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// DIEs, (possibly ending with subprogram DIE), all of which are contained
146e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// in some concrete inlined instance tree. Address range for each DIE
147e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// (except the last DIE) in this chain is contained in address
148e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// range for next DIE in the chain.
149e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonovstruct DWARFDebugInfoEntryInlinedChain {
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DWARFDebugInfoEntryInlinedChain() : U(nullptr) {}
151e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  SmallVector<DWARFDebugInfoEntryMinimal, 4> DIEs;
152cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFUnit *U;
15372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer};
15472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
15672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
15772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#endif
158