[Sanitizers] UBSan unreachable incompatible with Kernel ASan
[llvm-core.git] / tools / dsymutil / CompileUnit.cpp
blob3eb6abbb852d20fce110b39b80683e3234c7d6d2
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 //===----------------------------------------------------------------------===//
9 #include "CompileUnit.h"
10 #include "DeclContext.h"
12 namespace llvm {
13 namespace dsymutil {
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;
22 return false;
25 void CompileUnit::markEverythingAsKept() {
26 unsigned Idx = 0;
28 setHasInterestingContent();
30 for (auto &I : Info) {
31 // Mark everything that wasn't explicit marked for pruning.
32 I.Keep = !I.Prune;
33 auto DIE = OrigUnit.getDIEAtIndex(Idx++);
35 // Try to guess which DIEs must go to the accelerator tables. We do that
36 // just for variables, because functions will be handled depending on
37 // whether they carry a DW_AT_low_pc attribute or not.
38 if (DIE.getTag() != dwarf::DW_TAG_variable &&
39 DIE.getTag() != dwarf::DW_TAG_constant)
40 continue;
42 Optional<DWARFFormValue> Value;
43 if (!(Value = DIE.find(dwarf::DW_AT_location))) {
44 if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
45 !inFunctionScope(*this, I.ParentIdx))
46 I.InDebugMap = true;
47 continue;
49 if (auto Block = Value->getAsBlock()) {
50 if (Block->size() > OrigUnit.getAddressByteSize() &&
51 (*Block)[0] == dwarf::DW_OP_addr)
52 I.InDebugMap = true;
57 uint64_t CompileUnit::computeNextUnitOffset() {
58 NextUnitOffset = StartOffset + 11 /* Header size */;
59 // The root DIE might be null, meaning that the Unit had nothing to
60 // contribute to the linked output. In that case, we will emit the
61 // unit header without any actual DIE.
62 if (NewUnit)
63 NextUnitOffset += NewUnit->getUnitDie().getSize();
64 return NextUnitOffset;
67 /// Keep track of a forward cross-cu reference from this unit
68 /// to \p Die that lives in \p RefUnit.
69 void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
70 DeclContext *Ctxt, PatchLocation Attr) {
71 ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
74 void CompileUnit::fixupForwardReferences() {
75 for (const auto &Ref : ForwardDIEReferences) {
76 DIE *RefDie;
77 const CompileUnit *RefUnit;
78 PatchLocation Attr;
79 DeclContext *Ctxt;
80 std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
81 if (Ctxt && Ctxt->getCanonicalDIEOffset())
82 Attr.set(Ctxt->getCanonicalDIEOffset());
83 else
84 Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
88 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
89 Labels.insert({LabelLowPc, PcOffset});
92 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
93 int64_t PcOffset) {
94 // Don't add empty ranges to the interval map. They are a problem because
95 // the interval map expects half open intervals. This is safe because they
96 // are empty anyway.
97 if (FuncHighPc != FuncLowPc)
98 Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
99 this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
100 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
103 void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
104 if (Die.getTag() != dwarf::DW_TAG_compile_unit)
105 RangeAttributes.push_back(Attr);
106 else
107 UnitRangeAttribute = Attr;
110 void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
111 LocationAttributes.emplace_back(Attr, PcOffset);
114 void CompileUnit::addNamespaceAccelerator(const DIE *Die,
115 DwarfStringPoolEntryRef Name) {
116 Namespaces.emplace_back(Name, Die);
119 void CompileUnit::addObjCAccelerator(const DIE *Die,
120 DwarfStringPoolEntryRef Name,
121 bool SkipPubSection) {
122 ObjC.emplace_back(Name, Die, SkipPubSection);
125 void CompileUnit::addNameAccelerator(const DIE *Die,
126 DwarfStringPoolEntryRef Name,
127 bool SkipPubSection) {
128 Pubnames.emplace_back(Name, Die, SkipPubSection);
131 void CompileUnit::addTypeAccelerator(const DIE *Die,
132 DwarfStringPoolEntryRef Name,
133 bool ObjcClassImplementation,
134 uint32_t QualifiedNameHash) {
135 Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
138 } // namespace dsymutil
139 } // namespace llvm