1 | //===- DIEAttributeCloner.h -------------------------------------*- C++ -*-===// |
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 | #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H |
10 | #define LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H |
11 | |
12 | #include "ArrayList.h" |
13 | #include "DIEGenerator.h" |
14 | #include "DWARFLinkerCompileUnit.h" |
15 | #include "DWARFLinkerGlobalData.h" |
16 | #include "DWARFLinkerTypeUnit.h" |
17 | |
18 | namespace llvm { |
19 | namespace dwarf_linker { |
20 | namespace parallel { |
21 | |
22 | /// Information gathered and exchanged between the various |
23 | /// clone*Attr helpers about the attributes of a particular DIE. |
24 | struct AttributesInfo { |
25 | /// Short Name. |
26 | StringEntry *Name = nullptr; |
27 | |
28 | /// Mangled Name. |
29 | StringEntry *MangledName = nullptr; |
30 | |
31 | /// Does the DIE have an address pointing to live code section? |
32 | bool HasLiveAddress = false; |
33 | |
34 | /// Is this DIE only a declaration? |
35 | bool IsDeclaration = false; |
36 | |
37 | /// Does the DIE have a ranges attribute? |
38 | bool HasRanges = false; |
39 | |
40 | /// Does the DIE have a string offset attribute? |
41 | bool HasStringOffsetBaseAttr = false; |
42 | }; |
43 | |
44 | /// This class creates clones of input DIE attributes. |
45 | /// It enumerates attributes of input DIE, creates clone for each |
46 | /// attribute, adds cloned attribute to the output DIE. |
47 | class DIEAttributeCloner { |
48 | public: |
49 | DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, CompileUnit *OutUnit, |
50 | const DWARFDebugInfoEntry *InputDieEntry, |
51 | DIEGenerator &Generator, |
52 | std::optional<int64_t> FuncAddressAdjustment, |
53 | std::optional<int64_t> VarAddressAdjustment, |
54 | bool HasLocationExpressionAddress) |
55 | : DIEAttributeCloner(OutDIE, InUnit, |
56 | CompileUnit::OutputUnitVariantPtr(OutUnit), |
57 | InputDieEntry, Generator, FuncAddressAdjustment, |
58 | VarAddressAdjustment, HasLocationExpressionAddress) { |
59 | } |
60 | |
61 | DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, TypeUnit *OutUnit, |
62 | const DWARFDebugInfoEntry *InputDieEntry, |
63 | DIEGenerator &Generator, |
64 | std::optional<int64_t> FuncAddressAdjustment, |
65 | std::optional<int64_t> VarAddressAdjustment, |
66 | bool HasLocationExpressionAddress) |
67 | : DIEAttributeCloner(OutDIE, InUnit, |
68 | CompileUnit::OutputUnitVariantPtr(OutUnit), |
69 | InputDieEntry, Generator, FuncAddressAdjustment, |
70 | VarAddressAdjustment, HasLocationExpressionAddress) { |
71 | } |
72 | |
73 | /// Clone attributes of input DIE. |
74 | void clone(); |
75 | |
76 | /// Create abbreviations for the output DIE after all attributes are cloned. |
77 | unsigned finalizeAbbreviations(bool HasChildrenToClone); |
78 | |
79 | /// Cannot be used concurrently. |
80 | AttributesInfo AttrInfo; |
81 | |
82 | unsigned getOutOffset() { return AttrOutOffset; } |
83 | |
84 | protected: |
85 | DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, |
86 | CompileUnit::OutputUnitVariantPtr OutUnit, |
87 | const DWARFDebugInfoEntry *InputDieEntry, |
88 | DIEGenerator &Generator, |
89 | std::optional<int64_t> FuncAddressAdjustment, |
90 | std::optional<int64_t> VarAddressAdjustment, |
91 | bool HasLocationExpressionAddress) |
92 | : OutDIE(OutDIE), InUnit(InUnit), OutUnit(OutUnit), |
93 | DebugInfoOutputSection( |
94 | OutUnit->getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo)), |
95 | InputDieEntry(InputDieEntry), Generator(Generator), |
96 | FuncAddressAdjustment(FuncAddressAdjustment), |
97 | VarAddressAdjustment(VarAddressAdjustment), |
98 | HasLocationExpressionAddress(HasLocationExpressionAddress) { |
99 | InputDIEIdx = InUnit.getDIEIndex(Die: InputDieEntry); |
100 | |
101 | // Use DW_FORM_strp form for string attributes for DWARF version less than 5 |
102 | // or if output unit is type unit and we need to produce deterministic |
103 | // result. (We can not generate deterministic results for debug_str_offsets |
104 | // section when attributes are cloned parallelly). |
105 | Use_DW_FORM_strp = |
106 | (InUnit.getVersion() < 5) || |
107 | (OutUnit.isTypeUnit() && |
108 | ((InUnit.getGlobalData().getOptions().Threads != 1) && |
109 | !InUnit.getGlobalData().getOptions().AllowNonDeterministicOutput)); |
110 | } |
111 | |
112 | /// Clone string attribute. |
113 | size_t |
114 | cloneStringAttr(const DWARFFormValue &Val, |
115 | const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); |
116 | |
117 | /// Clone attribute referencing another DIE. |
118 | size_t |
119 | cloneDieRefAttr(const DWARFFormValue &Val, |
120 | const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); |
121 | |
122 | /// Clone scalar attribute. |
123 | size_t |
124 | cloneScalarAttr(const DWARFFormValue &Val, |
125 | const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); |
126 | |
127 | /// Clone block or exprloc attribute. |
128 | size_t |
129 | cloneBlockAttr(const DWARFFormValue &Val, |
130 | const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); |
131 | |
132 | /// Clone address attribute. |
133 | size_t |
134 | cloneAddressAttr(const DWARFFormValue &Val, |
135 | const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec); |
136 | |
137 | /// Returns true if attribute should be skipped. |
138 | bool |
139 | shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec); |
140 | |
141 | /// Output DIE. |
142 | DIE *OutDIE = nullptr; |
143 | |
144 | /// Input compilation unit. |
145 | CompileUnit &InUnit; |
146 | |
147 | /// Output unit(either "plain" compilation unit, either artificial type unit). |
148 | CompileUnit::OutputUnitVariantPtr OutUnit; |
149 | |
150 | /// .debug_info section descriptor. |
151 | SectionDescriptor &DebugInfoOutputSection; |
152 | |
153 | /// Input DIE entry. |
154 | const DWARFDebugInfoEntry *InputDieEntry = nullptr; |
155 | |
156 | /// Input DIE index. |
157 | uint32_t InputDIEIdx = 0; |
158 | |
159 | /// Output DIE generator. |
160 | DIEGenerator &Generator; |
161 | |
162 | /// Relocation adjustment for the function address ranges. |
163 | std::optional<int64_t> FuncAddressAdjustment; |
164 | |
165 | /// Relocation adjustment for the variable locations. |
166 | std::optional<int64_t> VarAddressAdjustment; |
167 | |
168 | /// Indicates whether InputDieEntry has an location attribute |
169 | /// containg address expression. |
170 | bool HasLocationExpressionAddress = false; |
171 | |
172 | /// Output offset after all attributes. |
173 | unsigned AttrOutOffset = 0; |
174 | |
175 | /// Patches for the cloned attributes. |
176 | OffsetsPtrVector PatchesOffsets; |
177 | |
178 | /// This flag forces using DW_FORM_strp for string attributes. |
179 | bool Use_DW_FORM_strp = false; |
180 | }; |
181 | |
182 | } // end of namespace parallel |
183 | } // end of namespace dwarf_linker |
184 | } // end of namespace llvm |
185 | |
186 | #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H |
187 | |