Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DIEGenerator.h
35292 views
1
//===- DIEGenerator.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_DIEGENERATOR_H
10
#define LLVM_LIB_DWARFLINKER_PARALLEL_DIEGENERATOR_H
11
12
#include "DWARFLinkerGlobalData.h"
13
#include "DWARFLinkerUnit.h"
14
#include "llvm/CodeGen/DIE.h"
15
#include "llvm/Support/LEB128.h"
16
17
namespace llvm {
18
namespace dwarf_linker {
19
namespace parallel {
20
21
/// This class is a helper to create output DIE tree.
22
class DIEGenerator {
23
public:
24
DIEGenerator(BumpPtrAllocator &Allocator, DwarfUnit &CU)
25
: Allocator(Allocator), CU(CU) {}
26
27
DIEGenerator(DIE *OutputDIE, BumpPtrAllocator &Allocator, DwarfUnit &CU)
28
: Allocator(Allocator), CU(CU), OutputDIE(OutputDIE) {}
29
30
/// Creates a DIE of specified tag \p DieTag and \p OutOffset.
31
DIE *createDIE(dwarf::Tag DieTag, uint32_t OutOffset) {
32
OutputDIE = DIE::get(Allocator, DieTag);
33
34
OutputDIE->setOffset(OutOffset);
35
36
return OutputDIE;
37
}
38
39
DIE *getDIE() { return OutputDIE; }
40
41
/// Adds a specified \p Child to the current DIE.
42
void addChild(DIE *Child) {
43
assert(Child != nullptr);
44
assert(OutputDIE != nullptr);
45
46
OutputDIE->addChild(Child);
47
}
48
49
/// Adds specified scalar attribute to the current DIE.
50
std::pair<DIEValue &, size_t> addScalarAttribute(dwarf::Attribute Attr,
51
dwarf::Form AttrForm,
52
uint64_t Value) {
53
return addAttribute(Attr, AttrForm, DIEInteger(Value));
54
}
55
56
/// Adds specified location attribute to the current DIE.
57
std::pair<DIEValue &, size_t> addLocationAttribute(dwarf::Attribute Attr,
58
dwarf::Form AttrForm,
59
ArrayRef<uint8_t> Bytes) {
60
DIELoc *Loc = new (Allocator) DIELoc;
61
for (auto Byte : Bytes)
62
static_cast<DIEValueList *>(Loc)->addValue(
63
Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
64
DIEInteger(Byte));
65
Loc->setSize(Bytes.size());
66
67
return addAttribute(Attr, AttrForm, Loc);
68
}
69
70
/// Adds specified block or exprloc attribute to the current DIE.
71
std::pair<DIEValue &, size_t> addBlockAttribute(dwarf::Attribute Attr,
72
dwarf::Form AttrForm,
73
ArrayRef<uint8_t> Bytes) {
74
// The expression location data might be updated and exceed the original
75
// size. Check whether the new data fits into the original form.
76
assert((AttrForm == dwarf::DW_FORM_block) ||
77
(AttrForm == dwarf::DW_FORM_exprloc) ||
78
(AttrForm == dwarf::DW_FORM_block1 && Bytes.size() <= UINT8_MAX) ||
79
(AttrForm == dwarf::DW_FORM_block2 && Bytes.size() <= UINT16_MAX) ||
80
(AttrForm == dwarf::DW_FORM_block4 && Bytes.size() <= UINT32_MAX));
81
82
DIEBlock *Block = new (Allocator) DIEBlock;
83
for (auto Byte : Bytes)
84
static_cast<DIEValueList *>(Block)->addValue(
85
Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
86
DIEInteger(Byte));
87
Block->setSize(Bytes.size());
88
89
return addAttribute(Attr, AttrForm, Block);
90
}
91
92
/// Adds specified location list attribute to the current DIE.
93
std::pair<DIEValue &, size_t> addLocListAttribute(dwarf::Attribute Attr,
94
dwarf::Form AttrForm,
95
uint64_t Value) {
96
return addAttribute(Attr, AttrForm, DIELocList(Value));
97
}
98
99
/// Adds indexed string attribute.
100
std::pair<DIEValue &, size_t> addIndexedStringAttribute(dwarf::Attribute Attr,
101
dwarf::Form AttrForm,
102
uint64_t Idx) {
103
assert(AttrForm == dwarf::DW_FORM_strx);
104
return addAttribute(Attr, AttrForm, DIEInteger(Idx));
105
}
106
107
/// Adds string attribute with dummy offset to the current DIE.
108
std::pair<DIEValue &, size_t>
109
addStringPlaceholderAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm) {
110
assert(AttrForm == dwarf::DW_FORM_strp ||
111
AttrForm == dwarf::DW_FORM_line_strp);
112
return addAttribute(Attr, AttrForm, DIEInteger(0xBADDEF));
113
}
114
115
/// Adds inplace string attribute to the current DIE.
116
std::pair<DIEValue &, size_t> addInplaceString(dwarf::Attribute Attr,
117
StringRef String) {
118
DIEBlock *Block = new (Allocator) DIEBlock;
119
for (auto Byte : String.bytes())
120
static_cast<DIEValueList *>(Block)->addValue(
121
Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
122
DIEInteger(Byte));
123
124
static_cast<DIEValueList *>(Block)->addValue(
125
Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
126
DIEInteger(0));
127
Block->setSize(String.size() + 1);
128
129
DIEValue &ValueRef =
130
*OutputDIE->addValue(Allocator, Attr, dwarf::DW_FORM_string, Block);
131
return std::pair<DIEValue &, size_t>(ValueRef, String.size() + 1);
132
}
133
134
/// Creates appreviations for the current DIE. Returns value of
135
/// abbreviation number. Updates offsets with the size of abbreviation
136
/// number.
137
size_t finalizeAbbreviations(bool CHILDREN_yes,
138
OffsetsPtrVector *OffsetsList) {
139
// Create abbreviations for output DIE.
140
DIEAbbrev NewAbbrev = OutputDIE->generateAbbrev();
141
if (CHILDREN_yes)
142
NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
143
144
CU.assignAbbrev(NewAbbrev);
145
OutputDIE->setAbbrevNumber(NewAbbrev.getNumber());
146
147
size_t AbbrevNumberSize = getULEB128Size(OutputDIE->getAbbrevNumber());
148
149
// Add size of abbreviation number to the offsets.
150
if (OffsetsList != nullptr) {
151
for (uint64_t *OffsetPtr : *OffsetsList)
152
*OffsetPtr += AbbrevNumberSize;
153
}
154
155
return AbbrevNumberSize;
156
}
157
158
protected:
159
template <typename T>
160
std::pair<DIEValue &, size_t> addAttribute(dwarf::Attribute Attr,
161
dwarf::Form AttrForm, T &&Value) {
162
DIEValue &ValueRef =
163
*OutputDIE->addValue(Allocator, Attr, AttrForm, std::forward<T>(Value));
164
unsigned ValueSize = ValueRef.sizeOf(CU.getFormParams());
165
return std::pair<DIEValue &, size_t>(ValueRef, ValueSize);
166
}
167
168
// Allocator for output DIEs and values.
169
BumpPtrAllocator &Allocator;
170
171
// Unit for the output DIE.
172
DwarfUnit &CU;
173
174
// OutputDIE.
175
DIE *OutputDIE = nullptr;
176
};
177
178
} // end of namespace parallel
179
} // end of namespace dwarf_linker
180
} // end of namespace llvm
181
182
#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DIEGENERATOR_H
183
184