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
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.
47class DIEAttributeCloner {
48public:
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
84protected:
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