1 //===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "CompileUnit.h" 11 #include "DeclContext.h" 12 13 namespace llvm { 14 namespace dsymutil { 15 16 /// Check if the DIE at \p Idx is in the scope of a function. 17 static bool inFunctionScope(CompileUnit &U, unsigned Idx) { 18 while (Idx) { 19 if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram) 20 return true; 21 Idx = U.getInfo(Idx).ParentIdx; 22 } 23 return false; 24 } 25 26 void CompileUnit::markEverythingAsKept() { 27 unsigned Idx = 0; 28 29 setHasInterestingContent(); 30 31 for (auto &I : Info) { 32 // Mark everything that wasn't explicit marked for pruning. 33 I.Keep = !I.Prune; 34 auto DIE = OrigUnit.getDIEAtIndex(Idx++); 35 36 // Try to guess which DIEs must go to the accelerator tables. We do that 37 // just for variables, because functions will be handled depending on 38 // whether they carry a DW_AT_low_pc attribute or not. 39 if (DIE.getTag() != dwarf::DW_TAG_variable && 40 DIE.getTag() != dwarf::DW_TAG_constant) 41 continue; 42 43 Optional<DWARFFormValue> Value; 44 if (!(Value = DIE.find(dwarf::DW_AT_location))) { 45 if ((Value = DIE.find(dwarf::DW_AT_const_value)) && 46 !inFunctionScope(*this, I.ParentIdx)) 47 I.InDebugMap = true; 48 continue; 49 } 50 if (auto Block = Value->getAsBlock()) { 51 if (Block->size() > OrigUnit.getAddressByteSize() && 52 (*Block)[0] == dwarf::DW_OP_addr) 53 I.InDebugMap = true; 54 } 55 } 56 } 57 58 uint64_t CompileUnit::computeNextUnitOffset() { 59 NextUnitOffset = StartOffset + 11 /* Header size */; 60 // The root DIE might be null, meaning that the Unit had nothing to 61 // contribute to the linked output. In that case, we will emit the 62 // unit header without any actual DIE. 63 if (NewUnit) 64 NextUnitOffset += NewUnit->getUnitDie().getSize(); 65 return NextUnitOffset; 66 } 67 68 /// Keep track of a forward cross-cu reference from this unit 69 /// to \p Die that lives in \p RefUnit. 70 void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit, 71 DeclContext *Ctxt, PatchLocation Attr) { 72 ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr); 73 } 74 75 void CompileUnit::fixupForwardReferences() { 76 for (const auto &Ref : ForwardDIEReferences) { 77 DIE *RefDie; 78 const CompileUnit *RefUnit; 79 PatchLocation Attr; 80 DeclContext *Ctxt; 81 std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref; 82 if (Ctxt && Ctxt->getCanonicalDIEOffset()) 83 Attr.set(Ctxt->getCanonicalDIEOffset()); 84 else 85 Attr.set(RefDie->getOffset() + RefUnit->getStartOffset()); 86 } 87 } 88 89 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) { 90 Labels.insert({LabelLowPc, PcOffset}); 91 } 92 93 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc, 94 int64_t PcOffset) { 95 Ranges.insert(FuncLowPc, FuncHighPc, PcOffset); 96 this->LowPc = std::min(LowPc, FuncLowPc + PcOffset); 97 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset); 98 } 99 100 void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) { 101 if (Die.getTag() != dwarf::DW_TAG_compile_unit) 102 RangeAttributes.push_back(Attr); 103 else 104 UnitRangeAttribute = Attr; 105 } 106 107 void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) { 108 LocationAttributes.emplace_back(Attr, PcOffset); 109 } 110 111 void CompileUnit::addNamespaceAccelerator(const DIE *Die, 112 DwarfStringPoolEntryRef Name) { 113 Namespaces.emplace_back(Name, Die); 114 } 115 116 void CompileUnit::addObjCAccelerator(const DIE *Die, 117 DwarfStringPoolEntryRef Name, 118 bool SkipPubSection) { 119 ObjC.emplace_back(Name, Die, SkipPubSection); 120 } 121 122 void CompileUnit::addNameAccelerator(const DIE *Die, 123 DwarfStringPoolEntryRef Name, 124 bool SkipPubSection) { 125 Pubnames.emplace_back(Name, Die, SkipPubSection); 126 } 127 128 void CompileUnit::addTypeAccelerator(const DIE *Die, 129 DwarfStringPoolEntryRef Name, 130 bool ObjcClassImplementation, 131 uint32_t QualifiedNameHash) { 132 Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation); 133 } 134 135 } // namespace dsymutil 136 } // namespace llvm 137