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"
145eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov#include "llvm/ADT/SmallVector.h"
1572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/DataTypes.h"
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramernamespace llvm {
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1910df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramerclass DWARFDebugAranges;
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFCompileUnit;
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFContext;
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFFormValue;
23e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonovstruct DWARFDebugInfoEntryInlinedChain;
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer/// DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerclass DWARFDebugInfoEntryMinimal {
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// Offset within the .debug_info of the start of this entry.
2880cc2598f89d09a6df2b84a5f8cea813b280b17bBenjamin Kramer  uint32_t Offset;
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// How many to subtract from "this" to get the parent.
3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// If zero this die has no parent.
3272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t ParentIdx;
3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// How many to add to "this" to get the sibling.
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t SiblingIdx;
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFAbbreviationDeclaration *AbbrevDecl;
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerpublic:
3915ec085c40cf45726a5c8925706795b52fd231bdBenjamin Kramer  DWARFDebugInfoEntryMinimal()
4015ec085c40cf45726a5c8925706795b52fd231bdBenjamin Kramer    : Offset(0), ParentIdx(0), SiblingIdx(0), AbbrevDecl(0) {}
4115ec085c40cf45726a5c8925706795b52fd231bdBenjamin Kramer
4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  void dump(raw_ostream &OS, const DWARFCompileUnit *cu,
4372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer            unsigned recurseDepth, unsigned indent = 0) const;
4472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  void dumpAttribute(raw_ostream &OS, const DWARFCompileUnit *cu,
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                     uint32_t *offset_ptr, uint16_t attr, uint16_t form,
4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                     unsigned indent = 0) const;
4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
48d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  /// Extracts a debug info entry, which is a child of a given compile unit,
49d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  /// starting at a given offset. If DIE can't be extracted, returns false and
50d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  /// doesn't change OffsetPtr.
51d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  bool extractFast(const DWARFCompileUnit *CU, const uint8_t *FixedFormSizes,
52d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov                   uint32_t *OffsetPtr);
5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// Extract a debug info entry for a given compile unit from the
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  /// .debug_info and .debug_abbrev data starting at the given offset.
56d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  /// If compile unit can't be parsed, returns false and doesn't change
57d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  /// OffsetPtr.
58d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov  bool extract(const DWARFCompileUnit *CU, uint32_t *OffsetPtr);
5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : 0; }
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  bool isNULL() const { return AbbrevDecl == 0; }
625eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
635eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns true if DIE represents a subprogram (not inlined).
645eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  bool isSubprogramDIE() const;
655eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns true if DIE represents a subprogram or an inlined
665eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// subroutine.
675eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  bool isSubroutineDIE() const;
685eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
6980cc2598f89d09a6df2b84a5f8cea813b280b17bBenjamin Kramer  uint32_t getOffset() const { return Offset; }
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t getNumAttributes() const {
7172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return !isNULL() ? AbbrevDecl->getNumAttributes() : 0;
7272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
7372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  bool hasChildren() const { return !isNULL() && AbbrevDecl->hasChildren(); }
7472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We know we are kept in a vector of contiguous entries, so we know
7672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // our parent will be some index behind "this".
7772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *getParent() {
7872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return ParentIdx > 0 ? this - ParentIdx : 0;
7972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFDebugInfoEntryMinimal *getParent() const {
8172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return ParentIdx > 0 ? this - ParentIdx : 0;
8272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We know we are kept in a vector of contiguous entries, so we know
8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // our sibling will be some index after "this".
8572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *getSibling() {
8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return SiblingIdx > 0 ? this + SiblingIdx : 0;
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFDebugInfoEntryMinimal *getSibling() const {
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return SiblingIdx > 0 ? this + SiblingIdx : 0;
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // We know we are kept in a vector of contiguous entries, so we know
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // we don't need to store our child pointer, if we have a child it will
9372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  // be the next entry in the list...
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFDebugInfoEntryMinimal *getFirstChild() {
9572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return hasChildren() ? this + 1 : 0;
9672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
9772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFDebugInfoEntryMinimal *getFirstChild() const {
9872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return hasChildren() ? this + 1 : 0;
9972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
10072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  void setParent(DWARFDebugInfoEntryMinimal *parent) {
10272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (parent) {
10372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // We know we are kept in a vector of contiguous entries, so we know
10472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // our parent will be some index behind "this".
10572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      ParentIdx = this - parent;
1064aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    } else
10772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      ParentIdx = 0;
10872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
10972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  void setSibling(DWARFDebugInfoEntryMinimal *sibling) {
1104aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    if (sibling) {
11172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // We know we are kept in a vector of contiguous entries, so we know
11272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      // our sibling will be some index after "this".
11372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      SiblingIdx = sibling - this;
11472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      sibling->setParent(getParent());
1154aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    } else
11672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      SiblingIdx = 0;
11772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
11872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
11972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const {
12072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return AbbrevDecl;
12172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
12272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
12372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t getAttributeValue(const DWARFCompileUnit *cu,
12472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                             const uint16_t attr, DWARFFormValue &formValue,
12572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                             uint32_t *end_attr_offset_ptr = 0) const;
12672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
12772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const char* getAttributeValueAsString(const DWARFCompileUnit* cu,
12872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                        const uint16_t attr,
12972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                        const char *fail_value) const;
13072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint64_t getAttributeValueAsUnsigned(const DWARFCompileUnit *cu,
13272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                       const uint16_t attr,
13372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                       uint64_t fail_value) const;
13472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint64_t getAttributeValueAsReference(const DWARFCompileUnit *cu,
13672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                        const uint16_t attr,
13772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                        uint64_t fail_value) const;
13872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
13972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  int64_t getAttributeValueAsSigned(const DWARFCompileUnit* cu,
14072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                    const uint16_t attr,
14172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                    int64_t fail_value) const;
14210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer
1435eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
1445eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns true if both attributes are present.
1455eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  bool getLowAndHighPC(const DWARFCompileUnit *CU,
1465eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                       uint64_t &LowPC, uint64_t &HighPC) const;
1475eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1485eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  void buildAddressRangeTable(const DWARFCompileUnit *CU,
1495eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                              DWARFDebugAranges *DebugAranges) const;
1505eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1515eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  bool addressRangeContainsAddress(const DWARFCompileUnit *CU,
1525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                   const uint64_t Address) const;
1535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1545eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// If a DIE represents a subprogram (or inlined subroutine),
1555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// returns its mangled name (or short name, if mangled is missing).
1565eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// This name may be fetched from specification or abstract origin
1575eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// for this subprogram. Returns null if no name is found.
1585eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  const char* getSubroutineName(const DWARFCompileUnit *CU) const;
1595eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1605eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Retrieves values of DW_AT_call_file, DW_AT_call_line and
1615eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// DW_AT_call_column from DIE (or zeroes if they are missing).
1625eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  void getCallerFrame(const DWARFCompileUnit *CU, uint32_t &CallFile,
1635eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                      uint32_t &CallLine, uint32_t &CallColumn) const;
1645eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
1655eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Get inlined chain for a given address, rooted at the current DIE.
1665eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// Returns empty chain if address is not contained in address range
1675eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  /// of current DIE.
168e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  DWARFDebugInfoEntryInlinedChain
169e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  getInlinedChainForAddress(const DWARFCompileUnit *CU,
170e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov                            const uint64_t Address) const;
171e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov};
172e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov
173e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine
174e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// DIEs, (possibly ending with subprogram DIE), all of which are contained
175e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// in some concrete inlined instance tree. Address range for each DIE
176e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// (except the last DIE) in this chain is contained in address
177e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov/// range for next DIE in the chain.
178e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonovstruct DWARFDebugInfoEntryInlinedChain {
179e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  DWARFDebugInfoEntryInlinedChain() : CU(0) {}
180e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  SmallVector<DWARFDebugInfoEntryMinimal, 4> DIEs;
181e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  const DWARFCompileUnit *CU;
18272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer};
18372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
18572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
18672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#endif
187