xref: /freebsd/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerUnit.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
1*1db9f3b2SDimitry Andric //===- DWARFLinkerUnit.cpp ------------------------------------------------===//
2*1db9f3b2SDimitry Andric //
3*1db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*1db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*1db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*1db9f3b2SDimitry Andric //
7*1db9f3b2SDimitry Andric //===----------------------------------------------------------------------===//
8*1db9f3b2SDimitry Andric 
9*1db9f3b2SDimitry Andric #include "DWARFLinkerUnit.h"
10*1db9f3b2SDimitry Andric #include "DWARFEmitterImpl.h"
11*1db9f3b2SDimitry Andric #include "DebugLineSectionEmitter.h"
12*1db9f3b2SDimitry Andric 
13*1db9f3b2SDimitry Andric using namespace llvm;
14*1db9f3b2SDimitry Andric using namespace dwarf_linker;
15*1db9f3b2SDimitry Andric using namespace dwarf_linker::parallel;
16*1db9f3b2SDimitry Andric 
17*1db9f3b2SDimitry Andric void DwarfUnit::assignAbbrev(DIEAbbrev &Abbrev) {
18*1db9f3b2SDimitry Andric   // Check the set for priors.
19*1db9f3b2SDimitry Andric   FoldingSetNodeID ID;
20*1db9f3b2SDimitry Andric   Abbrev.Profile(ID);
21*1db9f3b2SDimitry Andric   void *InsertToken;
22*1db9f3b2SDimitry Andric 
23*1db9f3b2SDimitry Andric   DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken);
24*1db9f3b2SDimitry Andric   // If it's newly added.
25*1db9f3b2SDimitry Andric   if (InSet) {
26*1db9f3b2SDimitry Andric     // Assign existing abbreviation number.
27*1db9f3b2SDimitry Andric     Abbrev.setNumber(InSet->getNumber());
28*1db9f3b2SDimitry Andric   } else {
29*1db9f3b2SDimitry Andric     // Add to abbreviation list.
30*1db9f3b2SDimitry Andric     Abbreviations.push_back(
31*1db9f3b2SDimitry Andric         std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren()));
32*1db9f3b2SDimitry Andric     for (const auto &Attr : Abbrev.getData())
33*1db9f3b2SDimitry Andric       Abbreviations.back()->AddAttribute(Attr);
34*1db9f3b2SDimitry Andric     AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken);
35*1db9f3b2SDimitry Andric     // Assign the unique abbreviation number.
36*1db9f3b2SDimitry Andric     Abbrev.setNumber(Abbreviations.size());
37*1db9f3b2SDimitry Andric     Abbreviations.back()->setNumber(Abbreviations.size());
38*1db9f3b2SDimitry Andric   }
39*1db9f3b2SDimitry Andric }
40*1db9f3b2SDimitry Andric 
41*1db9f3b2SDimitry Andric Error DwarfUnit::emitAbbreviations() {
42*1db9f3b2SDimitry Andric   const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs = getAbbreviations();
43*1db9f3b2SDimitry Andric   if (Abbrevs.empty())
44*1db9f3b2SDimitry Andric     return Error::success();
45*1db9f3b2SDimitry Andric 
46*1db9f3b2SDimitry Andric   SectionDescriptor &AbbrevSection =
47*1db9f3b2SDimitry Andric       getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev);
48*1db9f3b2SDimitry Andric 
49*1db9f3b2SDimitry Andric   // For each abbreviation.
50*1db9f3b2SDimitry Andric   for (const auto &Abbrev : Abbrevs)
51*1db9f3b2SDimitry Andric     emitDwarfAbbrevEntry(*Abbrev, AbbrevSection);
52*1db9f3b2SDimitry Andric 
53*1db9f3b2SDimitry Andric   // Mark end of abbreviations.
54*1db9f3b2SDimitry Andric   encodeULEB128(0, AbbrevSection.OS);
55*1db9f3b2SDimitry Andric 
56*1db9f3b2SDimitry Andric   return Error::success();
57*1db9f3b2SDimitry Andric }
58*1db9f3b2SDimitry Andric 
59*1db9f3b2SDimitry Andric void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev,
60*1db9f3b2SDimitry Andric                                      SectionDescriptor &AbbrevSection) {
61*1db9f3b2SDimitry Andric   // Emit the abbreviations code (base 1 index.)
62*1db9f3b2SDimitry Andric   encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS);
63*1db9f3b2SDimitry Andric 
64*1db9f3b2SDimitry Andric   // Emit the abbreviations data.
65*1db9f3b2SDimitry Andric   // Emit its Dwarf tag type.
66*1db9f3b2SDimitry Andric   encodeULEB128(Abbrev.getTag(), AbbrevSection.OS);
67*1db9f3b2SDimitry Andric 
68*1db9f3b2SDimitry Andric   // Emit whether it has children DIEs.
69*1db9f3b2SDimitry Andric   encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS);
70*1db9f3b2SDimitry Andric 
71*1db9f3b2SDimitry Andric   // For each attribute description.
72*1db9f3b2SDimitry Andric   const SmallVectorImpl<DIEAbbrevData> &Data = Abbrev.getData();
73*1db9f3b2SDimitry Andric   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
74*1db9f3b2SDimitry Andric     const DIEAbbrevData &AttrData = Data[i];
75*1db9f3b2SDimitry Andric 
76*1db9f3b2SDimitry Andric     // Emit attribute type.
77*1db9f3b2SDimitry Andric     encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS);
78*1db9f3b2SDimitry Andric 
79*1db9f3b2SDimitry Andric     // Emit form type.
80*1db9f3b2SDimitry Andric     encodeULEB128(AttrData.getForm(), AbbrevSection.OS);
81*1db9f3b2SDimitry Andric 
82*1db9f3b2SDimitry Andric     // Emit value for DW_FORM_implicit_const.
83*1db9f3b2SDimitry Andric     if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
84*1db9f3b2SDimitry Andric       encodeSLEB128(AttrData.getValue(), AbbrevSection.OS);
85*1db9f3b2SDimitry Andric   }
86*1db9f3b2SDimitry Andric 
87*1db9f3b2SDimitry Andric   // Mark end of abbreviation.
88*1db9f3b2SDimitry Andric   encodeULEB128(0, AbbrevSection.OS);
89*1db9f3b2SDimitry Andric   encodeULEB128(0, AbbrevSection.OS);
90*1db9f3b2SDimitry Andric }
91*1db9f3b2SDimitry Andric 
92*1db9f3b2SDimitry Andric Error DwarfUnit::emitDebugInfo(const Triple &TargetTriple) {
93*1db9f3b2SDimitry Andric   DIE *OutUnitDIE = getOutUnitDIE();
94*1db9f3b2SDimitry Andric   if (OutUnitDIE == nullptr)
95*1db9f3b2SDimitry Andric     return Error::success();
96*1db9f3b2SDimitry Andric 
97*1db9f3b2SDimitry Andric   // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs
98*1db9f3b2SDimitry Andric   // directly.
99*1db9f3b2SDimitry Andric 
100*1db9f3b2SDimitry Andric   SectionDescriptor &OutSection =
101*1db9f3b2SDimitry Andric       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
102*1db9f3b2SDimitry Andric   DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS);
103*1db9f3b2SDimitry Andric   if (Error Err = Emitter.init(TargetTriple, "__DWARF"))
104*1db9f3b2SDimitry Andric     return Err;
105*1db9f3b2SDimitry Andric 
106*1db9f3b2SDimitry Andric   // Emit compile unit header.
107*1db9f3b2SDimitry Andric   Emitter.emitCompileUnitHeader(*this);
108*1db9f3b2SDimitry Andric   size_t OffsetToAbbreviationTableOffset =
109*1db9f3b2SDimitry Andric       (getFormParams().Version >= 5) ? 8 : 6;
110*1db9f3b2SDimitry Andric   OutSection.notePatch(DebugOffsetPatch{
111*1db9f3b2SDimitry Andric       OffsetToAbbreviationTableOffset,
112*1db9f3b2SDimitry Andric       &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)});
113*1db9f3b2SDimitry Andric 
114*1db9f3b2SDimitry Andric   // Emit DIEs.
115*1db9f3b2SDimitry Andric   Emitter.emitDIE(*OutUnitDIE);
116*1db9f3b2SDimitry Andric   Emitter.finish();
117*1db9f3b2SDimitry Andric 
118*1db9f3b2SDimitry Andric   // Set start offset ans size for .debug_info section.
119*1db9f3b2SDimitry Andric   OutSection.setSizesForSectionCreatedByAsmPrinter();
120*1db9f3b2SDimitry Andric   return Error::success();
121*1db9f3b2SDimitry Andric }
122*1db9f3b2SDimitry Andric 
123*1db9f3b2SDimitry Andric Error DwarfUnit::emitDebugLine(const Triple &TargetTriple,
124*1db9f3b2SDimitry Andric                                const DWARFDebugLine::LineTable &OutLineTable) {
125*1db9f3b2SDimitry Andric   DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this);
126*1db9f3b2SDimitry Andric 
127*1db9f3b2SDimitry Andric   return DebugLineEmitter.emit(OutLineTable);
128*1db9f3b2SDimitry Andric }
129*1db9f3b2SDimitry Andric 
130*1db9f3b2SDimitry Andric Error DwarfUnit::emitDebugStringOffsetSection() {
131*1db9f3b2SDimitry Andric   if (getVersion() < 5)
132*1db9f3b2SDimitry Andric     return Error::success();
133*1db9f3b2SDimitry Andric 
134*1db9f3b2SDimitry Andric   if (DebugStringIndexMap.empty())
135*1db9f3b2SDimitry Andric     return Error::success();
136*1db9f3b2SDimitry Andric 
137*1db9f3b2SDimitry Andric   SectionDescriptor &OutDebugStrOffsetsSection =
138*1db9f3b2SDimitry Andric       getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets);
139*1db9f3b2SDimitry Andric 
140*1db9f3b2SDimitry Andric   // Emit section header.
141*1db9f3b2SDimitry Andric 
142*1db9f3b2SDimitry Andric   //   Emit length.
143*1db9f3b2SDimitry Andric   OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF);
144*1db9f3b2SDimitry Andric   uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell();
145*1db9f3b2SDimitry Andric 
146*1db9f3b2SDimitry Andric   //   Emit version.
147*1db9f3b2SDimitry Andric   OutDebugStrOffsetsSection.emitIntVal(5, 2);
148*1db9f3b2SDimitry Andric 
149*1db9f3b2SDimitry Andric   //   Emit padding.
150*1db9f3b2SDimitry Andric   OutDebugStrOffsetsSection.emitIntVal(0, 2);
151*1db9f3b2SDimitry Andric 
152*1db9f3b2SDimitry Andric   //   Emit index to offset map.
153*1db9f3b2SDimitry Andric   for (const StringEntry *String : DebugStringIndexMap.getValues()) {
154*1db9f3b2SDimitry Andric     // Note patch for string offset value.
155*1db9f3b2SDimitry Andric     OutDebugStrOffsetsSection.notePatch(
156*1db9f3b2SDimitry Andric         DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String});
157*1db9f3b2SDimitry Andric 
158*1db9f3b2SDimitry Andric     // Emit placeholder for offset value.
159*1db9f3b2SDimitry Andric     OutDebugStrOffsetsSection.emitOffset(0xBADDEF);
160*1db9f3b2SDimitry Andric   }
161*1db9f3b2SDimitry Andric 
162*1db9f3b2SDimitry Andric   // Patch section length.
163*1db9f3b2SDimitry Andric   OutDebugStrOffsetsSection.apply(
164*1db9f3b2SDimitry Andric       OffsetAfterSectionLength -
165*1db9f3b2SDimitry Andric           OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(),
166*1db9f3b2SDimitry Andric       dwarf::DW_FORM_sec_offset,
167*1db9f3b2SDimitry Andric       OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength);
168*1db9f3b2SDimitry Andric 
169*1db9f3b2SDimitry Andric   return Error::success();
170*1db9f3b2SDimitry Andric }
171*1db9f3b2SDimitry Andric 
172*1db9f3b2SDimitry Andric /// Emit the pubnames or pubtypes section contribution for \p
173*1db9f3b2SDimitry Andric /// Unit into \p Sec. The data is provided in \p Info.
174*1db9f3b2SDimitry Andric std::optional<uint64_t>
175*1db9f3b2SDimitry Andric DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor &OutSection,
176*1db9f3b2SDimitry Andric                                    const DwarfUnit::AccelInfo &Info,
177*1db9f3b2SDimitry Andric                                    std::optional<uint64_t> LengthOffset) {
178*1db9f3b2SDimitry Andric   if (!LengthOffset) {
179*1db9f3b2SDimitry Andric     // Emit the header.
180*1db9f3b2SDimitry Andric     OutSection.emitIntVal(0xBADDEF,
181*1db9f3b2SDimitry Andric                           getFormParams().getDwarfOffsetByteSize()); // Length
182*1db9f3b2SDimitry Andric     LengthOffset = OutSection.OS.tell();
183*1db9f3b2SDimitry Andric 
184*1db9f3b2SDimitry Andric     OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version
185*1db9f3b2SDimitry Andric 
186*1db9f3b2SDimitry Andric     OutSection.notePatch(DebugOffsetPatch{
187*1db9f3b2SDimitry Andric         OutSection.OS.tell(),
188*1db9f3b2SDimitry Andric         &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)});
189*1db9f3b2SDimitry Andric     OutSection.emitOffset(0xBADDEF); // Unit offset
190*1db9f3b2SDimitry Andric 
191*1db9f3b2SDimitry Andric     OutSection.emitIntVal(getUnitSize(), 4); // Size
192*1db9f3b2SDimitry Andric   }
193*1db9f3b2SDimitry Andric   OutSection.emitOffset(Info.OutOffset);
194*1db9f3b2SDimitry Andric 
195*1db9f3b2SDimitry Andric   // Emit the string itself.
196*1db9f3b2SDimitry Andric   OutSection.emitInplaceString(Info.String->first());
197*1db9f3b2SDimitry Andric 
198*1db9f3b2SDimitry Andric   return LengthOffset;
199*1db9f3b2SDimitry Andric }
200*1db9f3b2SDimitry Andric 
201*1db9f3b2SDimitry Andric /// Emit .debug_pubnames and .debug_pubtypes for \p Unit.
202*1db9f3b2SDimitry Andric void DwarfUnit::emitPubAccelerators() {
203*1db9f3b2SDimitry Andric   std::optional<uint64_t> NamesLengthOffset;
204*1db9f3b2SDimitry Andric   std::optional<uint64_t> TypesLengthOffset;
205*1db9f3b2SDimitry Andric 
206*1db9f3b2SDimitry Andric   forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {
207*1db9f3b2SDimitry Andric     if (Info.AvoidForPubSections)
208*1db9f3b2SDimitry Andric       return;
209*1db9f3b2SDimitry Andric 
210*1db9f3b2SDimitry Andric     switch (Info.Type) {
211*1db9f3b2SDimitry Andric     case DwarfUnit::AccelType::Name: {
212*1db9f3b2SDimitry Andric       NamesLengthOffset = emitPubAcceleratorEntry(
213*1db9f3b2SDimitry Andric           getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info,
214*1db9f3b2SDimitry Andric           NamesLengthOffset);
215*1db9f3b2SDimitry Andric     } break;
216*1db9f3b2SDimitry Andric     case DwarfUnit::AccelType::Type: {
217*1db9f3b2SDimitry Andric       TypesLengthOffset = emitPubAcceleratorEntry(
218*1db9f3b2SDimitry Andric           getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info,
219*1db9f3b2SDimitry Andric           TypesLengthOffset);
220*1db9f3b2SDimitry Andric     } break;
221*1db9f3b2SDimitry Andric     default: {
222*1db9f3b2SDimitry Andric       // Nothing to do.
223*1db9f3b2SDimitry Andric     } break;
224*1db9f3b2SDimitry Andric     }
225*1db9f3b2SDimitry Andric   });
226*1db9f3b2SDimitry Andric 
227*1db9f3b2SDimitry Andric   if (NamesLengthOffset) {
228*1db9f3b2SDimitry Andric     SectionDescriptor &OutSection =
229*1db9f3b2SDimitry Andric         getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames);
230*1db9f3b2SDimitry Andric     OutSection.emitIntVal(0, 4); // End marker.
231*1db9f3b2SDimitry Andric 
232*1db9f3b2SDimitry Andric     OutSection.apply(*NamesLengthOffset -
233*1db9f3b2SDimitry Andric                          OutSection.getFormParams().getDwarfOffsetByteSize(),
234*1db9f3b2SDimitry Andric                      dwarf::DW_FORM_sec_offset,
235*1db9f3b2SDimitry Andric                      OutSection.OS.tell() - *NamesLengthOffset);
236*1db9f3b2SDimitry Andric   }
237*1db9f3b2SDimitry Andric 
238*1db9f3b2SDimitry Andric   if (TypesLengthOffset) {
239*1db9f3b2SDimitry Andric     SectionDescriptor &OutSection =
240*1db9f3b2SDimitry Andric         getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes);
241*1db9f3b2SDimitry Andric     OutSection.emitIntVal(0, 4); // End marker.
242*1db9f3b2SDimitry Andric 
243*1db9f3b2SDimitry Andric     OutSection.apply(*TypesLengthOffset -
244*1db9f3b2SDimitry Andric                          OutSection.getFormParams().getDwarfOffsetByteSize(),
245*1db9f3b2SDimitry Andric                      dwarf::DW_FORM_sec_offset,
246*1db9f3b2SDimitry Andric                      OutSection.OS.tell() - *TypesLengthOffset);
247*1db9f3b2SDimitry Andric   }
248*1db9f3b2SDimitry Andric }
249