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
18namespace llvm {
19namespace dwarf_linker {
20namespace parallel {
21
22/// Information gathered and exchanged between the various
23/// clone*Attr helpers about the attributes of a particular DIE.
24struct 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 /// Does the DIE have an address base attribute?
44 bool HasAddrBaseAttr = false;
45};
46
47/// This class creates clones of input DIE attributes.
48/// It enumerates attributes of input DIE, creates clone for each
49/// attribute, adds cloned attribute to the output DIE.
50class DIEAttributeCloner {
51public:
52 DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, CompileUnit *OutUnit,
53 const DWARFDebugInfoEntry *InputDieEntry,
54 DIEGenerator &Generator,
55 std::optional<int64_t> FuncAddressAdjustment,
56 std::optional<int64_t> VarAddressAdjustment,
57 bool HasLocationExpressionAddress)
58 : DIEAttributeCloner(OutDIE, InUnit,
59 CompileUnit::OutputUnitVariantPtr(OutUnit),
60 InputDieEntry, Generator, FuncAddressAdjustment,
61 VarAddressAdjustment, HasLocationExpressionAddress) {
62 }
63
64 DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, TypeUnit *OutUnit,
65 const DWARFDebugInfoEntry *InputDieEntry,
66 DIEGenerator &Generator,
67 std::optional<int64_t> FuncAddressAdjustment,
68 std::optional<int64_t> VarAddressAdjustment,
69 bool HasLocationExpressionAddress)
70 : DIEAttributeCloner(OutDIE, InUnit,
71 CompileUnit::OutputUnitVariantPtr(OutUnit),
72 InputDieEntry, Generator, FuncAddressAdjustment,
73 VarAddressAdjustment, HasLocationExpressionAddress) {
74 }
75
76 /// Clone attributes of input DIE.
77 void clone();
78
79 /// Create abbreviations for the output DIE after all attributes are cloned.
80 unsigned finalizeAbbreviations(bool HasChildrenToClone);
81
82 /// Cannot be used concurrently.
83 AttributesInfo AttrInfo;
84
85 unsigned getOutOffset() { return AttrOutOffset; }
86
87protected:
88 DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit,
89 CompileUnit::OutputUnitVariantPtr OutUnit,
90 const DWARFDebugInfoEntry *InputDieEntry,
91 DIEGenerator &Generator,
92 std::optional<int64_t> FuncAddressAdjustment,
93 std::optional<int64_t> VarAddressAdjustment,
94 bool HasLocationExpressionAddress)
95 : OutDIE(OutDIE), InUnit(InUnit), OutUnit(OutUnit),
96 DebugInfoOutputSection(
97 OutUnit->getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo)),
98 InputDieEntry(InputDieEntry), Generator(Generator),
99 FuncAddressAdjustment(FuncAddressAdjustment),
100 VarAddressAdjustment(VarAddressAdjustment),
101 HasLocationExpressionAddress(HasLocationExpressionAddress) {
102 InputDIEIdx = InUnit.getDIEIndex(Die: InputDieEntry);
103
104 // Use DW_FORM_strp form for string attributes for DWARF version less than 5
105 // or if output unit is type unit and attributes are cloned in parallel
106 // (debug_str_offsets ordering would be non-deterministic otherwise).
107 Use_DW_FORM_strp = (InUnit.getVersion() < 5) ||
108 (OutUnit.isTypeUnit() &&
109 InUnit.getGlobalData().getOptions().Threads != 1);
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 the input DIE's DW_AT_high_pc value \p HighPC, constrained so the
138 /// code range it ends stays clear of the symbol the linker places next. \p
139 /// IsLength tells whether high_pc is encoded as a length rather than an
140 /// address.
141 ///
142 /// A scope nested in a function inherits the overrun of the function, so it
143 /// is constrained as well.
144 uint64_t constrainHighPC(uint64_t HighPC, bool IsLength);
145
146 /// Returns true if attribute should be skipped.
147 bool
148 shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec);
149
150 /// Output DIE.
151 DIE *OutDIE = nullptr;
152
153 /// Input compilation unit.
154 CompileUnit &InUnit;
155
156 /// Output unit(either "plain" compilation unit, either artificial type unit).
157 CompileUnit::OutputUnitVariantPtr OutUnit;
158
159 /// .debug_info section descriptor.
160 SectionDescriptor &DebugInfoOutputSection;
161
162 /// Input DIE entry.
163 const DWARFDebugInfoEntry *InputDieEntry = nullptr;
164
165 /// Input DIE index.
166 uint32_t InputDIEIdx = 0;
167
168 /// Output DIE generator.
169 DIEGenerator &Generator;
170
171 /// Relocation adjustment for the function address ranges.
172 std::optional<int64_t> FuncAddressAdjustment;
173
174 /// Relocation adjustment for the variable locations.
175 std::optional<int64_t> VarAddressAdjustment;
176
177 /// Indicates whether InputDieEntry has an location attribute
178 /// containg address expression.
179 bool HasLocationExpressionAddress = false;
180
181 /// Output offset after all attributes.
182 unsigned AttrOutOffset = 0;
183
184 /// Patches for the cloned attributes.
185 OffsetsPtrVector PatchesOffsets;
186
187 /// This flag forces using DW_FORM_strp for string attributes.
188 bool Use_DW_FORM_strp = false;
189};
190
191} // end of namespace parallel
192} // end of namespace dwarf_linker
193} // end of namespace llvm
194
195#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H
196