summaryrefslogtreecommitdiffstats
path: root/lib/DebugInfo/DWARFCompileUnit.h
blob: 2a74605fcb2d3d3d3a63f9b580d190dc5f2b1864 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//===-- DWARFCompileUnit.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_DWARFCOMPILEUNIT_H
#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H

#include "DWARFDebugAbbrev.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugRangeList.h"
#include "DWARFRelocMap.h"
#include <vector>

namespace llvm {

class DWARFDebugAbbrev;
class StringRef;
class raw_ostream;

class DWARFCompileUnit {
  const DWARFDebugAbbrev *Abbrev;
  StringRef InfoSection;
  StringRef AbbrevSection;
  StringRef RangeSection;
  StringRef StringSection;
  StringRef StringOffsetSection;
  StringRef AddrOffsetSection;
  const RelocAddrMap *RelocMap;
  bool isLittleEndian;

  uint32_t Offset;
  uint32_t Length;
  uint16_t Version;
  const DWARFAbbreviationDeclarationSet *Abbrevs;
  uint8_t AddrSize;
  uint64_t BaseAddr;
  // The compile unit debug information entry item.
  std::vector<DWARFDebugInfoEntryMinimal> DieArray;
public:

  DWARFCompileUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS,
                   StringRef RS, StringRef SS, StringRef SOS, StringRef AOS,
                   const RelocAddrMap *M, bool LE) :
    Abbrev(DA), InfoSection(IS), AbbrevSection(AS),
    RangeSection(RS), StringSection(SS), StringOffsetSection(SOS),
    AddrOffsetSection(AOS), RelocMap(M), isLittleEndian(LE) {
    clear();
  }

  StringRef getStringSection() const { return StringSection; }
  StringRef getStringOffsetSection() const { return StringOffsetSection; }
  StringRef getAddrOffsetSection() const { return AddrOffsetSection; }
  const RelocAddrMap *getRelocMap() const { return RelocMap; }
  DataExtractor getDebugInfoExtractor() const;

  bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
  uint32_t extract(uint32_t offset, DataExtractor debug_info_data,
                   const DWARFAbbreviationDeclarationSet *abbrevs);

  /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
  /// hasn't already been done. Returns the number of DIEs parsed at this call.
  size_t extractDIEsIfNeeded(bool cu_die_only);
  /// extractRangeList - extracts the range list referenced by this compile
  /// unit from .debug_ranges section. Returns true on success.
  /// Requires that compile unit is already extracted.
  bool extractRangeList(uint32_t RangeListOffset,
                        DWARFDebugRangeList &RangeList) const;
  void clear();
  void dump(raw_ostream &OS);
  uint32_t getOffset() const { return Offset; }
  /// Size in bytes of the compile unit header.
  uint32_t getSize() const { return 11; }
  bool containsDIEOffset(uint32_t die_offset) const {
    return die_offset >= getFirstDIEOffset() &&
      die_offset < getNextCompileUnitOffset();
  }
  uint32_t getFirstDIEOffset() const { return Offset + getSize(); }
  uint32_t getNextCompileUnitOffset() const { return Offset + Length + 4; }
  /// Size in bytes of the .debug_info data associated with this compile unit.
  size_t getDebugInfoSize() const { return Length + 4 - getSize(); }
  uint32_t getLength() const { return Length; }
  uint16_t getVersion() const { return Version; }
  const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
    return Abbrevs;
  }
  uint8_t getAddressByteSize() const { return AddrSize; }
  uint64_t getBaseAddress() const { return BaseAddr; }

  void setBaseAddress(uint64_t base_addr) {
    BaseAddr = base_addr;
  }

  const DWARFDebugInfoEntryMinimal *
  getCompileUnitDIE(bool extract_cu_die_only = true) {
    extractDIEsIfNeeded(extract_cu_die_only);
    if (DieArray.empty())
      return NULL;
    return &DieArray[0];
  }

  const char *getCompilationDir();

  /// setDIERelations - We read in all of the DIE entries into our flat list
  /// of DIE entries and now we need to go back through all of them and set the
  /// parent, sibling and child pointers for quick DIE navigation.
  void setDIERelations();

  void addDIE(DWARFDebugInfoEntryMinimal &die) {
    // The average bytes per DIE entry has been seen to be
    // around 14-20 so lets pre-reserve the needed memory for
    // our DIE entries accordingly. Search forward for "Compute
    // average bytes per DIE" to see #if'ed out code that does
    // that determination.

    // Only reserve the memory if we are adding children of
    // the main compile unit DIE. The compile unit DIE is always
    // the first entry, so if our size is 1, then we are adding
    // the first compile unit child DIE and should reserve
    // the memory.
    if (DieArray.empty())
      DieArray.reserve(getDebugInfoSize() / 14);
    DieArray.push_back(die);
  }

  void clearDIEs(bool keep_compile_unit_die);

  void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
                              bool clear_dies_if_already_not_parsed);

  /// getInlinedChainForAddress - fetches inlined chain for a given address.
  /// Returns empty chain if there is no subprogram containing address.
  DWARFDebugInfoEntryMinimal::InlinedChain getInlinedChainForAddress(
      uint64_t Address);
};

}

#endif