xref: /freebsd/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DIEAttributeCloner.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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(DebugSectionKind::DebugInfo)),
95         InputDieEntry(InputDieEntry), Generator(Generator),
96         FuncAddressAdjustment(FuncAddressAdjustment),
97         VarAddressAdjustment(VarAddressAdjustment),
98         HasLocationExpressionAddress(HasLocationExpressionAddress) {
99     InputDIEIdx = InUnit.getDIEIndex(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