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