comparison tools/dsymutil/CompileUnit.cpp @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
comparison
equal deleted inserted replaced
146:3fc4d5c3e21e 148:63bd29f05246
1 //===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "CompileUnit.h"
10 #include "DeclContext.h"
11
12 namespace llvm {
13 namespace dsymutil {
14
15 /// Check if the DIE at \p Idx is in the scope of a function.
16 static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
17 while (Idx) {
18 if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram)
19 return true;
20 Idx = U.getInfo(Idx).ParentIdx;
21 }
22 return false;
23 }
24
25 uint16_t CompileUnit::getLanguage() {
26 if (!Language) {
27 DWARFDie CU = getOrigUnit().getUnitDIE();
28 Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0);
29 }
30 return Language;
31 }
32
33 void CompileUnit::markEverythingAsKept() {
34 unsigned Idx = 0;
35
36 setHasInterestingContent();
37
38 for (auto &I : Info) {
39 // Mark everything that wasn't explicit marked for pruning.
40 I.Keep = !I.Prune;
41 auto DIE = OrigUnit.getDIEAtIndex(Idx++);
42
43 // Try to guess which DIEs must go to the accelerator tables. We do that
44 // just for variables, because functions will be handled depending on
45 // whether they carry a DW_AT_low_pc attribute or not.
46 if (DIE.getTag() != dwarf::DW_TAG_variable &&
47 DIE.getTag() != dwarf::DW_TAG_constant)
48 continue;
49
50 Optional<DWARFFormValue> Value;
51 if (!(Value = DIE.find(dwarf::DW_AT_location))) {
52 if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
53 !inFunctionScope(*this, I.ParentIdx))
54 I.InDebugMap = true;
55 continue;
56 }
57 if (auto Block = Value->getAsBlock()) {
58 if (Block->size() > OrigUnit.getAddressByteSize() &&
59 (*Block)[0] == dwarf::DW_OP_addr)
60 I.InDebugMap = true;
61 }
62 }
63 }
64
65 uint64_t CompileUnit::computeNextUnitOffset() {
66 NextUnitOffset = StartOffset;
67 if (NewUnit) {
68 NextUnitOffset += 11 /* Header size */;
69 NextUnitOffset += NewUnit->getUnitDie().getSize();
70 }
71 return NextUnitOffset;
72 }
73
74 /// Keep track of a forward cross-cu reference from this unit
75 /// to \p Die that lives in \p RefUnit.
76 void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
77 DeclContext *Ctxt, PatchLocation Attr) {
78 ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
79 }
80
81 void CompileUnit::fixupForwardReferences() {
82 for (const auto &Ref : ForwardDIEReferences) {
83 DIE *RefDie;
84 const CompileUnit *RefUnit;
85 PatchLocation Attr;
86 DeclContext *Ctxt;
87 std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
88 if (Ctxt && Ctxt->getCanonicalDIEOffset())
89 Attr.set(Ctxt->getCanonicalDIEOffset());
90 else
91 Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
92 }
93 }
94
95 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
96 Labels.insert({LabelLowPc, PcOffset});
97 }
98
99 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
100 int64_t PcOffset) {
101 // Don't add empty ranges to the interval map. They are a problem because
102 // the interval map expects half open intervals. This is safe because they
103 // are empty anyway.
104 if (FuncHighPc != FuncLowPc)
105 Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
106 this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
107 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
108 }
109
110 void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
111 if (Die.getTag() != dwarf::DW_TAG_compile_unit)
112 RangeAttributes.push_back(Attr);
113 else
114 UnitRangeAttribute = Attr;
115 }
116
117 void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
118 LocationAttributes.emplace_back(Attr, PcOffset);
119 }
120
121 void CompileUnit::addNamespaceAccelerator(const DIE *Die,
122 DwarfStringPoolEntryRef Name) {
123 Namespaces.emplace_back(Name, Die);
124 }
125
126 void CompileUnit::addObjCAccelerator(const DIE *Die,
127 DwarfStringPoolEntryRef Name,
128 bool SkipPubSection) {
129 ObjC.emplace_back(Name, Die, SkipPubSection);
130 }
131
132 void CompileUnit::addNameAccelerator(const DIE *Die,
133 DwarfStringPoolEntryRef Name,
134 bool SkipPubSection) {
135 Pubnames.emplace_back(Name, Die, SkipPubSection);
136 }
137
138 void CompileUnit::addTypeAccelerator(const DIE *Die,
139 DwarfStringPoolEntryRef Name,
140 bool ObjcClassImplementation,
141 uint32_t QualifiedNameHash) {
142 Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
143 }
144
145 } // namespace dsymutil
146 } // namespace llvm