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