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