xref: /llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.cpp (revision 7f17b6b740bd49b84430a46b366381bfc8b74fb0)
12357e899Savl-llvm //===- DWARFEmitterImpl.cpp -----------------------------------------------===//
22357e899Savl-llvm //
32357e899Savl-llvm // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42357e899Savl-llvm // See https://llvm.org/LICENSE.txt for license information.
52357e899Savl-llvm // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62357e899Savl-llvm //
72357e899Savl-llvm //===----------------------------------------------------------------------===//
82357e899Savl-llvm 
92357e899Savl-llvm #include "DWARFEmitterImpl.h"
102357e899Savl-llvm #include "DWARFLinkerCompileUnit.h"
112357e899Savl-llvm #include "llvm/MC/MCAsmBackend.h"
122357e899Savl-llvm #include "llvm/MC/MCCodeEmitter.h"
132357e899Savl-llvm #include "llvm/MC/MCObjectWriter.h"
142357e899Savl-llvm #include "llvm/MC/MCSubtargetInfo.h"
152357e899Savl-llvm #include "llvm/MC/MCTargetOptions.h"
162357e899Savl-llvm #include "llvm/MC/MCTargetOptionsCommandFlags.h"
172357e899Savl-llvm #include "llvm/MC/TargetRegistry.h"
182357e899Savl-llvm #include "llvm/Support/FormattedStream.h"
192357e899Savl-llvm 
202357e899Savl-llvm using namespace llvm;
212357e899Savl-llvm using namespace dwarf_linker;
222357e899Savl-llvm using namespace dwarf_linker::parallel;
232357e899Savl-llvm 
242357e899Savl-llvm Error DwarfEmitterImpl::init(Triple TheTriple,
252357e899Savl-llvm                              StringRef Swift5ReflectionSegmentName) {
262357e899Savl-llvm   std::string ErrorStr;
272357e899Savl-llvm   std::string TripleName;
282357e899Savl-llvm 
292357e899Savl-llvm   // Get the target.
302357e899Savl-llvm   const Target *TheTarget =
312357e899Savl-llvm       TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
322357e899Savl-llvm   if (!TheTarget)
332357e899Savl-llvm     return createStringError(std::errc::invalid_argument, ErrorStr.c_str());
342357e899Savl-llvm   TripleName = TheTriple.getTriple();
352357e899Savl-llvm 
362357e899Savl-llvm   // Create all the MC Objects.
372357e899Savl-llvm   MRI.reset(TheTarget->createMCRegInfo(TripleName));
382357e899Savl-llvm   if (!MRI)
392357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
402357e899Savl-llvm                              "no register info for target %s",
412357e899Savl-llvm                              TripleName.c_str());
422357e899Savl-llvm 
432357e899Savl-llvm   MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
4452e79ed1SFangrui Song   MCOptions.AsmVerbose = true;
4552e79ed1SFangrui Song   MCOptions.MCUseDwarfDirectory = MCTargetOptions::EnableDwarfDirectory;
462357e899Savl-llvm   MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
472357e899Savl-llvm   if (!MAI)
482357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
492357e899Savl-llvm                              "no asm info for target %s", TripleName.c_str());
502357e899Savl-llvm 
512357e899Savl-llvm   MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
522357e899Savl-llvm   if (!MSTI)
532357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
542357e899Savl-llvm                              "no subtarget info for target %s",
552357e899Savl-llvm                              TripleName.c_str());
562357e899Savl-llvm 
572357e899Savl-llvm   MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,
582357e899Savl-llvm                          nullptr, true, Swift5ReflectionSegmentName));
592357e899Savl-llvm   MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false));
602357e899Savl-llvm   MC->setObjectFileInfo(MOFI.get());
612357e899Savl-llvm 
622357e899Savl-llvm   MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
632357e899Savl-llvm   if (!MAB)
642357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
652357e899Savl-llvm                              "no asm backend for target %s",
662357e899Savl-llvm                              TripleName.c_str());
672357e899Savl-llvm 
682357e899Savl-llvm   MII.reset(TheTarget->createMCInstrInfo());
692357e899Savl-llvm   if (!MII)
702357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
712357e899Savl-llvm                              "no instr info info for target %s",
722357e899Savl-llvm                              TripleName.c_str());
732357e899Savl-llvm 
742357e899Savl-llvm   MCE = TheTarget->createMCCodeEmitter(*MII, *MC);
752357e899Savl-llvm   if (!MCE)
762357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
772357e899Savl-llvm                              "no code emitter for target %s",
782357e899Savl-llvm                              TripleName.c_str());
792357e899Savl-llvm 
802357e899Savl-llvm   switch (OutFileType) {
812357e899Savl-llvm   case DWARFLinker::OutputFileType::Assembly: {
822357e899Savl-llvm     MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),
832357e899Savl-llvm                                          *MAI, *MII, *MRI);
842357e899Savl-llvm     MS = TheTarget->createAsmStreamer(
85*7f17b6b7SFangrui Song         *MC, std::make_unique<formatted_raw_ostream>(OutFile), MIP,
86*7f17b6b7SFangrui Song         std::unique_ptr<MCCodeEmitter>(MCE),
87*7f17b6b7SFangrui Song         std::unique_ptr<MCAsmBackend>(MAB));
882357e899Savl-llvm     break;
892357e899Savl-llvm   }
902357e899Savl-llvm   case DWARFLinker::OutputFileType::Object: {
912357e899Savl-llvm     MS = TheTarget->createMCObjectStreamer(
922357e899Savl-llvm         TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
932357e899Savl-llvm         MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),
94b8220b98SFangrui Song         *MSTI);
952357e899Savl-llvm     break;
962357e899Savl-llvm   }
972357e899Savl-llvm   }
982357e899Savl-llvm 
992357e899Savl-llvm   if (!MS)
1002357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
1012357e899Savl-llvm                              "no object streamer for target %s",
1022357e899Savl-llvm                              TripleName.c_str());
1032357e899Savl-llvm 
1042357e899Savl-llvm   // Finally create the AsmPrinter we'll use to emit the DIEs.
1052357e899Savl-llvm   TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
1062357e899Savl-llvm                                           std::nullopt));
1072357e899Savl-llvm   if (!TM)
1082357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
1092357e899Savl-llvm                              "no target machine for target %s",
1102357e899Savl-llvm                              TripleName.c_str());
1112357e899Savl-llvm 
1122357e899Savl-llvm   Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
1132357e899Savl-llvm   if (!Asm)
1142357e899Savl-llvm     return createStringError(std::errc::invalid_argument,
1152357e899Savl-llvm                              "no asm printer for target %s",
1162357e899Savl-llvm                              TripleName.c_str());
1172357e899Savl-llvm   Asm->setDwarfUsesRelocationsAcrossSections(false);
1182357e899Savl-llvm 
1192357e899Savl-llvm   DebugInfoSectionSize = 0;
1202357e899Savl-llvm 
1212357e899Savl-llvm   return Error::success();
1222357e899Savl-llvm }
1232357e899Savl-llvm 
1242357e899Savl-llvm void DwarfEmitterImpl::emitAbbrevs(
1252357e899Savl-llvm     const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
1262357e899Savl-llvm     unsigned DwarfVersion) {
1272357e899Savl-llvm   MS->switchSection(MOFI->getDwarfAbbrevSection());
1282357e899Savl-llvm   MC->setDwarfVersion(DwarfVersion);
1292357e899Savl-llvm   Asm->emitDwarfAbbrevs(Abbrevs);
1302357e899Savl-llvm }
1312357e899Savl-llvm 
1322357e899Savl-llvm void DwarfEmitterImpl::emitCompileUnitHeader(DwarfUnit &Unit) {
1332357e899Savl-llvm   MS->switchSection(MOFI->getDwarfInfoSection());
1342357e899Savl-llvm   MC->setDwarfVersion(Unit.getVersion());
1352357e899Savl-llvm 
1362357e899Savl-llvm   // Emit size of content not including length itself. The size has already
1372357e899Savl-llvm   // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
1382357e899Savl-llvm   // account for the length field.
1392357e899Savl-llvm   Asm->emitInt32(Unit.getUnitSize() - 4);
1402357e899Savl-llvm   Asm->emitInt16(Unit.getVersion());
1412357e899Savl-llvm 
1422357e899Savl-llvm   if (Unit.getVersion() >= 5) {
1432357e899Savl-llvm     Asm->emitInt8(dwarf::DW_UT_compile);
1442357e899Savl-llvm     Asm->emitInt8(Unit.getFormParams().AddrSize);
1452357e899Savl-llvm     // Proper offset to the abbreviations table will be set later.
1462357e899Savl-llvm     Asm->emitInt32(0);
1472357e899Savl-llvm     DebugInfoSectionSize += 12;
1482357e899Savl-llvm   } else {
1492357e899Savl-llvm     // Proper offset to the abbreviations table will be set later.
1502357e899Savl-llvm     Asm->emitInt32(0);
1512357e899Savl-llvm     Asm->emitInt8(Unit.getFormParams().AddrSize);
1522357e899Savl-llvm     DebugInfoSectionSize += 11;
1532357e899Savl-llvm   }
1542357e899Savl-llvm }
1552357e899Savl-llvm 
1562357e899Savl-llvm void DwarfEmitterImpl::emitDIE(DIE &Die) {
1572357e899Savl-llvm   MS->switchSection(MOFI->getDwarfInfoSection());
1582357e899Savl-llvm   Asm->emitDwarfDIE(Die);
1592357e899Savl-llvm   DebugInfoSectionSize += Die.getSize();
1602357e899Savl-llvm }
1612357e899Savl-llvm 
1622357e899Savl-llvm void DwarfEmitterImpl::emitDebugNames(DWARF5AccelTable &Table,
1632357e899Savl-llvm                                       DebugNamesUnitsOffsets &CUOffsets,
1642357e899Savl-llvm                                       CompUnitIDToIdx &CUidToIdx) {
1652357e899Savl-llvm   if (CUOffsets.empty())
1662357e899Savl-llvm     return;
1672357e899Savl-llvm 
1682357e899Savl-llvm   Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
1692357e899Savl-llvm   dwarf::Form Form =
1702357e899Savl-llvm       DIEInteger::BestForm(/*IsSigned*/ false, (uint64_t)CUidToIdx.size() - 1);
1712357e899Savl-llvm   // FIXME: add support for type units + .debug_names. For now the behavior is
1722357e899Savl-llvm   // unsuported.
1732357e899Savl-llvm   emitDWARF5AccelTable(
1742357e899Savl-llvm       Asm.get(), Table, CUOffsets,
1752357e899Savl-llvm       [&](const DWARF5AccelTableData &Entry)
1762357e899Savl-llvm           -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {
1772357e899Savl-llvm         if (CUidToIdx.size() > 1)
1782357e899Savl-llvm           return {{CUidToIdx[Entry.getUnitID()],
1792357e899Savl-llvm                    {dwarf::DW_IDX_compile_unit, Form}}};
1802357e899Savl-llvm         return std::nullopt;
1812357e899Savl-llvm       });
1822357e899Savl-llvm }
1832357e899Savl-llvm 
1842357e899Savl-llvm void DwarfEmitterImpl::emitAppleNamespaces(
1852357e899Savl-llvm     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
1862357e899Savl-llvm   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
1872357e899Savl-llvm   auto *SectionBegin = Asm->createTempSymbol("namespac_begin");
1882357e899Savl-llvm   Asm->OutStreamer->emitLabel(SectionBegin);
1892357e899Savl-llvm   emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);
1902357e899Savl-llvm }
1912357e899Savl-llvm 
1922357e899Savl-llvm void DwarfEmitterImpl::emitAppleNames(
1932357e899Savl-llvm     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
1942357e899Savl-llvm   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
1952357e899Savl-llvm   auto *SectionBegin = Asm->createTempSymbol("names_begin");
1962357e899Savl-llvm   Asm->OutStreamer->emitLabel(SectionBegin);
1972357e899Savl-llvm   emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);
1982357e899Savl-llvm }
1992357e899Savl-llvm 
2002357e899Savl-llvm void DwarfEmitterImpl::emitAppleObjc(
2012357e899Savl-llvm     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
2022357e899Savl-llvm   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
2032357e899Savl-llvm   auto *SectionBegin = Asm->createTempSymbol("objc_begin");
2042357e899Savl-llvm   Asm->OutStreamer->emitLabel(SectionBegin);
2052357e899Savl-llvm   emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);
2062357e899Savl-llvm }
2072357e899Savl-llvm 
2082357e899Savl-llvm void DwarfEmitterImpl::emitAppleTypes(
2092357e899Savl-llvm     AccelTable<AppleAccelTableStaticTypeData> &Table) {
2102357e899Savl-llvm   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
2112357e899Savl-llvm   auto *SectionBegin = Asm->createTempSymbol("types_begin");
2122357e899Savl-llvm   Asm->OutStreamer->emitLabel(SectionBegin);
2132357e899Savl-llvm   emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);
2142357e899Savl-llvm }
215