aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DIEAttributeCloner.h
blob: 6a6bd08570d7da2ab10ac51f74ee8cf4cd67f9d2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//===- DIEAttributeCloner.h -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H
#define LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H

#include "ArrayList.h"
#include "DIEGenerator.h"
#include "DWARFLinkerCompileUnit.h"
#include "DWARFLinkerGlobalData.h"
#include "DWARFLinkerTypeUnit.h"

namespace llvm {
namespace dwarf_linker {
namespace parallel {

/// Information gathered and exchanged between the various
/// clone*Attr helpers about the attributes of a particular DIE.
struct AttributesInfo {
  /// Short Name.
  StringEntry *Name = nullptr;

  /// Mangled Name.
  StringEntry *MangledName = nullptr;

  /// Does the DIE have an address pointing to live code section?
  bool HasLiveAddress = false;

  /// Is this DIE only a declaration?
  bool IsDeclaration = false;

  /// Does the DIE have a ranges attribute?
  bool HasRanges = false;

  /// Does the DIE have a string offset attribute?
  bool HasStringOffsetBaseAttr = false;
};

/// This class creates clones of input DIE attributes.
/// It enumerates attributes of input DIE, creates clone for each
/// attribute, adds cloned attribute to the output DIE.
class DIEAttributeCloner {
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)
      : DIEAttributeCloner(OutDIE, InUnit,
                           CompileUnit::OutputUnitVariantPtr(OutUnit),
                           InputDieEntry, Generator, FuncAddressAdjustment,
                           VarAddressAdjustment, HasLocationExpressionAddress) {
  }

  DIEAttributeCloner(DIE *OutDIE, CompileUnit &InUnit, TypeUnit *OutUnit,
                     const DWARFDebugInfoEntry *InputDieEntry,
                     DIEGenerator &Generator,
                     std::optional<int64_t> FuncAddressAdjustment,
                     std::optional<int64_t> VarAddressAdjustment,
                     bool HasLocationExpressionAddress)
      : DIEAttributeCloner(OutDIE, InUnit,
                           CompileUnit::OutputUnitVariantPtr(OutUnit),
                           InputDieEntry, Generator, FuncAddressAdjustment,
                           VarAddressAdjustment, HasLocationExpressionAddress) {
  }

  /// Clone attributes of input DIE.
  void clone();

  /// Create abbreviations for the output DIE after all attributes are cloned.
  unsigned finalizeAbbreviations(bool HasChildrenToClone);

  /// Cannot be used concurrently.
  AttributesInfo AttrInfo;

  unsigned getOutOffset() { return AttrOutOffset; }

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)
      : OutDIE(OutDIE), InUnit(InUnit), OutUnit(OutUnit),
        DebugInfoOutputSection(
            OutUnit->getSectionDescriptor(DebugSectionKind::DebugInfo)),
        InputDieEntry(InputDieEntry), Generator(Generator),
        FuncAddressAdjustment(FuncAddressAdjustment),
        VarAddressAdjustment(VarAddressAdjustment),
        HasLocationExpressionAddress(HasLocationExpressionAddress) {
    InputDIEIdx = InUnit.getDIEIndex(InputDieEntry);

    // Use DW_FORM_strp form for string attributes for DWARF version less than 5
    // or if output unit is type unit and we need to produce deterministic
    // result. (We can not generate deterministic results for debug_str_offsets
    // section when attributes are cloned parallelly).
    Use_DW_FORM_strp =
        (InUnit.getVersion() < 5) ||
        (OutUnit.isTypeUnit() &&
         ((InUnit.getGlobalData().getOptions().Threads != 1) &&
          !InUnit.getGlobalData().getOptions().AllowNonDeterministicOutput));
  }

  /// Clone string attribute.
  size_t
  cloneStringAttr(const DWARFFormValue &Val,
                  const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);

  /// Clone attribute referencing another DIE.
  size_t
  cloneDieRefAttr(const DWARFFormValue &Val,
                  const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);

  /// Clone scalar attribute.
  size_t
  cloneScalarAttr(const DWARFFormValue &Val,
                  const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);

  /// Clone block or exprloc attribute.
  size_t
  cloneBlockAttr(const DWARFFormValue &Val,
                 const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);

  /// Clone address attribute.
  size_t
  cloneAddressAttr(const DWARFFormValue &Val,
                   const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);

  /// Returns true if attribute should be skipped.
  bool
  shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec);

  /// Output DIE.
  DIE *OutDIE = nullptr;

  /// Input compilation unit.
  CompileUnit &InUnit;

  /// Output unit(either "plain" compilation unit, either artificial type unit).
  CompileUnit::OutputUnitVariantPtr OutUnit;

  /// .debug_info section descriptor.
  SectionDescriptor &DebugInfoOutputSection;

  /// Input DIE entry.
  const DWARFDebugInfoEntry *InputDieEntry = nullptr;

  /// Input DIE index.
  uint32_t InputDIEIdx = 0;

  /// Output DIE generator.
  DIEGenerator &Generator;

  /// Relocation adjustment for the function address ranges.
  std::optional<int64_t> FuncAddressAdjustment;

  /// Relocation adjustment for the variable locations.
  std::optional<int64_t> VarAddressAdjustment;

  /// Indicates whether InputDieEntry has an location attribute
  /// containg address expression.
  bool HasLocationExpressionAddress = false;

  /// Output offset after all attributes.
  unsigned AttrOutOffset = 0;

  /// Patches for the cloned attributes.
  OffsetsPtrVector PatchesOffsets;

  /// This flag forces using DW_FORM_strp for string attributes.
  bool Use_DW_FORM_strp = false;
};

} // end of namespace parallel
} // end of namespace dwarf_linker
} // end of namespace llvm

#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DIEATTRIBUTECLONER_H