1 //===- DWARFLinkerUnit.cpp ------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "DWARFLinkerUnit.h"
10 #include "DWARFEmitterImpl.h"
11 #include "DebugLineSectionEmitter.h"
14 using namespace dwarf_linker
;
15 using namespace dwarf_linker::parallel
;
17 void DwarfUnit::assignAbbrev(DIEAbbrev
&Abbrev
) {
18 // Check the set for priors.
23 DIEAbbrev
*InSet
= AbbreviationsSet
.FindNodeOrInsertPos(ID
, InsertToken
);
24 // If it's newly added.
26 // Assign existing abbreviation number.
27 Abbrev
.setNumber(InSet
->getNumber());
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());
41 Error
DwarfUnit::emitAbbreviations() {
42 const std::vector
<std::unique_ptr
<DIEAbbrev
>> &Abbrevs
= getAbbreviations();
44 return Error::success();
46 SectionDescriptor
&AbbrevSection
=
47 getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev
);
49 // For each abbreviation.
50 for (const auto &Abbrev
: Abbrevs
)
51 emitDwarfAbbrevEntry(*Abbrev
, AbbrevSection
);
53 // Mark end of abbreviations.
54 encodeULEB128(0, AbbrevSection
.OS
);
56 return Error::success();
59 void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev
&Abbrev
,
60 SectionDescriptor
&AbbrevSection
) {
61 // Emit the abbreviations code (base 1 index.)
62 encodeULEB128(Abbrev
.getNumber(), AbbrevSection
.OS
);
64 // Emit the abbreviations data.
65 // Emit its Dwarf tag type.
66 encodeULEB128(Abbrev
.getTag(), AbbrevSection
.OS
);
68 // Emit whether it has children DIEs.
69 encodeULEB128((unsigned)Abbrev
.hasChildren(), AbbrevSection
.OS
);
71 // For each attribute description.
72 const SmallVectorImpl
<DIEAbbrevData
> &Data
= Abbrev
.getData();
73 for (const DIEAbbrevData
&AttrData
: Data
) {
74 // Emit attribute type.
75 encodeULEB128(AttrData
.getAttribute(), AbbrevSection
.OS
);
78 encodeULEB128(AttrData
.getForm(), AbbrevSection
.OS
);
80 // Emit value for DW_FORM_implicit_const.
81 if (AttrData
.getForm() == dwarf::DW_FORM_implicit_const
)
82 encodeSLEB128(AttrData
.getValue(), AbbrevSection
.OS
);
85 // Mark end of abbreviation.
86 encodeULEB128(0, AbbrevSection
.OS
);
87 encodeULEB128(0, AbbrevSection
.OS
);
90 Error
DwarfUnit::emitDebugInfo(const Triple
&TargetTriple
) {
91 DIE
*OutUnitDIE
= getOutUnitDIE();
92 if (OutUnitDIE
== nullptr)
93 return Error::success();
95 // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs
98 SectionDescriptor
&OutSection
=
99 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
100 DwarfEmitterImpl
Emitter(DWARFLinker::OutputFileType::Object
, OutSection
.OS
);
101 if (Error Err
= Emitter
.init(TargetTriple
, "__DWARF"))
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
)});
113 Emitter
.emitDIE(*OutUnitDIE
);
116 // Set start offset ans size for .debug_info section.
117 OutSection
.setSizesForSectionCreatedByAsmPrinter();
118 return Error::success();
121 Error
DwarfUnit::emitDebugLine(const Triple
&TargetTriple
,
122 const DWARFDebugLine::LineTable
&OutLineTable
) {
123 DebugLineSectionEmitter
DebugLineEmitter(TargetTriple
, *this);
125 return DebugLineEmitter
.emit(OutLineTable
);
128 Error
DwarfUnit::emitDebugStringOffsetSection() {
129 if (getVersion() < 5)
130 return Error::success();
132 if (DebugStringIndexMap
.empty())
133 return Error::success();
135 SectionDescriptor
&OutDebugStrOffsetsSection
=
136 getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets
);
138 // Emit section header.
141 OutDebugStrOffsetsSection
.emitUnitLength(0xBADDEF);
142 uint64_t OffsetAfterSectionLength
= OutDebugStrOffsetsSection
.OS
.tell();
145 OutDebugStrOffsetsSection
.emitIntVal(5, 2);
148 OutDebugStrOffsetsSection
.emitIntVal(0, 2);
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
});
156 // Emit placeholder for offset value.
157 OutDebugStrOffsetsSection
.emitOffset(0xBADDEF);
160 // Patch section length.
161 OutDebugStrOffsetsSection
.apply(
162 OffsetAfterSectionLength
-
163 OutDebugStrOffsetsSection
.getFormParams().getDwarfOffsetByteSize(),
164 dwarf::DW_FORM_sec_offset
,
165 OutDebugStrOffsetsSection
.OS
.tell() - OffsetAfterSectionLength
);
167 return Error::success();
170 /// Emit the pubnames or pubtypes section contribution for \p
171 /// Unit into \p Sec. The data is provided in \p Info.
172 std::optional
<uint64_t>
173 DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor
&OutSection
,
174 const DwarfUnit::AccelInfo
&Info
,
175 std::optional
<uint64_t> LengthOffset
) {
178 OutSection
.emitIntVal(0xBADDEF,
179 getFormParams().getDwarfOffsetByteSize()); // Length
180 LengthOffset
= OutSection
.OS
.tell();
182 OutSection
.emitIntVal(dwarf::DW_PUBNAMES_VERSION
, 2); // Version
184 OutSection
.notePatch(DebugOffsetPatch
{
185 OutSection
.OS
.tell(),
186 &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
)});
187 OutSection
.emitOffset(0xBADDEF); // Unit offset
189 OutSection
.emitIntVal(getUnitSize(), 4); // Size
191 OutSection
.emitOffset(Info
.OutOffset
);
193 // Emit the string itself.
194 OutSection
.emitInplaceString(Info
.String
->first());
199 /// Emit .debug_pubnames and .debug_pubtypes for \p Unit.
200 void DwarfUnit::emitPubAccelerators() {
201 std::optional
<uint64_t> NamesLengthOffset
;
202 std::optional
<uint64_t> TypesLengthOffset
;
204 forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo
&Info
) {
205 if (Info
.AvoidForPubSections
)
209 case DwarfUnit::AccelType::Name
: {
210 NamesLengthOffset
= emitPubAcceleratorEntry(
211 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames
), Info
,
214 case DwarfUnit::AccelType::Type
: {
215 TypesLengthOffset
= emitPubAcceleratorEntry(
216 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes
), Info
,
225 if (NamesLengthOffset
) {
226 SectionDescriptor
&OutSection
=
227 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames
);
228 OutSection
.emitIntVal(0, 4); // End marker.
230 OutSection
.apply(*NamesLengthOffset
-
231 OutSection
.getFormParams().getDwarfOffsetByteSize(),
232 dwarf::DW_FORM_sec_offset
,
233 OutSection
.OS
.tell() - *NamesLengthOffset
);
236 if (TypesLengthOffset
) {
237 SectionDescriptor
&OutSection
=
238 getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes
);
239 OutSection
.emitIntVal(0, 4); // End marker.
241 OutSection
.apply(*TypesLengthOffset
-
242 OutSection
.getFormParams().getDwarfOffsetByteSize(),
243 dwarf::DW_FORM_sec_offset
,
244 OutSection
.OS
.tell() - *TypesLengthOffset
);