LLVM 20.0.0git
DWARFLinkerUnit.cpp
Go to the documentation of this file.
1//===- DWARFLinkerUnit.cpp ------------------------------------------------===//
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#include "DWARFLinkerUnit.h"
10#include "DWARFEmitterImpl.h"
12
13using namespace llvm;
14using namespace dwarf_linker;
15using namespace dwarf_linker::parallel;
16
18 // Check the set for priors.
20 Abbrev.Profile(ID);
21 void *InsertToken;
22
23 DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken);
24 // If it's newly added.
25 if (InSet) {
26 // Assign existing abbreviation number.
27 Abbrev.setNumber(InSet->getNumber());
28 } else {
29 // Add to abbreviation list.
30 Abbreviations.push_back(
31 std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren()));
32 for (const auto &Attr : Abbrev.getData())
33 Abbreviations.back()->AddAttribute(Attr);
34 AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken);
35 // Assign the unique abbreviation number.
36 Abbrev.setNumber(Abbreviations.size());
37 Abbreviations.back()->setNumber(Abbreviations.size());
38 }
39}
40
42 const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs = getAbbreviations();
43 if (Abbrevs.empty())
44 return Error::success();
45
46 SectionDescriptor &AbbrevSection =
47 getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev);
48
49 // For each abbreviation.
50 for (const auto &Abbrev : Abbrevs)
51 emitDwarfAbbrevEntry(*Abbrev, AbbrevSection);
52
53 // Mark end of abbreviations.
54 encodeULEB128(0, AbbrevSection.OS);
55
56 return Error::success();
57}
58
60 SectionDescriptor &AbbrevSection) {
61 // Emit the abbreviations code (base 1 index.)
62 encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS);
63
64 // Emit the abbreviations data.
65 // Emit its Dwarf tag type.
66 encodeULEB128(Abbrev.getTag(), AbbrevSection.OS);
67
68 // Emit whether it has children DIEs.
69 encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS);
70
71 // For each attribute description.
73 for (const DIEAbbrevData &AttrData : Data) {
74 // Emit attribute type.
75 encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS);
76
77 // Emit form type.
78 encodeULEB128(AttrData.getForm(), AbbrevSection.OS);
79
80 // Emit value for DW_FORM_implicit_const.
81 if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
82 encodeSLEB128(AttrData.getValue(), AbbrevSection.OS);
83 }
84
85 // Mark end of abbreviation.
86 encodeULEB128(0, AbbrevSection.OS);
87 encodeULEB128(0, AbbrevSection.OS);
88}
89
91 DIE *OutUnitDIE = getOutUnitDIE();
92 if (OutUnitDIE == nullptr)
93 return Error::success();
94
95 // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs
96 // directly.
97
98 SectionDescriptor &OutSection =
99 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
100 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS);
101 if (Error Err = Emitter.init(TargetTriple, "__DWARF"))
102 return Err;
103
104 // Emit compile unit header.
105 Emitter.emitCompileUnitHeader(*this);
106 size_t OffsetToAbbreviationTableOffset =
107 (getFormParams().Version >= 5) ? 8 : 6;
108 OutSection.notePatch(DebugOffsetPatch{
109 OffsetToAbbreviationTableOffset,
110 &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)});
111
112 // Emit DIEs.
113 Emitter.emitDIE(*OutUnitDIE);
114 Emitter.finish();
115
116 // Set start offset ans size for .debug_info section.
118 return Error::success();
119}
120
122 const DWARFDebugLine::LineTable &OutLineTable) {
123 DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this);
124
125 return DebugLineEmitter.emit(OutLineTable);
126}
127
129 if (getVersion() < 5)
130 return Error::success();
131
132 if (DebugStringIndexMap.empty())
133 return Error::success();
134
135 SectionDescriptor &OutDebugStrOffsetsSection =
136 getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets);
137
138 // Emit section header.
139
140 // Emit length.
141 OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF);
142 uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell();
143
144 // Emit version.
145 OutDebugStrOffsetsSection.emitIntVal(5, 2);
146
147 // Emit padding.
148 OutDebugStrOffsetsSection.emitIntVal(0, 2);
149
150 // Emit index to offset map.
151 for (const StringEntry *String : DebugStringIndexMap.getValues()) {
152 // Note patch for string offset value.
153 OutDebugStrOffsetsSection.notePatch(
154 DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String});
155
156 // Emit placeholder for offset value.
157 OutDebugStrOffsetsSection.emitOffset(0xBADDEF);
158 }
159
160 // Patch section length.
161 OutDebugStrOffsetsSection.apply(
162 OffsetAfterSectionLength -
163 OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(),
164 dwarf::DW_FORM_sec_offset,
165 OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength);
166
167 return Error::success();
168}
169
170/// Emit the pubnames or pubtypes section contribution for \p
171/// Unit into \p Sec. The data is provided in \p Info.
172std::optional<uint64_t>
174 const DwarfUnit::AccelInfo &Info,
175 std::optional<uint64_t> LengthOffset) {
176 if (!LengthOffset) {
177 // Emit the header.
178 OutSection.emitIntVal(0xBADDEF,
179 getFormParams().getDwarfOffsetByteSize()); // Length
180 LengthOffset = OutSection.OS.tell();
181
182 OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version
183
184 OutSection.notePatch(DebugOffsetPatch{
185 OutSection.OS.tell(),
186 &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)});
187 OutSection.emitOffset(0xBADDEF); // Unit offset
188
189 OutSection.emitIntVal(getUnitSize(), 4); // Size
190 }
191 OutSection.emitOffset(Info.OutOffset);
192
193 // Emit the string itself.
194 OutSection.emitInplaceString(Info.String->first());
195
196 return LengthOffset;
197}
198
199/// Emit .debug_pubnames and .debug_pubtypes for \p Unit.
201 std::optional<uint64_t> NamesLengthOffset;
202 std::optional<uint64_t> TypesLengthOffset;
203
204 forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {
205 if (Info.AvoidForPubSections)
206 return;
207
208 switch (Info.Type) {
209 case DwarfUnit::AccelType::Name: {
210 NamesLengthOffset = emitPubAcceleratorEntry(
211 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info,
212 NamesLengthOffset);
213 } break;
214 case DwarfUnit::AccelType::Type: {
215 TypesLengthOffset = emitPubAcceleratorEntry(
216 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info,
217 TypesLengthOffset);
218 } break;
219 default: {
220 // Nothing to do.
221 } break;
222 }
223 });
224
225 if (NamesLengthOffset) {
226 SectionDescriptor &OutSection =
227 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames);
228 OutSection.emitIntVal(0, 4); // End marker.
229
230 OutSection.apply(*NamesLengthOffset -
232 dwarf::DW_FORM_sec_offset,
233 OutSection.OS.tell() - *NamesLengthOffset);
234 }
235
236 if (TypesLengthOffset) {
237 SectionDescriptor &OutSection =
238 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes);
239 OutSection.emitIntVal(0, 4); // End marker.
240
241 OutSection.apply(*TypesLengthOffset -
243 dwarf::DW_FORM_sec_offset,
244 OutSection.OS.tell() - *TypesLengthOffset);
245 }
246}
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
dxil DXContainer Global Emitter
Dwarf abbreviation data, describes one attribute of a Dwarf abbreviation.
Definition: DIE.h:49
Dwarf abbreviation, describes the organization of a debug information object.
Definition: DIE.h:79
unsigned getNumber() const
Definition: DIE.h:101
const SmallVectorImpl< DIEAbbrevData > & getData() const
Definition: DIE.h:103
dwarf::Tag getTag() const
Accessors.
Definition: DIE.h:100
void setNumber(unsigned N)
Definition: DIE.h:105
void Profile(FoldingSetNodeID &ID) const
Used to gather unique data for the abbreviation folding set.
Definition: DIE.cpp:51
bool hasChildren() const
Definition: DIE.h:102
A structured debug information entry.
Definition: DIE.h:819
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:327
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
This class emits specified line table into the .debug_line section.
Error emit(const DWARFDebugLine::LineTable &LineTable)
This class emits DWARF data to the output stream.
void assignAbbrev(DIEAbbrev &Abbrev)
Adds Abbrev into unit`s abbreviation table.
std::optional< uint64_t > emitPubAcceleratorEntry(SectionDescriptor &OutSection, const AccelInfo &Info, std::optional< uint64_t > LengthOffset)
Emit single pubnames/pubtypes accelerator entry.
void emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, SectionDescriptor &AbbrevSection)
Emit single abbreviation entry.
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:147
Error emitDebugInfo(const Triple &TargetTriple)
Emit .debug_info section for unit DIEs.
Error emitDebugStringOffsetSection()
Emit the .debug_str_offsets section for current unit.
void emitPubAccelerators()
Emit .debug_pubnames and .debug_pubtypes for Unit.
Error emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable)
Emit .debug_line section.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:1064
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
Definition: Dwarf.h:63
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition: LEB128.h:23
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:1095
This structure is used to update strings offsets into .debug_str.
This structure keeps fields which would be used for creating accelerator table.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
Definition: DWARFLinker.h:107
This structure is used to keep data of the concrete section.
raw_svector_ostream OS
Stream which stores data to the Contents.
void setSizesForSectionCreatedByAsmPrinter()
Some sections are emitted using AsmPrinter.
void emitUnitLength(uint64_t Length)
Emit unit length into the current section contents.
void emitOffset(uint64_t Val)
Emit specified offset value into the current section contents.
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
void emitInplaceString(StringRef String)
Emit specified inplace string value into the current section contents.