1cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
2cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//
3cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//                     The LLVM Compiler Infrastructure
4cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//
5cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// This file is distributed under the University of Illinois Open Source
6cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// License. See LICENSE.TXT for details.
7cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//
8cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//===----------------------------------------------------------------------===//
9cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
10cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#ifndef LLVM_DEBUGINFO_DWARFUNIT_H
11cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#define LLVM_DEBUGINFO_DWARFUNIT_H
12cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
13cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "DWARFDebugAbbrev.h"
14cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "DWARFDebugInfoEntry.h"
15cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "DWARFDebugRangeList.h"
16cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "DWARFRelocMap.h"
17cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include <vector>
18cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
19cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikienamespace llvm {
20cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
21cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikienamespace object {
22cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass ObjectFile;
23cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie}
24cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
25cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass DWARFDebugAbbrev;
26cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass StringRef;
27cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass raw_ostream;
28cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
29cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieclass DWARFUnit {
30cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFDebugAbbrev *Abbrev;
31cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef InfoSection;
32cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef RangeSection;
33cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t RangeSectionBase;
34cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef StringSection;
35cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef StringOffsetSection;
36cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef AddrOffsetSection;
37cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t AddrOffsetSectionBase;
38cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const RelocAddrMap *RelocMap;
39cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool isLittleEndian;
40cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
41cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t Offset;
42cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t Length;
43cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint16_t Version;
44cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFAbbreviationDeclarationSet *Abbrevs;
45cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint8_t AddrSize;
46cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint64_t BaseAddr;
47cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  // The compile unit debug information entry items.
48cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  std::vector<DWARFDebugInfoEntryMinimal> DieArray;
49cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
50cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  class DWOHolder {
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<object::ObjectFile> DWOFile;
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<DWARFContext> DWOContext;
53cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    DWARFUnit *DWOU;
54cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  public:
55cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    DWOHolder(object::ObjectFile *DWOFile);
56cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    DWARFUnit *getUnit() const { return DWOU; }
57cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  };
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<DWOHolder> DWO;
59cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
60cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieprotected:
61cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Size in bytes of the unit header.
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  virtual uint32_t getHeaderSize() const { return 11; }
64cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
65cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiepublic:
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS,
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M,
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            bool LE);
69cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
70cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  virtual ~DWARFUnit();
71cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
72cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef getStringSection() const { return StringSection; }
73cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  StringRef getStringOffsetSection() const { return StringOffsetSection; }
74cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
75cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    AddrOffsetSection = AOS;
76cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    AddrOffsetSectionBase = Base;
77cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
78cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void setRangesSection(StringRef RS, uint32_t Base) {
79cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    RangeSection = RS;
80cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    RangeSectionBase = Base;
81cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
82cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
83cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
84cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  // FIXME: Result should be uint64_t in DWARF64.
85cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
86cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
87cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DataExtractor getDebugInfoExtractor() const {
88cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    return DataExtractor(InfoSection, isLittleEndian, AddrSize);
89cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
90cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DataExtractor getStringExtractor() const {
91cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    return DataExtractor(StringSection, false, 0);
92cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
93cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
94cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const RelocAddrMap *getRelocMap() const { return RelocMap; }
95cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
96cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
97cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
98cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// extractRangeList - extracts the range list referenced by this compile
99cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// unit from .debug_ranges section. Returns true on success.
100cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// Requires that compile unit is already extracted.
101cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool extractRangeList(uint32_t RangeListOffset,
102cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                        DWARFDebugRangeList &RangeList) const;
103cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void clear();
104cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t getOffset() const { return Offset; }
105cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
106cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint32_t getLength() const { return Length; }
107cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint16_t getVersion() const { return Version; }
108cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
109cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    return Abbrevs;
110cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
111cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint8_t getAddressByteSize() const { return AddrSize; }
112cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint64_t getBaseAddress() const { return BaseAddr; }
113cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
114cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void setBaseAddress(uint64_t base_addr) {
115cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    BaseAddr = base_addr;
116cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
117cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
118cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFDebugInfoEntryMinimal *
119cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  getCompileUnitDIE(bool extract_cu_die_only = true) {
120cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    extractDIEsIfNeeded(extract_cu_die_only);
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return DieArray.empty() ? nullptr : &DieArray[0];
122cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  }
123cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
124cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const char *getCompilationDir();
125cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  uint64_t getDWOId();
126cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void collectAddressRanges(DWARFAddressRangesVector &CURanges);
128cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
129cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// getInlinedChainForAddress - fetches inlined chain for a given address.
130cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// Returns empty chain if there is no subprogram containing address. The
131cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// chain is valid as long as parsed compile unit DIEs are not cleared.
132cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
133cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
134cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieprivate:
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Size in bytes of the .debug_info data associated with this compile unit.
136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1387d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
1397d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// hasn't already been done. Returns the number of DIEs parsed at this call.
1407d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  size_t extractDIEsIfNeeded(bool CUDieOnly);
141cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// extractDIEsToVector - Appends all parsed DIEs to a vector.
142cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
143cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie                           std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const;
1447d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// setDIERelations - We read in all of the DIE entries into our flat list
1457d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// of DIE entries and now we need to go back through all of them and set the
1467d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  /// parent, sibling and child pointers for quick DIE navigation.
1477d82b4284984143a093b793d0979a6bee4490332Alexey Samsonov  void setDIERelations();
148cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// clearDIEs - Clear parsed DIEs to keep memory usage low.
149cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  void clearDIEs(bool KeepCUDie);
150cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
151cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// parseDWO - Parses .dwo file for current compile unit. Returns true if
152cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// it was actually constructed.
153cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  bool parseDWO();
154cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
155cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// getSubprogramForAddress - Returns subprogram DIE with address range
156cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// encompassing the provided address. The pointer is alive as long as parsed
157cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  /// compile unit DIEs are not cleared.
158cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie  const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
159cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie};
160cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
161cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie}
162cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie
163cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#endif
164