xref: /freebsd/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
1*1db9f3b2SDimitry Andric //===- DWARFEmitterImpl.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 "DWARFEmitterImpl.h"
10*1db9f3b2SDimitry Andric #include "DWARFLinkerCompileUnit.h"
11*1db9f3b2SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
12*1db9f3b2SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
13*1db9f3b2SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
14*1db9f3b2SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
15*1db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
16*1db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptionsCommandFlags.h"
17*1db9f3b2SDimitry Andric #include "llvm/MC/TargetRegistry.h"
18*1db9f3b2SDimitry Andric #include "llvm/Support/FormattedStream.h"
19*1db9f3b2SDimitry Andric 
20*1db9f3b2SDimitry Andric using namespace llvm;
21*1db9f3b2SDimitry Andric using namespace dwarf_linker;
22*1db9f3b2SDimitry Andric using namespace dwarf_linker::parallel;
23*1db9f3b2SDimitry Andric 
24*1db9f3b2SDimitry Andric Error DwarfEmitterImpl::init(Triple TheTriple,
25*1db9f3b2SDimitry Andric                              StringRef Swift5ReflectionSegmentName) {
26*1db9f3b2SDimitry Andric   std::string ErrorStr;
27*1db9f3b2SDimitry Andric   std::string TripleName;
28*1db9f3b2SDimitry Andric 
29*1db9f3b2SDimitry Andric   // Get the target.
30*1db9f3b2SDimitry Andric   const Target *TheTarget =
31*1db9f3b2SDimitry Andric       TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
32*1db9f3b2SDimitry Andric   if (!TheTarget)
33*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument, ErrorStr.c_str());
34*1db9f3b2SDimitry Andric   TripleName = TheTriple.getTriple();
35*1db9f3b2SDimitry Andric 
36*1db9f3b2SDimitry Andric   // Create all the MC Objects.
37*1db9f3b2SDimitry Andric   MRI.reset(TheTarget->createMCRegInfo(TripleName));
38*1db9f3b2SDimitry Andric   if (!MRI)
39*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
40*1db9f3b2SDimitry Andric                              "no register info for target %s",
41*1db9f3b2SDimitry Andric                              TripleName.c_str());
42*1db9f3b2SDimitry Andric 
43*1db9f3b2SDimitry Andric   MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
44*1db9f3b2SDimitry Andric   MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
45*1db9f3b2SDimitry Andric   if (!MAI)
46*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
47*1db9f3b2SDimitry Andric                              "no asm info for target %s", TripleName.c_str());
48*1db9f3b2SDimitry Andric 
49*1db9f3b2SDimitry Andric   MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
50*1db9f3b2SDimitry Andric   if (!MSTI)
51*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
52*1db9f3b2SDimitry Andric                              "no subtarget info for target %s",
53*1db9f3b2SDimitry Andric                              TripleName.c_str());
54*1db9f3b2SDimitry Andric 
55*1db9f3b2SDimitry Andric   MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,
56*1db9f3b2SDimitry Andric                          nullptr, true, Swift5ReflectionSegmentName));
57*1db9f3b2SDimitry Andric   MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false));
58*1db9f3b2SDimitry Andric   MC->setObjectFileInfo(MOFI.get());
59*1db9f3b2SDimitry Andric 
60*1db9f3b2SDimitry Andric   MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
61*1db9f3b2SDimitry Andric   if (!MAB)
62*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
63*1db9f3b2SDimitry Andric                              "no asm backend for target %s",
64*1db9f3b2SDimitry Andric                              TripleName.c_str());
65*1db9f3b2SDimitry Andric 
66*1db9f3b2SDimitry Andric   MII.reset(TheTarget->createMCInstrInfo());
67*1db9f3b2SDimitry Andric   if (!MII)
68*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
69*1db9f3b2SDimitry Andric                              "no instr info info for target %s",
70*1db9f3b2SDimitry Andric                              TripleName.c_str());
71*1db9f3b2SDimitry Andric 
72*1db9f3b2SDimitry Andric   MCE = TheTarget->createMCCodeEmitter(*MII, *MC);
73*1db9f3b2SDimitry Andric   if (!MCE)
74*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
75*1db9f3b2SDimitry Andric                              "no code emitter for target %s",
76*1db9f3b2SDimitry Andric                              TripleName.c_str());
77*1db9f3b2SDimitry Andric 
78*1db9f3b2SDimitry Andric   switch (OutFileType) {
79*1db9f3b2SDimitry Andric   case DWARFLinker::OutputFileType::Assembly: {
80*1db9f3b2SDimitry Andric     MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),
81*1db9f3b2SDimitry Andric                                          *MAI, *MII, *MRI);
82*1db9f3b2SDimitry Andric     MS = TheTarget->createAsmStreamer(
83*1db9f3b2SDimitry Andric         *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP,
84*1db9f3b2SDimitry Andric         std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
85*1db9f3b2SDimitry Andric         true);
86*1db9f3b2SDimitry Andric     break;
87*1db9f3b2SDimitry Andric   }
88*1db9f3b2SDimitry Andric   case DWARFLinker::OutputFileType::Object: {
89*1db9f3b2SDimitry Andric     MS = TheTarget->createMCObjectStreamer(
90*1db9f3b2SDimitry Andric         TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
91*1db9f3b2SDimitry Andric         MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),
92*1db9f3b2SDimitry Andric         *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
93*1db9f3b2SDimitry Andric         /*DWARFMustBeAtTheEnd*/ false);
94*1db9f3b2SDimitry Andric     break;
95*1db9f3b2SDimitry Andric   }
96*1db9f3b2SDimitry Andric   }
97*1db9f3b2SDimitry Andric 
98*1db9f3b2SDimitry Andric   if (!MS)
99*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
100*1db9f3b2SDimitry Andric                              "no object streamer for target %s",
101*1db9f3b2SDimitry Andric                              TripleName.c_str());
102*1db9f3b2SDimitry Andric 
103*1db9f3b2SDimitry Andric   // Finally create the AsmPrinter we'll use to emit the DIEs.
104*1db9f3b2SDimitry Andric   TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
105*1db9f3b2SDimitry Andric                                           std::nullopt));
106*1db9f3b2SDimitry Andric   if (!TM)
107*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
108*1db9f3b2SDimitry Andric                              "no target machine for target %s",
109*1db9f3b2SDimitry Andric                              TripleName.c_str());
110*1db9f3b2SDimitry Andric 
111*1db9f3b2SDimitry Andric   Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
112*1db9f3b2SDimitry Andric   if (!Asm)
113*1db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
114*1db9f3b2SDimitry Andric                              "no asm printer for target %s",
115*1db9f3b2SDimitry Andric                              TripleName.c_str());
116*1db9f3b2SDimitry Andric   Asm->setDwarfUsesRelocationsAcrossSections(false);
117*1db9f3b2SDimitry Andric 
118*1db9f3b2SDimitry Andric   DebugInfoSectionSize = 0;
119*1db9f3b2SDimitry Andric 
120*1db9f3b2SDimitry Andric   return Error::success();
121*1db9f3b2SDimitry Andric }
122*1db9f3b2SDimitry Andric 
123*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitSwiftAST(StringRef Buffer) {
124*1db9f3b2SDimitry Andric   MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
125*1db9f3b2SDimitry Andric   SwiftASTSection->setAlignment(Align(32));
126*1db9f3b2SDimitry Andric   MS->switchSection(SwiftASTSection);
127*1db9f3b2SDimitry Andric   MS->emitBytes(Buffer);
128*1db9f3b2SDimitry Andric }
129*1db9f3b2SDimitry Andric 
130*1db9f3b2SDimitry Andric /// Emit the swift reflection section stored in \p Buffer.
131*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitSwiftReflectionSection(
132*1db9f3b2SDimitry Andric     llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
133*1db9f3b2SDimitry Andric     StringRef Buffer, uint32_t Alignment, uint32_t) {
134*1db9f3b2SDimitry Andric   MCSection *ReflectionSection =
135*1db9f3b2SDimitry Andric       MOFI->getSwift5ReflectionSection(ReflSectionKind);
136*1db9f3b2SDimitry Andric   if (ReflectionSection == nullptr)
137*1db9f3b2SDimitry Andric     return;
138*1db9f3b2SDimitry Andric   ReflectionSection->setAlignment(Align(Alignment));
139*1db9f3b2SDimitry Andric   MS->switchSection(ReflectionSection);
140*1db9f3b2SDimitry Andric   MS->emitBytes(Buffer);
141*1db9f3b2SDimitry Andric }
142*1db9f3b2SDimitry Andric 
143*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitSectionContents(StringRef SecData,
144*1db9f3b2SDimitry Andric                                            StringRef SecName) {
145*1db9f3b2SDimitry Andric   if (SecData.empty())
146*1db9f3b2SDimitry Andric     return;
147*1db9f3b2SDimitry Andric 
148*1db9f3b2SDimitry Andric   if (MCSection *Section = switchSection(SecName)) {
149*1db9f3b2SDimitry Andric     MS->switchSection(Section);
150*1db9f3b2SDimitry Andric 
151*1db9f3b2SDimitry Andric     MS->emitBytes(SecData);
152*1db9f3b2SDimitry Andric   }
153*1db9f3b2SDimitry Andric }
154*1db9f3b2SDimitry Andric 
155*1db9f3b2SDimitry Andric MCSection *DwarfEmitterImpl::switchSection(StringRef SecName) {
156*1db9f3b2SDimitry Andric   return StringSwitch<MCSection *>(SecName)
157*1db9f3b2SDimitry Andric       .Case("debug_info", MC->getObjectFileInfo()->getDwarfInfoSection())
158*1db9f3b2SDimitry Andric       .Case("debug_abbrev", MC->getObjectFileInfo()->getDwarfAbbrevSection())
159*1db9f3b2SDimitry Andric       .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
160*1db9f3b2SDimitry Andric       .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
161*1db9f3b2SDimitry Andric       .Case("debug_ranges", MC->getObjectFileInfo()->getDwarfRangesSection())
162*1db9f3b2SDimitry Andric       .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
163*1db9f3b2SDimitry Andric       .Case("debug_aranges", MC->getObjectFileInfo()->getDwarfARangesSection())
164*1db9f3b2SDimitry Andric       .Case("debug_rnglists",
165*1db9f3b2SDimitry Andric             MC->getObjectFileInfo()->getDwarfRnglistsSection())
166*1db9f3b2SDimitry Andric       .Case("debug_loclists",
167*1db9f3b2SDimitry Andric             MC->getObjectFileInfo()->getDwarfLoclistsSection())
168*1db9f3b2SDimitry Andric       .Case("debug_macro", MC->getObjectFileInfo()->getDwarfMacroSection())
169*1db9f3b2SDimitry Andric       .Case("debug_macinfo", MC->getObjectFileInfo()->getDwarfMacinfoSection())
170*1db9f3b2SDimitry Andric       .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
171*1db9f3b2SDimitry Andric       .Case("debug_str", MC->getObjectFileInfo()->getDwarfStrSection())
172*1db9f3b2SDimitry Andric       .Case("debug_line_str", MC->getObjectFileInfo()->getDwarfLineStrSection())
173*1db9f3b2SDimitry Andric       .Case("debug_str_offsets",
174*1db9f3b2SDimitry Andric             MC->getObjectFileInfo()->getDwarfStrOffSection())
175*1db9f3b2SDimitry Andric       .Case("debug_pubnames",
176*1db9f3b2SDimitry Andric             MC->getObjectFileInfo()->getDwarfPubNamesSection())
177*1db9f3b2SDimitry Andric       .Case("debug_pubtypes",
178*1db9f3b2SDimitry Andric             MC->getObjectFileInfo()->getDwarfPubTypesSection())
179*1db9f3b2SDimitry Andric       .Case("debug_names", MC->getObjectFileInfo()->getDwarfDebugNamesSection())
180*1db9f3b2SDimitry Andric       .Case("apple_names", MC->getObjectFileInfo()->getDwarfAccelNamesSection())
181*1db9f3b2SDimitry Andric       .Case("apple_namespac",
182*1db9f3b2SDimitry Andric             MC->getObjectFileInfo()->getDwarfAccelNamespaceSection())
183*1db9f3b2SDimitry Andric       .Case("apple_objc", MC->getObjectFileInfo()->getDwarfAccelObjCSection())
184*1db9f3b2SDimitry Andric       .Case("apple_types", MC->getObjectFileInfo()->getDwarfAccelTypesSection())
185*1db9f3b2SDimitry Andric 
186*1db9f3b2SDimitry Andric       .Default(nullptr);
187*1db9f3b2SDimitry Andric }
188*1db9f3b2SDimitry Andric 
189*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitAbbrevs(
190*1db9f3b2SDimitry Andric     const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
191*1db9f3b2SDimitry Andric     unsigned DwarfVersion) {
192*1db9f3b2SDimitry Andric   MS->switchSection(MOFI->getDwarfAbbrevSection());
193*1db9f3b2SDimitry Andric   MC->setDwarfVersion(DwarfVersion);
194*1db9f3b2SDimitry Andric   Asm->emitDwarfAbbrevs(Abbrevs);
195*1db9f3b2SDimitry Andric }
196*1db9f3b2SDimitry Andric 
197*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitCompileUnitHeader(DwarfUnit &Unit) {
198*1db9f3b2SDimitry Andric   MS->switchSection(MOFI->getDwarfInfoSection());
199*1db9f3b2SDimitry Andric   MC->setDwarfVersion(Unit.getVersion());
200*1db9f3b2SDimitry Andric 
201*1db9f3b2SDimitry Andric   // Emit size of content not including length itself. The size has already
202*1db9f3b2SDimitry Andric   // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
203*1db9f3b2SDimitry Andric   // account for the length field.
204*1db9f3b2SDimitry Andric   Asm->emitInt32(Unit.getUnitSize() - 4);
205*1db9f3b2SDimitry Andric   Asm->emitInt16(Unit.getVersion());
206*1db9f3b2SDimitry Andric 
207*1db9f3b2SDimitry Andric   if (Unit.getVersion() >= 5) {
208*1db9f3b2SDimitry Andric     Asm->emitInt8(dwarf::DW_UT_compile);
209*1db9f3b2SDimitry Andric     Asm->emitInt8(Unit.getFormParams().AddrSize);
210*1db9f3b2SDimitry Andric     // Proper offset to the abbreviations table will be set later.
211*1db9f3b2SDimitry Andric     Asm->emitInt32(0);
212*1db9f3b2SDimitry Andric     DebugInfoSectionSize += 12;
213*1db9f3b2SDimitry Andric   } else {
214*1db9f3b2SDimitry Andric     // Proper offset to the abbreviations table will be set later.
215*1db9f3b2SDimitry Andric     Asm->emitInt32(0);
216*1db9f3b2SDimitry Andric     Asm->emitInt8(Unit.getFormParams().AddrSize);
217*1db9f3b2SDimitry Andric     DebugInfoSectionSize += 11;
218*1db9f3b2SDimitry Andric   }
219*1db9f3b2SDimitry Andric }
220*1db9f3b2SDimitry Andric 
221*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitDIE(DIE &Die) {
222*1db9f3b2SDimitry Andric   MS->switchSection(MOFI->getDwarfInfoSection());
223*1db9f3b2SDimitry Andric   Asm->emitDwarfDIE(Die);
224*1db9f3b2SDimitry Andric   DebugInfoSectionSize += Die.getSize();
225*1db9f3b2SDimitry Andric }
226*1db9f3b2SDimitry Andric 
227*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitDebugNames(DWARF5AccelTable &Table,
228*1db9f3b2SDimitry Andric                                       DebugNamesUnitsOffsets &CUOffsets,
229*1db9f3b2SDimitry Andric                                       CompUnitIDToIdx &CUidToIdx) {
230*1db9f3b2SDimitry Andric   if (CUOffsets.empty())
231*1db9f3b2SDimitry Andric     return;
232*1db9f3b2SDimitry Andric 
233*1db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
234*1db9f3b2SDimitry Andric   dwarf::Form Form =
235*1db9f3b2SDimitry Andric       DIEInteger::BestForm(/*IsSigned*/ false, (uint64_t)CUidToIdx.size() - 1);
236*1db9f3b2SDimitry Andric   // FIXME: add support for type units + .debug_names. For now the behavior is
237*1db9f3b2SDimitry Andric   // unsuported.
238*1db9f3b2SDimitry Andric   emitDWARF5AccelTable(
239*1db9f3b2SDimitry Andric       Asm.get(), Table, CUOffsets,
240*1db9f3b2SDimitry Andric       [&](const DWARF5AccelTableData &Entry)
241*1db9f3b2SDimitry Andric           -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {
242*1db9f3b2SDimitry Andric         if (CUidToIdx.size() > 1)
243*1db9f3b2SDimitry Andric           return {{CUidToIdx[Entry.getUnitID()],
244*1db9f3b2SDimitry Andric                    {dwarf::DW_IDX_compile_unit, Form}}};
245*1db9f3b2SDimitry Andric         return std::nullopt;
246*1db9f3b2SDimitry Andric       });
247*1db9f3b2SDimitry Andric }
248*1db9f3b2SDimitry Andric 
249*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitAppleNamespaces(
250*1db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
251*1db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
252*1db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("namespac_begin");
253*1db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
254*1db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);
255*1db9f3b2SDimitry Andric }
256*1db9f3b2SDimitry Andric 
257*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitAppleNames(
258*1db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
259*1db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
260*1db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("names_begin");
261*1db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
262*1db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);
263*1db9f3b2SDimitry Andric }
264*1db9f3b2SDimitry Andric 
265*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitAppleObjc(
266*1db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
267*1db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
268*1db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("objc_begin");
269*1db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
270*1db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);
271*1db9f3b2SDimitry Andric }
272*1db9f3b2SDimitry Andric 
273*1db9f3b2SDimitry Andric void DwarfEmitterImpl::emitAppleTypes(
274*1db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticTypeData> &Table) {
275*1db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
276*1db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("types_begin");
277*1db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
278*1db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);
279*1db9f3b2SDimitry Andric }
280