1*1db9f3b2SDimitry Andric //===- DwarfStreamer.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 "llvm/DWARFLinker/Classic/DWARFStreamer.h" 10*1db9f3b2SDimitry Andric #include "llvm/CodeGen/NonRelocatableStringpool.h" 11*1db9f3b2SDimitry Andric #include "llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h" 12*1db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFContext.h" 13*1db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" 14*1db9f3b2SDimitry Andric #include "llvm/MC/MCAsmBackend.h" 15*1db9f3b2SDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 16*1db9f3b2SDimitry Andric #include "llvm/MC/MCDwarf.h" 17*1db9f3b2SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 18*1db9f3b2SDimitry Andric #include "llvm/MC/MCSection.h" 19*1db9f3b2SDimitry Andric #include "llvm/MC/MCStreamer.h" 20*1db9f3b2SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 21*1db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptions.h" 22*1db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptionsCommandFlags.h" 23*1db9f3b2SDimitry Andric #include "llvm/MC/TargetRegistry.h" 24*1db9f3b2SDimitry Andric #include "llvm/Support/FormatVariadic.h" 25*1db9f3b2SDimitry Andric #include "llvm/Support/LEB128.h" 26*1db9f3b2SDimitry Andric #include "llvm/Target/TargetOptions.h" 27*1db9f3b2SDimitry Andric #include "llvm/TargetParser/Triple.h" 28*1db9f3b2SDimitry Andric 29*1db9f3b2SDimitry Andric using namespace llvm; 30*1db9f3b2SDimitry Andric using namespace dwarf_linker; 31*1db9f3b2SDimitry Andric using namespace dwarf_linker::classic; 32*1db9f3b2SDimitry Andric 33*1db9f3b2SDimitry Andric Error DwarfStreamer::init(Triple TheTriple, 34*1db9f3b2SDimitry Andric StringRef Swift5ReflectionSegmentName) { 35*1db9f3b2SDimitry Andric std::string ErrorStr; 36*1db9f3b2SDimitry Andric std::string TripleName; 37*1db9f3b2SDimitry Andric 38*1db9f3b2SDimitry Andric // Get the target. 39*1db9f3b2SDimitry Andric const Target *TheTarget = 40*1db9f3b2SDimitry Andric TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); 41*1db9f3b2SDimitry Andric if (!TheTarget) 42*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, ErrorStr.c_str()); 43*1db9f3b2SDimitry Andric 44*1db9f3b2SDimitry Andric TripleName = TheTriple.getTriple(); 45*1db9f3b2SDimitry Andric 46*1db9f3b2SDimitry Andric // Create all the MC Objects. 47*1db9f3b2SDimitry Andric MRI.reset(TheTarget->createMCRegInfo(TripleName)); 48*1db9f3b2SDimitry Andric if (!MRI) 49*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 50*1db9f3b2SDimitry Andric "no register info for target %s", 51*1db9f3b2SDimitry Andric TripleName.c_str()); 52*1db9f3b2SDimitry Andric 53*1db9f3b2SDimitry Andric MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags(); 54*1db9f3b2SDimitry Andric MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 55*1db9f3b2SDimitry Andric if (!MAI) 56*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 57*1db9f3b2SDimitry Andric "no asm info for target %s", TripleName.c_str()); 58*1db9f3b2SDimitry Andric 59*1db9f3b2SDimitry Andric MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); 60*1db9f3b2SDimitry Andric if (!MSTI) 61*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 62*1db9f3b2SDimitry Andric "no subtarget info for target %s", 63*1db9f3b2SDimitry Andric TripleName.c_str()); 64*1db9f3b2SDimitry Andric 65*1db9f3b2SDimitry Andric MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr, 66*1db9f3b2SDimitry Andric nullptr, true, Swift5ReflectionSegmentName)); 67*1db9f3b2SDimitry Andric MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false)); 68*1db9f3b2SDimitry Andric MC->setObjectFileInfo(MOFI.get()); 69*1db9f3b2SDimitry Andric 70*1db9f3b2SDimitry Andric MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions); 71*1db9f3b2SDimitry Andric if (!MAB) 72*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 73*1db9f3b2SDimitry Andric "no asm backend for target %s", 74*1db9f3b2SDimitry Andric TripleName.c_str()); 75*1db9f3b2SDimitry Andric 76*1db9f3b2SDimitry Andric MII.reset(TheTarget->createMCInstrInfo()); 77*1db9f3b2SDimitry Andric if (!MII) 78*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 79*1db9f3b2SDimitry Andric "no instr info info for target %s", 80*1db9f3b2SDimitry Andric TripleName.c_str()); 81*1db9f3b2SDimitry Andric 82*1db9f3b2SDimitry Andric MCE = TheTarget->createMCCodeEmitter(*MII, *MC); 83*1db9f3b2SDimitry Andric if (!MCE) 84*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 85*1db9f3b2SDimitry Andric "no code emitter for target %s", 86*1db9f3b2SDimitry Andric TripleName.c_str()); 87*1db9f3b2SDimitry Andric 88*1db9f3b2SDimitry Andric switch (OutFileType) { 89*1db9f3b2SDimitry Andric case DWARFLinker::OutputFileType::Assembly: { 90*1db9f3b2SDimitry Andric MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(), 91*1db9f3b2SDimitry Andric *MAI, *MII, *MRI); 92*1db9f3b2SDimitry Andric MS = TheTarget->createAsmStreamer( 93*1db9f3b2SDimitry Andric *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP, 94*1db9f3b2SDimitry Andric std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB), 95*1db9f3b2SDimitry Andric true); 96*1db9f3b2SDimitry Andric break; 97*1db9f3b2SDimitry Andric } 98*1db9f3b2SDimitry Andric case DWARFLinker::OutputFileType::Object: { 99*1db9f3b2SDimitry Andric MS = TheTarget->createMCObjectStreamer( 100*1db9f3b2SDimitry Andric TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB), 101*1db9f3b2SDimitry Andric MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE), 102*1db9f3b2SDimitry Andric *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, 103*1db9f3b2SDimitry Andric /*DWARFMustBeAtTheEnd*/ false); 104*1db9f3b2SDimitry Andric break; 105*1db9f3b2SDimitry Andric } 106*1db9f3b2SDimitry Andric } 107*1db9f3b2SDimitry Andric 108*1db9f3b2SDimitry Andric if (!MS) 109*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 110*1db9f3b2SDimitry Andric "no object streamer for target %s", 111*1db9f3b2SDimitry Andric TripleName.c_str()); 112*1db9f3b2SDimitry Andric 113*1db9f3b2SDimitry Andric // Finally create the AsmPrinter we'll use to emit the DIEs. 114*1db9f3b2SDimitry Andric TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), 115*1db9f3b2SDimitry Andric std::nullopt)); 116*1db9f3b2SDimitry Andric if (!TM) 117*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 118*1db9f3b2SDimitry Andric "no target machine for target %s", 119*1db9f3b2SDimitry Andric TripleName.c_str()); 120*1db9f3b2SDimitry Andric 121*1db9f3b2SDimitry Andric Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS))); 122*1db9f3b2SDimitry Andric if (!Asm) 123*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 124*1db9f3b2SDimitry Andric "no asm printer for target %s", 125*1db9f3b2SDimitry Andric TripleName.c_str()); 126*1db9f3b2SDimitry Andric Asm->setDwarfUsesRelocationsAcrossSections(false); 127*1db9f3b2SDimitry Andric 128*1db9f3b2SDimitry Andric RangesSectionSize = 0; 129*1db9f3b2SDimitry Andric RngListsSectionSize = 0; 130*1db9f3b2SDimitry Andric LocSectionSize = 0; 131*1db9f3b2SDimitry Andric LocListsSectionSize = 0; 132*1db9f3b2SDimitry Andric LineSectionSize = 0; 133*1db9f3b2SDimitry Andric FrameSectionSize = 0; 134*1db9f3b2SDimitry Andric DebugInfoSectionSize = 0; 135*1db9f3b2SDimitry Andric MacInfoSectionSize = 0; 136*1db9f3b2SDimitry Andric MacroSectionSize = 0; 137*1db9f3b2SDimitry Andric 138*1db9f3b2SDimitry Andric return Error::success(); 139*1db9f3b2SDimitry Andric } 140*1db9f3b2SDimitry Andric 141*1db9f3b2SDimitry Andric void DwarfStreamer::finish() { MS->finish(); } 142*1db9f3b2SDimitry Andric 143*1db9f3b2SDimitry Andric void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) { 144*1db9f3b2SDimitry Andric MS->switchSection(MOFI->getDwarfInfoSection()); 145*1db9f3b2SDimitry Andric MC->setDwarfVersion(DwarfVersion); 146*1db9f3b2SDimitry Andric } 147*1db9f3b2SDimitry Andric 148*1db9f3b2SDimitry Andric /// Emit the compilation unit header for \p Unit in the debug_info section. 149*1db9f3b2SDimitry Andric /// 150*1db9f3b2SDimitry Andric /// A Dwarf 4 section header is encoded as: 151*1db9f3b2SDimitry Andric /// uint32_t Unit length (omitting this field) 152*1db9f3b2SDimitry Andric /// uint16_t Version 153*1db9f3b2SDimitry Andric /// uint32_t Abbreviation table offset 154*1db9f3b2SDimitry Andric /// uint8_t Address size 155*1db9f3b2SDimitry Andric /// Leading to a total of 11 bytes. 156*1db9f3b2SDimitry Andric /// 157*1db9f3b2SDimitry Andric /// A Dwarf 5 section header is encoded as: 158*1db9f3b2SDimitry Andric /// uint32_t Unit length (omitting this field) 159*1db9f3b2SDimitry Andric /// uint16_t Version 160*1db9f3b2SDimitry Andric /// uint8_t Unit type 161*1db9f3b2SDimitry Andric /// uint8_t Address size 162*1db9f3b2SDimitry Andric /// uint32_t Abbreviation table offset 163*1db9f3b2SDimitry Andric /// Leading to a total of 12 bytes. 164*1db9f3b2SDimitry Andric void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit, 165*1db9f3b2SDimitry Andric unsigned DwarfVersion) { 166*1db9f3b2SDimitry Andric switchToDebugInfoSection(DwarfVersion); 167*1db9f3b2SDimitry Andric 168*1db9f3b2SDimitry Andric /// The start of the unit within its section. 169*1db9f3b2SDimitry Andric Unit.setLabelBegin(Asm->createTempSymbol("cu_begin")); 170*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(Unit.getLabelBegin()); 171*1db9f3b2SDimitry Andric 172*1db9f3b2SDimitry Andric // Emit size of content not including length itself. The size has already 173*1db9f3b2SDimitry Andric // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to 174*1db9f3b2SDimitry Andric // account for the length field. 175*1db9f3b2SDimitry Andric Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4); 176*1db9f3b2SDimitry Andric Asm->emitInt16(DwarfVersion); 177*1db9f3b2SDimitry Andric 178*1db9f3b2SDimitry Andric if (DwarfVersion >= 5) { 179*1db9f3b2SDimitry Andric Asm->emitInt8(dwarf::DW_UT_compile); 180*1db9f3b2SDimitry Andric Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize()); 181*1db9f3b2SDimitry Andric // We share one abbreviations table across all units so it's always at the 182*1db9f3b2SDimitry Andric // start of the section. 183*1db9f3b2SDimitry Andric Asm->emitInt32(0); 184*1db9f3b2SDimitry Andric DebugInfoSectionSize += 12; 185*1db9f3b2SDimitry Andric } else { 186*1db9f3b2SDimitry Andric // We share one abbreviations table across all units so it's always at the 187*1db9f3b2SDimitry Andric // start of the section. 188*1db9f3b2SDimitry Andric Asm->emitInt32(0); 189*1db9f3b2SDimitry Andric Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize()); 190*1db9f3b2SDimitry Andric DebugInfoSectionSize += 11; 191*1db9f3b2SDimitry Andric } 192*1db9f3b2SDimitry Andric 193*1db9f3b2SDimitry Andric // Remember this CU. 194*1db9f3b2SDimitry Andric EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()}); 195*1db9f3b2SDimitry Andric } 196*1db9f3b2SDimitry Andric 197*1db9f3b2SDimitry Andric /// Emit the \p Abbrevs array as the shared abbreviation table 198*1db9f3b2SDimitry Andric /// for the linked Dwarf file. 199*1db9f3b2SDimitry Andric void DwarfStreamer::emitAbbrevs( 200*1db9f3b2SDimitry Andric const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, 201*1db9f3b2SDimitry Andric unsigned DwarfVersion) { 202*1db9f3b2SDimitry Andric MS->switchSection(MOFI->getDwarfAbbrevSection()); 203*1db9f3b2SDimitry Andric MC->setDwarfVersion(DwarfVersion); 204*1db9f3b2SDimitry Andric Asm->emitDwarfAbbrevs(Abbrevs); 205*1db9f3b2SDimitry Andric } 206*1db9f3b2SDimitry Andric 207*1db9f3b2SDimitry Andric /// Recursively emit the DIE tree rooted at \p Die. 208*1db9f3b2SDimitry Andric void DwarfStreamer::emitDIE(DIE &Die) { 209*1db9f3b2SDimitry Andric MS->switchSection(MOFI->getDwarfInfoSection()); 210*1db9f3b2SDimitry Andric Asm->emitDwarfDIE(Die); 211*1db9f3b2SDimitry Andric DebugInfoSectionSize += Die.getSize(); 212*1db9f3b2SDimitry Andric } 213*1db9f3b2SDimitry Andric 214*1db9f3b2SDimitry Andric /// Emit contents of section SecName From Obj. 215*1db9f3b2SDimitry Andric void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) { 216*1db9f3b2SDimitry Andric MCSection *Section = 217*1db9f3b2SDimitry Andric StringSwitch<MCSection *>(SecName) 218*1db9f3b2SDimitry Andric .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection()) 219*1db9f3b2SDimitry Andric .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection()) 220*1db9f3b2SDimitry Andric .Case("debug_ranges", 221*1db9f3b2SDimitry Andric MC->getObjectFileInfo()->getDwarfRangesSection()) 222*1db9f3b2SDimitry Andric .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection()) 223*1db9f3b2SDimitry Andric .Case("debug_aranges", 224*1db9f3b2SDimitry Andric MC->getObjectFileInfo()->getDwarfARangesSection()) 225*1db9f3b2SDimitry Andric .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection()) 226*1db9f3b2SDimitry Andric .Case("debug_rnglists", 227*1db9f3b2SDimitry Andric MC->getObjectFileInfo()->getDwarfRnglistsSection()) 228*1db9f3b2SDimitry Andric .Case("debug_loclists", 229*1db9f3b2SDimitry Andric MC->getObjectFileInfo()->getDwarfLoclistsSection()) 230*1db9f3b2SDimitry Andric .Default(nullptr); 231*1db9f3b2SDimitry Andric 232*1db9f3b2SDimitry Andric if (Section) { 233*1db9f3b2SDimitry Andric MS->switchSection(Section); 234*1db9f3b2SDimitry Andric 235*1db9f3b2SDimitry Andric MS->emitBytes(SecData); 236*1db9f3b2SDimitry Andric } 237*1db9f3b2SDimitry Andric } 238*1db9f3b2SDimitry Andric 239*1db9f3b2SDimitry Andric /// Emit the debug_str section stored in \p Pool. 240*1db9f3b2SDimitry Andric void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) { 241*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection()); 242*1db9f3b2SDimitry Andric std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission(); 243*1db9f3b2SDimitry Andric for (auto Entry : Entries) { 244*1db9f3b2SDimitry Andric // Emit the string itself. 245*1db9f3b2SDimitry Andric Asm->OutStreamer->emitBytes(Entry.getString()); 246*1db9f3b2SDimitry Andric // Emit a null terminator. 247*1db9f3b2SDimitry Andric Asm->emitInt8(0); 248*1db9f3b2SDimitry Andric } 249*1db9f3b2SDimitry Andric } 250*1db9f3b2SDimitry Andric 251*1db9f3b2SDimitry Andric /// Emit the debug string offset table described by \p StringOffsets into the 252*1db9f3b2SDimitry Andric /// .debug_str_offsets table. 253*1db9f3b2SDimitry Andric void DwarfStreamer::emitStringOffsets( 254*1db9f3b2SDimitry Andric const SmallVector<uint64_t> &StringOffsets, uint16_t TargetDWARFVersion) { 255*1db9f3b2SDimitry Andric 256*1db9f3b2SDimitry Andric if (TargetDWARFVersion < 5 || StringOffsets.empty()) 257*1db9f3b2SDimitry Andric return; 258*1db9f3b2SDimitry Andric 259*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfStrOffSection()); 260*1db9f3b2SDimitry Andric 261*1db9f3b2SDimitry Andric MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugstroff"); 262*1db9f3b2SDimitry Andric MCSymbol *EndLabel = Asm->createTempSymbol("Edebugstroff"); 263*1db9f3b2SDimitry Andric 264*1db9f3b2SDimitry Andric // Length. 265*1db9f3b2SDimitry Andric Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); 266*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(BeginLabel); 267*1db9f3b2SDimitry Andric StrOffsetSectionSize += sizeof(uint32_t); 268*1db9f3b2SDimitry Andric 269*1db9f3b2SDimitry Andric // Version. 270*1db9f3b2SDimitry Andric MS->emitInt16(5); 271*1db9f3b2SDimitry Andric StrOffsetSectionSize += sizeof(uint16_t); 272*1db9f3b2SDimitry Andric 273*1db9f3b2SDimitry Andric // Padding. 274*1db9f3b2SDimitry Andric MS->emitInt16(0); 275*1db9f3b2SDimitry Andric StrOffsetSectionSize += sizeof(uint16_t); 276*1db9f3b2SDimitry Andric 277*1db9f3b2SDimitry Andric for (auto Off : StringOffsets) { 278*1db9f3b2SDimitry Andric Asm->OutStreamer->emitInt32(Off); 279*1db9f3b2SDimitry Andric StrOffsetSectionSize += sizeof(uint32_t); 280*1db9f3b2SDimitry Andric } 281*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(EndLabel); 282*1db9f3b2SDimitry Andric } 283*1db9f3b2SDimitry Andric 284*1db9f3b2SDimitry Andric /// Emit the debug_line_str section stored in \p Pool. 285*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineStrings(const NonRelocatableStringpool &Pool) { 286*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection()); 287*1db9f3b2SDimitry Andric std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission(); 288*1db9f3b2SDimitry Andric for (auto Entry : Entries) { 289*1db9f3b2SDimitry Andric // Emit the string itself. 290*1db9f3b2SDimitry Andric Asm->OutStreamer->emitBytes(Entry.getString()); 291*1db9f3b2SDimitry Andric // Emit a null terminator. 292*1db9f3b2SDimitry Andric Asm->emitInt8(0); 293*1db9f3b2SDimitry Andric } 294*1db9f3b2SDimitry Andric } 295*1db9f3b2SDimitry Andric 296*1db9f3b2SDimitry Andric void DwarfStreamer::emitDebugNames(DWARF5AccelTable &Table) { 297*1db9f3b2SDimitry Andric if (EmittedUnits.empty()) 298*1db9f3b2SDimitry Andric return; 299*1db9f3b2SDimitry Andric 300*1db9f3b2SDimitry Andric // Build up data structures needed to emit this section. 301*1db9f3b2SDimitry Andric std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits; 302*1db9f3b2SDimitry Andric DenseMap<unsigned, unsigned> UniqueIdToCuMap; 303*1db9f3b2SDimitry Andric unsigned Id = 0; 304*1db9f3b2SDimitry Andric for (auto &CU : EmittedUnits) { 305*1db9f3b2SDimitry Andric CompUnits.push_back(CU.LabelBegin); 306*1db9f3b2SDimitry Andric // We might be omitting CUs, so we need to remap them. 307*1db9f3b2SDimitry Andric UniqueIdToCuMap[CU.ID] = Id++; 308*1db9f3b2SDimitry Andric } 309*1db9f3b2SDimitry Andric 310*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection()); 311*1db9f3b2SDimitry Andric dwarf::Form Form = DIEInteger::BestForm(/*IsSigned*/ false, 312*1db9f3b2SDimitry Andric (uint64_t)UniqueIdToCuMap.size() - 1); 313*1db9f3b2SDimitry Andric /// llvm-dwarfutil doesn't support type units + .debug_names right now. 314*1db9f3b2SDimitry Andric // FIXME: add support for type units + .debug_names. For now the behavior is 315*1db9f3b2SDimitry Andric // unsuported. 316*1db9f3b2SDimitry Andric emitDWARF5AccelTable( 317*1db9f3b2SDimitry Andric Asm.get(), Table, CompUnits, 318*1db9f3b2SDimitry Andric [&](const DWARF5AccelTableData &Entry) 319*1db9f3b2SDimitry Andric -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> { 320*1db9f3b2SDimitry Andric if (UniqueIdToCuMap.size() > 1) 321*1db9f3b2SDimitry Andric return {{UniqueIdToCuMap[Entry.getUnitID()], 322*1db9f3b2SDimitry Andric {dwarf::DW_IDX_compile_unit, Form}}}; 323*1db9f3b2SDimitry Andric return std::nullopt; 324*1db9f3b2SDimitry Andric }); 325*1db9f3b2SDimitry Andric } 326*1db9f3b2SDimitry Andric 327*1db9f3b2SDimitry Andric void DwarfStreamer::emitAppleNamespaces( 328*1db9f3b2SDimitry Andric AccelTable<AppleAccelTableStaticOffsetData> &Table) { 329*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection()); 330*1db9f3b2SDimitry Andric auto *SectionBegin = Asm->createTempSymbol("namespac_begin"); 331*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(SectionBegin); 332*1db9f3b2SDimitry Andric emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin); 333*1db9f3b2SDimitry Andric } 334*1db9f3b2SDimitry Andric 335*1db9f3b2SDimitry Andric void DwarfStreamer::emitAppleNames( 336*1db9f3b2SDimitry Andric AccelTable<AppleAccelTableStaticOffsetData> &Table) { 337*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection()); 338*1db9f3b2SDimitry Andric auto *SectionBegin = Asm->createTempSymbol("names_begin"); 339*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(SectionBegin); 340*1db9f3b2SDimitry Andric emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin); 341*1db9f3b2SDimitry Andric } 342*1db9f3b2SDimitry Andric 343*1db9f3b2SDimitry Andric void DwarfStreamer::emitAppleObjc( 344*1db9f3b2SDimitry Andric AccelTable<AppleAccelTableStaticOffsetData> &Table) { 345*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection()); 346*1db9f3b2SDimitry Andric auto *SectionBegin = Asm->createTempSymbol("objc_begin"); 347*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(SectionBegin); 348*1db9f3b2SDimitry Andric emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin); 349*1db9f3b2SDimitry Andric } 350*1db9f3b2SDimitry Andric 351*1db9f3b2SDimitry Andric void DwarfStreamer::emitAppleTypes( 352*1db9f3b2SDimitry Andric AccelTable<AppleAccelTableStaticTypeData> &Table) { 353*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection()); 354*1db9f3b2SDimitry Andric auto *SectionBegin = Asm->createTempSymbol("types_begin"); 355*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(SectionBegin); 356*1db9f3b2SDimitry Andric emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin); 357*1db9f3b2SDimitry Andric } 358*1db9f3b2SDimitry Andric 359*1db9f3b2SDimitry Andric /// Emit the swift_ast section stored in \p Buffers. 360*1db9f3b2SDimitry Andric void DwarfStreamer::emitSwiftAST(StringRef Buffer) { 361*1db9f3b2SDimitry Andric MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection(); 362*1db9f3b2SDimitry Andric SwiftASTSection->setAlignment(Align(32)); 363*1db9f3b2SDimitry Andric MS->switchSection(SwiftASTSection); 364*1db9f3b2SDimitry Andric MS->emitBytes(Buffer); 365*1db9f3b2SDimitry Andric } 366*1db9f3b2SDimitry Andric 367*1db9f3b2SDimitry Andric void DwarfStreamer::emitSwiftReflectionSection( 368*1db9f3b2SDimitry Andric llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, 369*1db9f3b2SDimitry Andric StringRef Buffer, uint32_t Alignment, uint32_t Size) { 370*1db9f3b2SDimitry Andric MCSection *ReflectionSection = 371*1db9f3b2SDimitry Andric MOFI->getSwift5ReflectionSection(ReflSectionKind); 372*1db9f3b2SDimitry Andric if (ReflectionSection == nullptr) 373*1db9f3b2SDimitry Andric return; 374*1db9f3b2SDimitry Andric ReflectionSection->setAlignment(Align(Alignment)); 375*1db9f3b2SDimitry Andric MS->switchSection(ReflectionSection); 376*1db9f3b2SDimitry Andric MS->emitBytes(Buffer); 377*1db9f3b2SDimitry Andric } 378*1db9f3b2SDimitry Andric 379*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugArangesTable( 380*1db9f3b2SDimitry Andric const CompileUnit &Unit, const AddressRanges &LinkedRanges) { 381*1db9f3b2SDimitry Andric unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 382*1db9f3b2SDimitry Andric 383*1db9f3b2SDimitry Andric // Make .debug_aranges to be current section. 384*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfARangesSection()); 385*1db9f3b2SDimitry Andric 386*1db9f3b2SDimitry Andric // Emit Header. 387*1db9f3b2SDimitry Andric MCSymbol *BeginLabel = Asm->createTempSymbol("Barange"); 388*1db9f3b2SDimitry Andric MCSymbol *EndLabel = Asm->createTempSymbol("Earange"); 389*1db9f3b2SDimitry Andric 390*1db9f3b2SDimitry Andric unsigned HeaderSize = 391*1db9f3b2SDimitry Andric sizeof(int32_t) + // Size of contents (w/o this field 392*1db9f3b2SDimitry Andric sizeof(int16_t) + // DWARF ARange version number 393*1db9f3b2SDimitry Andric sizeof(int32_t) + // Offset of CU in the .debug_info section 394*1db9f3b2SDimitry Andric sizeof(int8_t) + // Pointer Size (in bytes) 395*1db9f3b2SDimitry Andric sizeof(int8_t); // Segment Size (in bytes) 396*1db9f3b2SDimitry Andric 397*1db9f3b2SDimitry Andric unsigned TupleSize = AddressSize * 2; 398*1db9f3b2SDimitry Andric unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize)); 399*1db9f3b2SDimitry Andric 400*1db9f3b2SDimitry Andric Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Arange length 401*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(BeginLabel); 402*1db9f3b2SDimitry Andric Asm->emitInt16(dwarf::DW_ARANGES_VERSION); // Version number 403*1db9f3b2SDimitry Andric Asm->emitInt32(Unit.getStartOffset()); // Corresponding unit's offset 404*1db9f3b2SDimitry Andric Asm->emitInt8(AddressSize); // Address size 405*1db9f3b2SDimitry Andric Asm->emitInt8(0); // Segment size 406*1db9f3b2SDimitry Andric 407*1db9f3b2SDimitry Andric Asm->OutStreamer->emitFill(Padding, 0x0); 408*1db9f3b2SDimitry Andric 409*1db9f3b2SDimitry Andric // Emit linked ranges. 410*1db9f3b2SDimitry Andric for (const AddressRange &Range : LinkedRanges) { 411*1db9f3b2SDimitry Andric MS->emitIntValue(Range.start(), AddressSize); 412*1db9f3b2SDimitry Andric MS->emitIntValue(Range.end() - Range.start(), AddressSize); 413*1db9f3b2SDimitry Andric } 414*1db9f3b2SDimitry Andric 415*1db9f3b2SDimitry Andric // Emit terminator. 416*1db9f3b2SDimitry Andric Asm->OutStreamer->emitIntValue(0, AddressSize); 417*1db9f3b2SDimitry Andric Asm->OutStreamer->emitIntValue(0, AddressSize); 418*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(EndLabel); 419*1db9f3b2SDimitry Andric } 420*1db9f3b2SDimitry Andric 421*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRangesTableFragment( 422*1db9f3b2SDimitry Andric const CompileUnit &Unit, const AddressRanges &LinkedRanges, 423*1db9f3b2SDimitry Andric PatchLocation Patch) { 424*1db9f3b2SDimitry Andric Patch.set(RangesSectionSize); 425*1db9f3b2SDimitry Andric 426*1db9f3b2SDimitry Andric // Make .debug_ranges to be current section. 427*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); 428*1db9f3b2SDimitry Andric unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 429*1db9f3b2SDimitry Andric 430*1db9f3b2SDimitry Andric // Emit ranges. 431*1db9f3b2SDimitry Andric uint64_t BaseAddress = 0; 432*1db9f3b2SDimitry Andric if (std::optional<uint64_t> LowPC = Unit.getLowPc()) 433*1db9f3b2SDimitry Andric BaseAddress = *LowPC; 434*1db9f3b2SDimitry Andric 435*1db9f3b2SDimitry Andric for (const AddressRange &Range : LinkedRanges) { 436*1db9f3b2SDimitry Andric MS->emitIntValue(Range.start() - BaseAddress, AddressSize); 437*1db9f3b2SDimitry Andric MS->emitIntValue(Range.end() - BaseAddress, AddressSize); 438*1db9f3b2SDimitry Andric 439*1db9f3b2SDimitry Andric RangesSectionSize += AddressSize; 440*1db9f3b2SDimitry Andric RangesSectionSize += AddressSize; 441*1db9f3b2SDimitry Andric } 442*1db9f3b2SDimitry Andric 443*1db9f3b2SDimitry Andric // Add the terminator entry. 444*1db9f3b2SDimitry Andric MS->emitIntValue(0, AddressSize); 445*1db9f3b2SDimitry Andric MS->emitIntValue(0, AddressSize); 446*1db9f3b2SDimitry Andric 447*1db9f3b2SDimitry Andric RangesSectionSize += AddressSize; 448*1db9f3b2SDimitry Andric RangesSectionSize += AddressSize; 449*1db9f3b2SDimitry Andric } 450*1db9f3b2SDimitry Andric 451*1db9f3b2SDimitry Andric MCSymbol * 452*1db9f3b2SDimitry Andric DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit &Unit) { 453*1db9f3b2SDimitry Andric if (Unit.getOrigUnit().getVersion() < 5) 454*1db9f3b2SDimitry Andric return nullptr; 455*1db9f3b2SDimitry Andric 456*1db9f3b2SDimitry Andric // Make .debug_rnglists to be current section. 457*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); 458*1db9f3b2SDimitry Andric 459*1db9f3b2SDimitry Andric MCSymbol *BeginLabel = Asm->createTempSymbol("Brnglists"); 460*1db9f3b2SDimitry Andric MCSymbol *EndLabel = Asm->createTempSymbol("Ernglists"); 461*1db9f3b2SDimitry Andric unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 462*1db9f3b2SDimitry Andric 463*1db9f3b2SDimitry Andric // Length 464*1db9f3b2SDimitry Andric Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); 465*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(BeginLabel); 466*1db9f3b2SDimitry Andric RngListsSectionSize += sizeof(uint32_t); 467*1db9f3b2SDimitry Andric 468*1db9f3b2SDimitry Andric // Version. 469*1db9f3b2SDimitry Andric MS->emitInt16(5); 470*1db9f3b2SDimitry Andric RngListsSectionSize += sizeof(uint16_t); 471*1db9f3b2SDimitry Andric 472*1db9f3b2SDimitry Andric // Address size. 473*1db9f3b2SDimitry Andric MS->emitInt8(AddressSize); 474*1db9f3b2SDimitry Andric RngListsSectionSize++; 475*1db9f3b2SDimitry Andric 476*1db9f3b2SDimitry Andric // Seg_size 477*1db9f3b2SDimitry Andric MS->emitInt8(0); 478*1db9f3b2SDimitry Andric RngListsSectionSize++; 479*1db9f3b2SDimitry Andric 480*1db9f3b2SDimitry Andric // Offset entry count 481*1db9f3b2SDimitry Andric MS->emitInt32(0); 482*1db9f3b2SDimitry Andric RngListsSectionSize += sizeof(uint32_t); 483*1db9f3b2SDimitry Andric 484*1db9f3b2SDimitry Andric return EndLabel; 485*1db9f3b2SDimitry Andric } 486*1db9f3b2SDimitry Andric 487*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRangeListFragment( 488*1db9f3b2SDimitry Andric const CompileUnit &Unit, const AddressRanges &LinkedRanges, 489*1db9f3b2SDimitry Andric PatchLocation Patch, DebugDieValuePool &AddrPool) { 490*1db9f3b2SDimitry Andric if (Unit.getOrigUnit().getVersion() < 5) { 491*1db9f3b2SDimitry Andric emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch); 492*1db9f3b2SDimitry Andric return; 493*1db9f3b2SDimitry Andric } 494*1db9f3b2SDimitry Andric 495*1db9f3b2SDimitry Andric emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool); 496*1db9f3b2SDimitry Andric } 497*1db9f3b2SDimitry Andric 498*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit, 499*1db9f3b2SDimitry Andric MCSymbol *EndLabel) { 500*1db9f3b2SDimitry Andric if (Unit.getOrigUnit().getVersion() < 5) 501*1db9f3b2SDimitry Andric return; 502*1db9f3b2SDimitry Andric 503*1db9f3b2SDimitry Andric // Make .debug_rnglists to be current section. 504*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); 505*1db9f3b2SDimitry Andric 506*1db9f3b2SDimitry Andric if (EndLabel != nullptr) 507*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(EndLabel); 508*1db9f3b2SDimitry Andric } 509*1db9f3b2SDimitry Andric 510*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRngListsTableFragment( 511*1db9f3b2SDimitry Andric const CompileUnit &Unit, const AddressRanges &LinkedRanges, 512*1db9f3b2SDimitry Andric PatchLocation Patch, DebugDieValuePool &AddrPool) { 513*1db9f3b2SDimitry Andric Patch.set(RngListsSectionSize); 514*1db9f3b2SDimitry Andric 515*1db9f3b2SDimitry Andric // Make .debug_rnglists to be current section. 516*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); 517*1db9f3b2SDimitry Andric std::optional<uint64_t> BaseAddress; 518*1db9f3b2SDimitry Andric 519*1db9f3b2SDimitry Andric for (const AddressRange &Range : LinkedRanges) { 520*1db9f3b2SDimitry Andric 521*1db9f3b2SDimitry Andric if (!BaseAddress) { 522*1db9f3b2SDimitry Andric BaseAddress = Range.start(); 523*1db9f3b2SDimitry Andric 524*1db9f3b2SDimitry Andric // Emit base address. 525*1db9f3b2SDimitry Andric MS->emitInt8(dwarf::DW_RLE_base_addressx); 526*1db9f3b2SDimitry Andric RngListsSectionSize += 1; 527*1db9f3b2SDimitry Andric RngListsSectionSize += 528*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress)); 529*1db9f3b2SDimitry Andric } 530*1db9f3b2SDimitry Andric 531*1db9f3b2SDimitry Andric // Emit type of entry. 532*1db9f3b2SDimitry Andric MS->emitInt8(dwarf::DW_RLE_offset_pair); 533*1db9f3b2SDimitry Andric RngListsSectionSize += 1; 534*1db9f3b2SDimitry Andric 535*1db9f3b2SDimitry Andric // Emit start offset relative to base address. 536*1db9f3b2SDimitry Andric RngListsSectionSize += 537*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(Range.start() - *BaseAddress); 538*1db9f3b2SDimitry Andric 539*1db9f3b2SDimitry Andric // Emit end offset relative to base address. 540*1db9f3b2SDimitry Andric RngListsSectionSize += MS->emitULEB128IntValue(Range.end() - *BaseAddress); 541*1db9f3b2SDimitry Andric } 542*1db9f3b2SDimitry Andric 543*1db9f3b2SDimitry Andric // Emit the terminator entry. 544*1db9f3b2SDimitry Andric MS->emitInt8(dwarf::DW_RLE_end_of_list); 545*1db9f3b2SDimitry Andric RngListsSectionSize += 1; 546*1db9f3b2SDimitry Andric } 547*1db9f3b2SDimitry Andric 548*1db9f3b2SDimitry Andric /// Emit debug locations(.debug_loc, .debug_loclists) header. 549*1db9f3b2SDimitry Andric MCSymbol *DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit &Unit) { 550*1db9f3b2SDimitry Andric if (Unit.getOrigUnit().getVersion() < 5) 551*1db9f3b2SDimitry Andric return nullptr; 552*1db9f3b2SDimitry Andric 553*1db9f3b2SDimitry Andric // Make .debug_loclists the current section. 554*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection()); 555*1db9f3b2SDimitry Andric 556*1db9f3b2SDimitry Andric MCSymbol *BeginLabel = Asm->createTempSymbol("Bloclists"); 557*1db9f3b2SDimitry Andric MCSymbol *EndLabel = Asm->createTempSymbol("Eloclists"); 558*1db9f3b2SDimitry Andric unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 559*1db9f3b2SDimitry Andric 560*1db9f3b2SDimitry Andric // Length 561*1db9f3b2SDimitry Andric Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); 562*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(BeginLabel); 563*1db9f3b2SDimitry Andric LocListsSectionSize += sizeof(uint32_t); 564*1db9f3b2SDimitry Andric 565*1db9f3b2SDimitry Andric // Version. 566*1db9f3b2SDimitry Andric MS->emitInt16(5); 567*1db9f3b2SDimitry Andric LocListsSectionSize += sizeof(uint16_t); 568*1db9f3b2SDimitry Andric 569*1db9f3b2SDimitry Andric // Address size. 570*1db9f3b2SDimitry Andric MS->emitInt8(AddressSize); 571*1db9f3b2SDimitry Andric LocListsSectionSize++; 572*1db9f3b2SDimitry Andric 573*1db9f3b2SDimitry Andric // Seg_size 574*1db9f3b2SDimitry Andric MS->emitInt8(0); 575*1db9f3b2SDimitry Andric LocListsSectionSize++; 576*1db9f3b2SDimitry Andric 577*1db9f3b2SDimitry Andric // Offset entry count 578*1db9f3b2SDimitry Andric MS->emitInt32(0); 579*1db9f3b2SDimitry Andric LocListsSectionSize += sizeof(uint32_t); 580*1db9f3b2SDimitry Andric 581*1db9f3b2SDimitry Andric return EndLabel; 582*1db9f3b2SDimitry Andric } 583*1db9f3b2SDimitry Andric 584*1db9f3b2SDimitry Andric /// Emit debug locations(.debug_loc, .debug_loclists) fragment. 585*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocListFragment( 586*1db9f3b2SDimitry Andric const CompileUnit &Unit, 587*1db9f3b2SDimitry Andric const DWARFLocationExpressionsVector &LinkedLocationExpression, 588*1db9f3b2SDimitry Andric PatchLocation Patch, DebugDieValuePool &AddrPool) { 589*1db9f3b2SDimitry Andric if (Unit.getOrigUnit().getVersion() < 5) { 590*1db9f3b2SDimitry Andric emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch); 591*1db9f3b2SDimitry Andric return; 592*1db9f3b2SDimitry Andric } 593*1db9f3b2SDimitry Andric 594*1db9f3b2SDimitry Andric emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch, 595*1db9f3b2SDimitry Andric AddrPool); 596*1db9f3b2SDimitry Andric } 597*1db9f3b2SDimitry Andric 598*1db9f3b2SDimitry Andric /// Emit debug locations(.debug_loc, .debug_loclists) footer. 599*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit &Unit, 600*1db9f3b2SDimitry Andric MCSymbol *EndLabel) { 601*1db9f3b2SDimitry Andric if (Unit.getOrigUnit().getVersion() < 5) 602*1db9f3b2SDimitry Andric return; 603*1db9f3b2SDimitry Andric 604*1db9f3b2SDimitry Andric // Make .debug_loclists the current section. 605*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection()); 606*1db9f3b2SDimitry Andric 607*1db9f3b2SDimitry Andric if (EndLabel != nullptr) 608*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(EndLabel); 609*1db9f3b2SDimitry Andric } 610*1db9f3b2SDimitry Andric 611*1db9f3b2SDimitry Andric /// Emit piece of .debug_loc for \p LinkedLocationExpression. 612*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocTableFragment( 613*1db9f3b2SDimitry Andric const CompileUnit &Unit, 614*1db9f3b2SDimitry Andric const DWARFLocationExpressionsVector &LinkedLocationExpression, 615*1db9f3b2SDimitry Andric PatchLocation Patch) { 616*1db9f3b2SDimitry Andric Patch.set(LocSectionSize); 617*1db9f3b2SDimitry Andric 618*1db9f3b2SDimitry Andric // Make .debug_loc to be current section. 619*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection()); 620*1db9f3b2SDimitry Andric unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); 621*1db9f3b2SDimitry Andric 622*1db9f3b2SDimitry Andric // Emit ranges. 623*1db9f3b2SDimitry Andric uint64_t BaseAddress = 0; 624*1db9f3b2SDimitry Andric if (std::optional<uint64_t> LowPC = Unit.getLowPc()) 625*1db9f3b2SDimitry Andric BaseAddress = *LowPC; 626*1db9f3b2SDimitry Andric 627*1db9f3b2SDimitry Andric for (const DWARFLocationExpression &LocExpression : 628*1db9f3b2SDimitry Andric LinkedLocationExpression) { 629*1db9f3b2SDimitry Andric if (LocExpression.Range) { 630*1db9f3b2SDimitry Andric MS->emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize); 631*1db9f3b2SDimitry Andric MS->emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize); 632*1db9f3b2SDimitry Andric 633*1db9f3b2SDimitry Andric LocSectionSize += AddressSize; 634*1db9f3b2SDimitry Andric LocSectionSize += AddressSize; 635*1db9f3b2SDimitry Andric } 636*1db9f3b2SDimitry Andric 637*1db9f3b2SDimitry Andric Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2); 638*1db9f3b2SDimitry Andric Asm->OutStreamer->emitBytes(StringRef( 639*1db9f3b2SDimitry Andric (const char *)LocExpression.Expr.data(), LocExpression.Expr.size())); 640*1db9f3b2SDimitry Andric LocSectionSize += LocExpression.Expr.size() + 2; 641*1db9f3b2SDimitry Andric } 642*1db9f3b2SDimitry Andric 643*1db9f3b2SDimitry Andric // Add the terminator entry. 644*1db9f3b2SDimitry Andric MS->emitIntValue(0, AddressSize); 645*1db9f3b2SDimitry Andric MS->emitIntValue(0, AddressSize); 646*1db9f3b2SDimitry Andric 647*1db9f3b2SDimitry Andric LocSectionSize += AddressSize; 648*1db9f3b2SDimitry Andric LocSectionSize += AddressSize; 649*1db9f3b2SDimitry Andric } 650*1db9f3b2SDimitry Andric 651*1db9f3b2SDimitry Andric /// Emit .debug_addr header. 652*1db9f3b2SDimitry Andric MCSymbol *DwarfStreamer::emitDwarfDebugAddrsHeader(const CompileUnit &Unit) { 653*1db9f3b2SDimitry Andric 654*1db9f3b2SDimitry Andric // Make .debug_addr the current section. 655*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection()); 656*1db9f3b2SDimitry Andric 657*1db9f3b2SDimitry Andric MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugaddr"); 658*1db9f3b2SDimitry Andric MCSymbol *EndLabel = Asm->createTempSymbol("Edebugaddr"); 659*1db9f3b2SDimitry Andric unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize(); 660*1db9f3b2SDimitry Andric 661*1db9f3b2SDimitry Andric // Emit length. 662*1db9f3b2SDimitry Andric Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); 663*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(BeginLabel); 664*1db9f3b2SDimitry Andric AddrSectionSize += sizeof(uint32_t); 665*1db9f3b2SDimitry Andric 666*1db9f3b2SDimitry Andric // Emit version. 667*1db9f3b2SDimitry Andric Asm->emitInt16(5); 668*1db9f3b2SDimitry Andric AddrSectionSize += 2; 669*1db9f3b2SDimitry Andric 670*1db9f3b2SDimitry Andric // Emit address size. 671*1db9f3b2SDimitry Andric Asm->emitInt8(AddrSize); 672*1db9f3b2SDimitry Andric AddrSectionSize += 1; 673*1db9f3b2SDimitry Andric 674*1db9f3b2SDimitry Andric // Emit segment size. 675*1db9f3b2SDimitry Andric Asm->emitInt8(0); 676*1db9f3b2SDimitry Andric AddrSectionSize += 1; 677*1db9f3b2SDimitry Andric 678*1db9f3b2SDimitry Andric return EndLabel; 679*1db9f3b2SDimitry Andric } 680*1db9f3b2SDimitry Andric 681*1db9f3b2SDimitry Andric /// Emit the .debug_addr addresses stored in \p Addrs. 682*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs, 683*1db9f3b2SDimitry Andric uint8_t AddrSize) { 684*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection()); 685*1db9f3b2SDimitry Andric for (auto Addr : Addrs) { 686*1db9f3b2SDimitry Andric Asm->OutStreamer->emitIntValue(Addr, AddrSize); 687*1db9f3b2SDimitry Andric AddrSectionSize += AddrSize; 688*1db9f3b2SDimitry Andric } 689*1db9f3b2SDimitry Andric } 690*1db9f3b2SDimitry Andric 691*1db9f3b2SDimitry Andric /// Emit .debug_addr footer. 692*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit &Unit, 693*1db9f3b2SDimitry Andric MCSymbol *EndLabel) { 694*1db9f3b2SDimitry Andric 695*1db9f3b2SDimitry Andric // Make .debug_addr the current section. 696*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection()); 697*1db9f3b2SDimitry Andric 698*1db9f3b2SDimitry Andric if (EndLabel != nullptr) 699*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(EndLabel); 700*1db9f3b2SDimitry Andric } 701*1db9f3b2SDimitry Andric 702*1db9f3b2SDimitry Andric /// Emit piece of .debug_loclists for \p LinkedLocationExpression. 703*1db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocListsTableFragment( 704*1db9f3b2SDimitry Andric const CompileUnit &Unit, 705*1db9f3b2SDimitry Andric const DWARFLocationExpressionsVector &LinkedLocationExpression, 706*1db9f3b2SDimitry Andric PatchLocation Patch, DebugDieValuePool &AddrPool) { 707*1db9f3b2SDimitry Andric Patch.set(LocListsSectionSize); 708*1db9f3b2SDimitry Andric 709*1db9f3b2SDimitry Andric // Make .debug_loclists the current section. 710*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection()); 711*1db9f3b2SDimitry Andric std::optional<uint64_t> BaseAddress; 712*1db9f3b2SDimitry Andric 713*1db9f3b2SDimitry Andric for (const DWARFLocationExpression &LocExpression : 714*1db9f3b2SDimitry Andric LinkedLocationExpression) { 715*1db9f3b2SDimitry Andric if (LocExpression.Range) { 716*1db9f3b2SDimitry Andric 717*1db9f3b2SDimitry Andric if (!BaseAddress) { 718*1db9f3b2SDimitry Andric 719*1db9f3b2SDimitry Andric BaseAddress = LocExpression.Range->LowPC; 720*1db9f3b2SDimitry Andric 721*1db9f3b2SDimitry Andric // Emit base address. 722*1db9f3b2SDimitry Andric MS->emitInt8(dwarf::DW_LLE_base_addressx); 723*1db9f3b2SDimitry Andric LocListsSectionSize += 1; 724*1db9f3b2SDimitry Andric LocListsSectionSize += 725*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress)); 726*1db9f3b2SDimitry Andric } 727*1db9f3b2SDimitry Andric 728*1db9f3b2SDimitry Andric // Emit type of entry. 729*1db9f3b2SDimitry Andric MS->emitInt8(dwarf::DW_LLE_offset_pair); 730*1db9f3b2SDimitry Andric LocListsSectionSize += 1; 731*1db9f3b2SDimitry Andric 732*1db9f3b2SDimitry Andric // Emit start offset relative to base address. 733*1db9f3b2SDimitry Andric LocListsSectionSize += 734*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(LocExpression.Range->LowPC - *BaseAddress); 735*1db9f3b2SDimitry Andric 736*1db9f3b2SDimitry Andric // Emit end offset relative to base address. 737*1db9f3b2SDimitry Andric LocListsSectionSize += 738*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(LocExpression.Range->HighPC - *BaseAddress); 739*1db9f3b2SDimitry Andric } else { 740*1db9f3b2SDimitry Andric // Emit type of entry. 741*1db9f3b2SDimitry Andric MS->emitInt8(dwarf::DW_LLE_default_location); 742*1db9f3b2SDimitry Andric LocListsSectionSize += 1; 743*1db9f3b2SDimitry Andric } 744*1db9f3b2SDimitry Andric 745*1db9f3b2SDimitry Andric LocListsSectionSize += MS->emitULEB128IntValue(LocExpression.Expr.size()); 746*1db9f3b2SDimitry Andric Asm->OutStreamer->emitBytes(StringRef( 747*1db9f3b2SDimitry Andric (const char *)LocExpression.Expr.data(), LocExpression.Expr.size())); 748*1db9f3b2SDimitry Andric LocListsSectionSize += LocExpression.Expr.size(); 749*1db9f3b2SDimitry Andric } 750*1db9f3b2SDimitry Andric 751*1db9f3b2SDimitry Andric // Emit the terminator entry. 752*1db9f3b2SDimitry Andric MS->emitInt8(dwarf::DW_LLE_end_of_list); 753*1db9f3b2SDimitry Andric LocListsSectionSize += 1; 754*1db9f3b2SDimitry Andric } 755*1db9f3b2SDimitry Andric 756*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableForUnit( 757*1db9f3b2SDimitry Andric const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit, 758*1db9f3b2SDimitry Andric OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool) { 759*1db9f3b2SDimitry Andric // Switch to the section where the table will be emitted into. 760*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfLineSection()); 761*1db9f3b2SDimitry Andric 762*1db9f3b2SDimitry Andric MCSymbol *LineStartSym = MC->createTempSymbol(); 763*1db9f3b2SDimitry Andric MCSymbol *LineEndSym = MC->createTempSymbol(); 764*1db9f3b2SDimitry Andric 765*1db9f3b2SDimitry Andric // unit_length. 766*1db9f3b2SDimitry Andric if (LineTable.Prologue.FormParams.Format == dwarf::DwarfFormat::DWARF64) { 767*1db9f3b2SDimitry Andric MS->emitInt32(dwarf::DW_LENGTH_DWARF64); 768*1db9f3b2SDimitry Andric LineSectionSize += 4; 769*1db9f3b2SDimitry Andric } 770*1db9f3b2SDimitry Andric emitLabelDifference(LineEndSym, LineStartSym, 771*1db9f3b2SDimitry Andric LineTable.Prologue.FormParams.Format, LineSectionSize); 772*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(LineStartSym); 773*1db9f3b2SDimitry Andric 774*1db9f3b2SDimitry Andric // Emit prologue. 775*1db9f3b2SDimitry Andric emitLineTablePrologue(LineTable.Prologue, DebugStrPool, DebugLineStrPool); 776*1db9f3b2SDimitry Andric 777*1db9f3b2SDimitry Andric // Emit rows. 778*1db9f3b2SDimitry Andric emitLineTableRows(LineTable, LineEndSym, 779*1db9f3b2SDimitry Andric Unit.getOrigUnit().getAddressByteSize()); 780*1db9f3b2SDimitry Andric } 781*1db9f3b2SDimitry Andric 782*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue &P, 783*1db9f3b2SDimitry Andric OffsetsStringPool &DebugStrPool, 784*1db9f3b2SDimitry Andric OffsetsStringPool &DebugLineStrPool) { 785*1db9f3b2SDimitry Andric MCSymbol *PrologueStartSym = MC->createTempSymbol(); 786*1db9f3b2SDimitry Andric MCSymbol *PrologueEndSym = MC->createTempSymbol(); 787*1db9f3b2SDimitry Andric 788*1db9f3b2SDimitry Andric // version (uhalf). 789*1db9f3b2SDimitry Andric MS->emitInt16(P.getVersion()); 790*1db9f3b2SDimitry Andric LineSectionSize += 2; 791*1db9f3b2SDimitry Andric if (P.getVersion() == 5) { 792*1db9f3b2SDimitry Andric // address_size (ubyte). 793*1db9f3b2SDimitry Andric MS->emitInt8(P.getAddressSize()); 794*1db9f3b2SDimitry Andric LineSectionSize += 1; 795*1db9f3b2SDimitry Andric 796*1db9f3b2SDimitry Andric // segment_selector_size (ubyte). 797*1db9f3b2SDimitry Andric MS->emitInt8(P.SegSelectorSize); 798*1db9f3b2SDimitry Andric LineSectionSize += 1; 799*1db9f3b2SDimitry Andric } 800*1db9f3b2SDimitry Andric 801*1db9f3b2SDimitry Andric // header_length. 802*1db9f3b2SDimitry Andric emitLabelDifference(PrologueEndSym, PrologueStartSym, P.FormParams.Format, 803*1db9f3b2SDimitry Andric LineSectionSize); 804*1db9f3b2SDimitry Andric 805*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(PrologueStartSym); 806*1db9f3b2SDimitry Andric emitLineTableProloguePayload(P, DebugStrPool, DebugLineStrPool); 807*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(PrologueEndSym); 808*1db9f3b2SDimitry Andric } 809*1db9f3b2SDimitry Andric 810*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable( 811*1db9f3b2SDimitry Andric const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, 812*1db9f3b2SDimitry Andric OffsetsStringPool &DebugLineStrPool) { 813*1db9f3b2SDimitry Andric // include_directories (sequence of path names). 814*1db9f3b2SDimitry Andric for (const DWARFFormValue &Include : P.IncludeDirectories) 815*1db9f3b2SDimitry Andric emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool); 816*1db9f3b2SDimitry Andric // The last entry is followed by a single null byte. 817*1db9f3b2SDimitry Andric MS->emitInt8(0); 818*1db9f3b2SDimitry Andric LineSectionSize += 1; 819*1db9f3b2SDimitry Andric 820*1db9f3b2SDimitry Andric // file_names (sequence of file entries). 821*1db9f3b2SDimitry Andric for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) { 822*1db9f3b2SDimitry Andric // A null-terminated string containing the full or relative path name of a 823*1db9f3b2SDimitry Andric // source file. 824*1db9f3b2SDimitry Andric emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool); 825*1db9f3b2SDimitry Andric // An unsigned LEB128 number representing the directory index of a directory 826*1db9f3b2SDimitry Andric // in the include_directories section. 827*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(File.DirIdx); 828*1db9f3b2SDimitry Andric // An unsigned LEB128 number representing the (implementation-defined) time 829*1db9f3b2SDimitry Andric // of last modification for the file, or 0 if not available. 830*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(File.ModTime); 831*1db9f3b2SDimitry Andric // An unsigned LEB128 number representing the length in bytes of the file, 832*1db9f3b2SDimitry Andric // or 0 if not available. 833*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(File.Length); 834*1db9f3b2SDimitry Andric } 835*1db9f3b2SDimitry Andric // The last entry is followed by a single null byte. 836*1db9f3b2SDimitry Andric MS->emitInt8(0); 837*1db9f3b2SDimitry Andric LineSectionSize += 1; 838*1db9f3b2SDimitry Andric } 839*1db9f3b2SDimitry Andric 840*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable( 841*1db9f3b2SDimitry Andric const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, 842*1db9f3b2SDimitry Andric OffsetsStringPool &DebugLineStrPool) { 843*1db9f3b2SDimitry Andric if (P.IncludeDirectories.empty()) { 844*1db9f3b2SDimitry Andric // directory_entry_format_count(ubyte). 845*1db9f3b2SDimitry Andric MS->emitInt8(0); 846*1db9f3b2SDimitry Andric LineSectionSize += 1; 847*1db9f3b2SDimitry Andric } else { 848*1db9f3b2SDimitry Andric // directory_entry_format_count(ubyte). 849*1db9f3b2SDimitry Andric MS->emitInt8(1); 850*1db9f3b2SDimitry Andric LineSectionSize += 1; 851*1db9f3b2SDimitry Andric 852*1db9f3b2SDimitry Andric // directory_entry_format (sequence of ULEB128 pairs). 853*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path); 854*1db9f3b2SDimitry Andric LineSectionSize += 855*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(P.IncludeDirectories[0].getForm()); 856*1db9f3b2SDimitry Andric } 857*1db9f3b2SDimitry Andric 858*1db9f3b2SDimitry Andric // directories_count (ULEB128). 859*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(P.IncludeDirectories.size()); 860*1db9f3b2SDimitry Andric // directories (sequence of directory names). 861*1db9f3b2SDimitry Andric for (auto Include : P.IncludeDirectories) 862*1db9f3b2SDimitry Andric emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool); 863*1db9f3b2SDimitry Andric 864*1db9f3b2SDimitry Andric bool HasChecksums = P.ContentTypes.HasMD5; 865*1db9f3b2SDimitry Andric bool HasInlineSources = P.ContentTypes.HasSource; 866*1db9f3b2SDimitry Andric 867*1db9f3b2SDimitry Andric if (P.FileNames.empty()) { 868*1db9f3b2SDimitry Andric // file_name_entry_format_count (ubyte). 869*1db9f3b2SDimitry Andric MS->emitInt8(0); 870*1db9f3b2SDimitry Andric LineSectionSize += 1; 871*1db9f3b2SDimitry Andric } else { 872*1db9f3b2SDimitry Andric // file_name_entry_format_count (ubyte). 873*1db9f3b2SDimitry Andric MS->emitInt8(2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0)); 874*1db9f3b2SDimitry Andric LineSectionSize += 1; 875*1db9f3b2SDimitry Andric 876*1db9f3b2SDimitry Andric // file_name_entry_format (sequence of ULEB128 pairs). 877*1db9f3b2SDimitry Andric auto StrForm = P.FileNames[0].Name.getForm(); 878*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path); 879*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(StrForm); 880*1db9f3b2SDimitry Andric 881*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index); 882*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1); 883*1db9f3b2SDimitry Andric 884*1db9f3b2SDimitry Andric if (HasChecksums) { 885*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_MD5); 886*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data16); 887*1db9f3b2SDimitry Andric } 888*1db9f3b2SDimitry Andric 889*1db9f3b2SDimitry Andric if (HasInlineSources) { 890*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source); 891*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(StrForm); 892*1db9f3b2SDimitry Andric } 893*1db9f3b2SDimitry Andric } 894*1db9f3b2SDimitry Andric 895*1db9f3b2SDimitry Andric // file_names_count (ULEB128). 896*1db9f3b2SDimitry Andric LineSectionSize += MS->emitULEB128IntValue(P.FileNames.size()); 897*1db9f3b2SDimitry Andric 898*1db9f3b2SDimitry Andric // file_names (sequence of file name entries). 899*1db9f3b2SDimitry Andric for (auto File : P.FileNames) { 900*1db9f3b2SDimitry Andric emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool); 901*1db9f3b2SDimitry Andric MS->emitInt8(File.DirIdx); 902*1db9f3b2SDimitry Andric LineSectionSize += 1; 903*1db9f3b2SDimitry Andric if (HasChecksums) { 904*1db9f3b2SDimitry Andric MS->emitBinaryData( 905*1db9f3b2SDimitry Andric StringRef(reinterpret_cast<const char *>(File.Checksum.data()), 906*1db9f3b2SDimitry Andric File.Checksum.size())); 907*1db9f3b2SDimitry Andric LineSectionSize += File.Checksum.size(); 908*1db9f3b2SDimitry Andric } 909*1db9f3b2SDimitry Andric if (HasInlineSources) 910*1db9f3b2SDimitry Andric emitLineTableString(P, File.Source, DebugStrPool, DebugLineStrPool); 911*1db9f3b2SDimitry Andric } 912*1db9f3b2SDimitry Andric } 913*1db9f3b2SDimitry Andric 914*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P, 915*1db9f3b2SDimitry Andric const DWARFFormValue &String, 916*1db9f3b2SDimitry Andric OffsetsStringPool &DebugStrPool, 917*1db9f3b2SDimitry Andric OffsetsStringPool &DebugLineStrPool) { 918*1db9f3b2SDimitry Andric std::optional<const char *> StringVal = dwarf::toString(String); 919*1db9f3b2SDimitry Andric if (!StringVal) { 920*1db9f3b2SDimitry Andric warn("Cann't read string from line table."); 921*1db9f3b2SDimitry Andric return; 922*1db9f3b2SDimitry Andric } 923*1db9f3b2SDimitry Andric 924*1db9f3b2SDimitry Andric switch (String.getForm()) { 925*1db9f3b2SDimitry Andric case dwarf::DW_FORM_string: { 926*1db9f3b2SDimitry Andric StringRef TranslatedString = 927*1db9f3b2SDimitry Andric (Translator) ? Translator(*StringVal) : *StringVal; 928*1db9f3b2SDimitry Andric Asm->OutStreamer->emitBytes(TranslatedString.data()); 929*1db9f3b2SDimitry Andric Asm->emitInt8(0); 930*1db9f3b2SDimitry Andric LineSectionSize += TranslatedString.size() + 1; 931*1db9f3b2SDimitry Andric } break; 932*1db9f3b2SDimitry Andric case dwarf::DW_FORM_strp: 933*1db9f3b2SDimitry Andric case dwarf::DW_FORM_line_strp: { 934*1db9f3b2SDimitry Andric DwarfStringPoolEntryRef StringRef = 935*1db9f3b2SDimitry Andric String.getForm() == dwarf::DW_FORM_strp 936*1db9f3b2SDimitry Andric ? DebugStrPool.getEntry(*StringVal) 937*1db9f3b2SDimitry Andric : DebugLineStrPool.getEntry(*StringVal); 938*1db9f3b2SDimitry Andric 939*1db9f3b2SDimitry Andric emitIntOffset(StringRef.getOffset(), P.FormParams.Format, LineSectionSize); 940*1db9f3b2SDimitry Andric } break; 941*1db9f3b2SDimitry Andric default: 942*1db9f3b2SDimitry Andric warn("Unsupported string form inside line table."); 943*1db9f3b2SDimitry Andric break; 944*1db9f3b2SDimitry Andric }; 945*1db9f3b2SDimitry Andric } 946*1db9f3b2SDimitry Andric 947*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableProloguePayload( 948*1db9f3b2SDimitry Andric const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, 949*1db9f3b2SDimitry Andric OffsetsStringPool &DebugLineStrPool) { 950*1db9f3b2SDimitry Andric // minimum_instruction_length (ubyte). 951*1db9f3b2SDimitry Andric MS->emitInt8(P.MinInstLength); 952*1db9f3b2SDimitry Andric LineSectionSize += 1; 953*1db9f3b2SDimitry Andric if (P.FormParams.Version >= 4) { 954*1db9f3b2SDimitry Andric // maximum_operations_per_instruction (ubyte). 955*1db9f3b2SDimitry Andric MS->emitInt8(P.MaxOpsPerInst); 956*1db9f3b2SDimitry Andric LineSectionSize += 1; 957*1db9f3b2SDimitry Andric } 958*1db9f3b2SDimitry Andric // default_is_stmt (ubyte). 959*1db9f3b2SDimitry Andric MS->emitInt8(P.DefaultIsStmt); 960*1db9f3b2SDimitry Andric LineSectionSize += 1; 961*1db9f3b2SDimitry Andric // line_base (sbyte). 962*1db9f3b2SDimitry Andric MS->emitInt8(P.LineBase); 963*1db9f3b2SDimitry Andric LineSectionSize += 1; 964*1db9f3b2SDimitry Andric // line_range (ubyte). 965*1db9f3b2SDimitry Andric MS->emitInt8(P.LineRange); 966*1db9f3b2SDimitry Andric LineSectionSize += 1; 967*1db9f3b2SDimitry Andric // opcode_base (ubyte). 968*1db9f3b2SDimitry Andric MS->emitInt8(P.OpcodeBase); 969*1db9f3b2SDimitry Andric LineSectionSize += 1; 970*1db9f3b2SDimitry Andric 971*1db9f3b2SDimitry Andric // standard_opcode_lengths (array of ubyte). 972*1db9f3b2SDimitry Andric for (auto Length : P.StandardOpcodeLengths) { 973*1db9f3b2SDimitry Andric MS->emitInt8(Length); 974*1db9f3b2SDimitry Andric LineSectionSize += 1; 975*1db9f3b2SDimitry Andric } 976*1db9f3b2SDimitry Andric 977*1db9f3b2SDimitry Andric if (P.FormParams.Version < 5) 978*1db9f3b2SDimitry Andric emitLineTablePrologueV2IncludeAndFileTable(P, DebugStrPool, 979*1db9f3b2SDimitry Andric DebugLineStrPool); 980*1db9f3b2SDimitry Andric else 981*1db9f3b2SDimitry Andric emitLineTablePrologueV5IncludeAndFileTable(P, DebugStrPool, 982*1db9f3b2SDimitry Andric DebugLineStrPool); 983*1db9f3b2SDimitry Andric } 984*1db9f3b2SDimitry Andric 985*1db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableRows( 986*1db9f3b2SDimitry Andric const DWARFDebugLine::LineTable &LineTable, MCSymbol *LineEndSym, 987*1db9f3b2SDimitry Andric unsigned AddressByteSize) { 988*1db9f3b2SDimitry Andric 989*1db9f3b2SDimitry Andric MCDwarfLineTableParams Params; 990*1db9f3b2SDimitry Andric Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase; 991*1db9f3b2SDimitry Andric Params.DWARF2LineBase = LineTable.Prologue.LineBase; 992*1db9f3b2SDimitry Andric Params.DWARF2LineRange = LineTable.Prologue.LineRange; 993*1db9f3b2SDimitry Andric 994*1db9f3b2SDimitry Andric SmallString<128> EncodingBuffer; 995*1db9f3b2SDimitry Andric 996*1db9f3b2SDimitry Andric if (LineTable.Rows.empty()) { 997*1db9f3b2SDimitry Andric // We only have the dummy entry, dsymutil emits an entry with a 0 998*1db9f3b2SDimitry Andric // address in that case. 999*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0, 1000*1db9f3b2SDimitry Andric EncodingBuffer); 1001*1db9f3b2SDimitry Andric MS->emitBytes(EncodingBuffer); 1002*1db9f3b2SDimitry Andric LineSectionSize += EncodingBuffer.size(); 1003*1db9f3b2SDimitry Andric MS->emitLabel(LineEndSym); 1004*1db9f3b2SDimitry Andric return; 1005*1db9f3b2SDimitry Andric } 1006*1db9f3b2SDimitry Andric 1007*1db9f3b2SDimitry Andric // Line table state machine fields 1008*1db9f3b2SDimitry Andric unsigned FileNum = 1; 1009*1db9f3b2SDimitry Andric unsigned LastLine = 1; 1010*1db9f3b2SDimitry Andric unsigned Column = 0; 1011*1db9f3b2SDimitry Andric unsigned IsStatement = 1; 1012*1db9f3b2SDimitry Andric unsigned Isa = 0; 1013*1db9f3b2SDimitry Andric uint64_t Address = -1ULL; 1014*1db9f3b2SDimitry Andric 1015*1db9f3b2SDimitry Andric unsigned RowsSinceLastSequence = 0; 1016*1db9f3b2SDimitry Andric 1017*1db9f3b2SDimitry Andric for (const DWARFDebugLine::Row &Row : LineTable.Rows) { 1018*1db9f3b2SDimitry Andric int64_t AddressDelta; 1019*1db9f3b2SDimitry Andric if (Address == -1ULL) { 1020*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_extended_op, 1); 1021*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(AddressByteSize + 1); 1022*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNE_set_address, 1); 1023*1db9f3b2SDimitry Andric MS->emitIntValue(Row.Address.Address, AddressByteSize); 1024*1db9f3b2SDimitry Andric LineSectionSize += 1025*1db9f3b2SDimitry Andric 2 + AddressByteSize + getULEB128Size(AddressByteSize + 1); 1026*1db9f3b2SDimitry Andric AddressDelta = 0; 1027*1db9f3b2SDimitry Andric } else { 1028*1db9f3b2SDimitry Andric AddressDelta = 1029*1db9f3b2SDimitry Andric (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength; 1030*1db9f3b2SDimitry Andric } 1031*1db9f3b2SDimitry Andric 1032*1db9f3b2SDimitry Andric // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable. 1033*1db9f3b2SDimitry Andric // We should find a way to share this code, but the current compatibility 1034*1db9f3b2SDimitry Andric // requirement with classic dsymutil makes it hard. Revisit that once this 1035*1db9f3b2SDimitry Andric // requirement is dropped. 1036*1db9f3b2SDimitry Andric 1037*1db9f3b2SDimitry Andric if (FileNum != Row.File) { 1038*1db9f3b2SDimitry Andric FileNum = Row.File; 1039*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_set_file, 1); 1040*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(FileNum); 1041*1db9f3b2SDimitry Andric LineSectionSize += 1 + getULEB128Size(FileNum); 1042*1db9f3b2SDimitry Andric } 1043*1db9f3b2SDimitry Andric if (Column != Row.Column) { 1044*1db9f3b2SDimitry Andric Column = Row.Column; 1045*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_set_column, 1); 1046*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(Column); 1047*1db9f3b2SDimitry Andric LineSectionSize += 1 + getULEB128Size(Column); 1048*1db9f3b2SDimitry Andric } 1049*1db9f3b2SDimitry Andric 1050*1db9f3b2SDimitry Andric // FIXME: We should handle the discriminator here, but dsymutil doesn't 1051*1db9f3b2SDimitry Andric // consider it, thus ignore it for now. 1052*1db9f3b2SDimitry Andric 1053*1db9f3b2SDimitry Andric if (Isa != Row.Isa) { 1054*1db9f3b2SDimitry Andric Isa = Row.Isa; 1055*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_set_isa, 1); 1056*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(Isa); 1057*1db9f3b2SDimitry Andric LineSectionSize += 1 + getULEB128Size(Isa); 1058*1db9f3b2SDimitry Andric } 1059*1db9f3b2SDimitry Andric if (IsStatement != Row.IsStmt) { 1060*1db9f3b2SDimitry Andric IsStatement = Row.IsStmt; 1061*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_negate_stmt, 1); 1062*1db9f3b2SDimitry Andric LineSectionSize += 1; 1063*1db9f3b2SDimitry Andric } 1064*1db9f3b2SDimitry Andric if (Row.BasicBlock) { 1065*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_set_basic_block, 1); 1066*1db9f3b2SDimitry Andric LineSectionSize += 1; 1067*1db9f3b2SDimitry Andric } 1068*1db9f3b2SDimitry Andric 1069*1db9f3b2SDimitry Andric if (Row.PrologueEnd) { 1070*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_set_prologue_end, 1); 1071*1db9f3b2SDimitry Andric LineSectionSize += 1; 1072*1db9f3b2SDimitry Andric } 1073*1db9f3b2SDimitry Andric 1074*1db9f3b2SDimitry Andric if (Row.EpilogueBegin) { 1075*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1); 1076*1db9f3b2SDimitry Andric LineSectionSize += 1; 1077*1db9f3b2SDimitry Andric } 1078*1db9f3b2SDimitry Andric 1079*1db9f3b2SDimitry Andric int64_t LineDelta = int64_t(Row.Line) - LastLine; 1080*1db9f3b2SDimitry Andric if (!Row.EndSequence) { 1081*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta, 1082*1db9f3b2SDimitry Andric EncodingBuffer); 1083*1db9f3b2SDimitry Andric MS->emitBytes(EncodingBuffer); 1084*1db9f3b2SDimitry Andric LineSectionSize += EncodingBuffer.size(); 1085*1db9f3b2SDimitry Andric EncodingBuffer.resize(0); 1086*1db9f3b2SDimitry Andric Address = Row.Address.Address; 1087*1db9f3b2SDimitry Andric LastLine = Row.Line; 1088*1db9f3b2SDimitry Andric RowsSinceLastSequence++; 1089*1db9f3b2SDimitry Andric } else { 1090*1db9f3b2SDimitry Andric if (LineDelta) { 1091*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_advance_line, 1); 1092*1db9f3b2SDimitry Andric MS->emitSLEB128IntValue(LineDelta); 1093*1db9f3b2SDimitry Andric LineSectionSize += 1 + getSLEB128Size(LineDelta); 1094*1db9f3b2SDimitry Andric } 1095*1db9f3b2SDimitry Andric if (AddressDelta) { 1096*1db9f3b2SDimitry Andric MS->emitIntValue(dwarf::DW_LNS_advance_pc, 1); 1097*1db9f3b2SDimitry Andric MS->emitULEB128IntValue(AddressDelta); 1098*1db9f3b2SDimitry Andric LineSectionSize += 1 + getULEB128Size(AddressDelta); 1099*1db9f3b2SDimitry Andric } 1100*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 1101*1db9f3b2SDimitry Andric 0, EncodingBuffer); 1102*1db9f3b2SDimitry Andric MS->emitBytes(EncodingBuffer); 1103*1db9f3b2SDimitry Andric LineSectionSize += EncodingBuffer.size(); 1104*1db9f3b2SDimitry Andric EncodingBuffer.resize(0); 1105*1db9f3b2SDimitry Andric Address = -1ULL; 1106*1db9f3b2SDimitry Andric LastLine = FileNum = IsStatement = 1; 1107*1db9f3b2SDimitry Andric RowsSinceLastSequence = Column = Isa = 0; 1108*1db9f3b2SDimitry Andric } 1109*1db9f3b2SDimitry Andric } 1110*1db9f3b2SDimitry Andric 1111*1db9f3b2SDimitry Andric if (RowsSinceLastSequence) { 1112*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0, 1113*1db9f3b2SDimitry Andric EncodingBuffer); 1114*1db9f3b2SDimitry Andric MS->emitBytes(EncodingBuffer); 1115*1db9f3b2SDimitry Andric LineSectionSize += EncodingBuffer.size(); 1116*1db9f3b2SDimitry Andric EncodingBuffer.resize(0); 1117*1db9f3b2SDimitry Andric } 1118*1db9f3b2SDimitry Andric 1119*1db9f3b2SDimitry Andric MS->emitLabel(LineEndSym); 1120*1db9f3b2SDimitry Andric } 1121*1db9f3b2SDimitry Andric 1122*1db9f3b2SDimitry Andric void DwarfStreamer::emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format, 1123*1db9f3b2SDimitry Andric uint64_t &SectionSize) { 1124*1db9f3b2SDimitry Andric uint8_t Size = dwarf::getDwarfOffsetByteSize(Format); 1125*1db9f3b2SDimitry Andric MS->emitIntValue(Offset, Size); 1126*1db9f3b2SDimitry Andric SectionSize += Size; 1127*1db9f3b2SDimitry Andric } 1128*1db9f3b2SDimitry Andric 1129*1db9f3b2SDimitry Andric void DwarfStreamer::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 1130*1db9f3b2SDimitry Andric dwarf::DwarfFormat Format, 1131*1db9f3b2SDimitry Andric uint64_t &SectionSize) { 1132*1db9f3b2SDimitry Andric uint8_t Size = dwarf::getDwarfOffsetByteSize(Format); 1133*1db9f3b2SDimitry Andric Asm->emitLabelDifference(Hi, Lo, Size); 1134*1db9f3b2SDimitry Andric SectionSize += Size; 1135*1db9f3b2SDimitry Andric } 1136*1db9f3b2SDimitry Andric 1137*1db9f3b2SDimitry Andric /// Emit the pubnames or pubtypes section contribution for \p 1138*1db9f3b2SDimitry Andric /// Unit into \p Sec. The data is provided in \p Names. 1139*1db9f3b2SDimitry Andric void DwarfStreamer::emitPubSectionForUnit( 1140*1db9f3b2SDimitry Andric MCSection *Sec, StringRef SecName, const CompileUnit &Unit, 1141*1db9f3b2SDimitry Andric const std::vector<CompileUnit::AccelInfo> &Names) { 1142*1db9f3b2SDimitry Andric if (Names.empty()) 1143*1db9f3b2SDimitry Andric return; 1144*1db9f3b2SDimitry Andric 1145*1db9f3b2SDimitry Andric // Start the dwarf pubnames section. 1146*1db9f3b2SDimitry Andric Asm->OutStreamer->switchSection(Sec); 1147*1db9f3b2SDimitry Andric MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin"); 1148*1db9f3b2SDimitry Andric MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end"); 1149*1db9f3b2SDimitry Andric 1150*1db9f3b2SDimitry Andric bool HeaderEmitted = false; 1151*1db9f3b2SDimitry Andric // Emit the pubnames for this compilation unit. 1152*1db9f3b2SDimitry Andric for (const auto &Name : Names) { 1153*1db9f3b2SDimitry Andric if (Name.SkipPubSection) 1154*1db9f3b2SDimitry Andric continue; 1155*1db9f3b2SDimitry Andric 1156*1db9f3b2SDimitry Andric if (!HeaderEmitted) { 1157*1db9f3b2SDimitry Andric // Emit the header. 1158*1db9f3b2SDimitry Andric Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Length 1159*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(BeginLabel); 1160*1db9f3b2SDimitry Andric Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION); // Version 1161*1db9f3b2SDimitry Andric Asm->emitInt32(Unit.getStartOffset()); // Unit offset 1162*1db9f3b2SDimitry Andric Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size 1163*1db9f3b2SDimitry Andric HeaderEmitted = true; 1164*1db9f3b2SDimitry Andric } 1165*1db9f3b2SDimitry Andric Asm->emitInt32(Name.Die->getOffset()); 1166*1db9f3b2SDimitry Andric 1167*1db9f3b2SDimitry Andric // Emit the string itself. 1168*1db9f3b2SDimitry Andric Asm->OutStreamer->emitBytes(Name.Name.getString()); 1169*1db9f3b2SDimitry Andric // Emit a null terminator. 1170*1db9f3b2SDimitry Andric Asm->emitInt8(0); 1171*1db9f3b2SDimitry Andric } 1172*1db9f3b2SDimitry Andric 1173*1db9f3b2SDimitry Andric if (!HeaderEmitted) 1174*1db9f3b2SDimitry Andric return; 1175*1db9f3b2SDimitry Andric Asm->emitInt32(0); // End marker. 1176*1db9f3b2SDimitry Andric Asm->OutStreamer->emitLabel(EndLabel); 1177*1db9f3b2SDimitry Andric } 1178*1db9f3b2SDimitry Andric 1179*1db9f3b2SDimitry Andric /// Emit .debug_pubnames for \p Unit. 1180*1db9f3b2SDimitry Andric void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) { 1181*1db9f3b2SDimitry Andric emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(), 1182*1db9f3b2SDimitry Andric "names", Unit, Unit.getPubnames()); 1183*1db9f3b2SDimitry Andric } 1184*1db9f3b2SDimitry Andric 1185*1db9f3b2SDimitry Andric /// Emit .debug_pubtypes for \p Unit. 1186*1db9f3b2SDimitry Andric void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) { 1187*1db9f3b2SDimitry Andric emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(), 1188*1db9f3b2SDimitry Andric "types", Unit, Unit.getPubtypes()); 1189*1db9f3b2SDimitry Andric } 1190*1db9f3b2SDimitry Andric 1191*1db9f3b2SDimitry Andric /// Emit a CIE into the debug_frame section. 1192*1db9f3b2SDimitry Andric void DwarfStreamer::emitCIE(StringRef CIEBytes) { 1193*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); 1194*1db9f3b2SDimitry Andric 1195*1db9f3b2SDimitry Andric MS->emitBytes(CIEBytes); 1196*1db9f3b2SDimitry Andric FrameSectionSize += CIEBytes.size(); 1197*1db9f3b2SDimitry Andric } 1198*1db9f3b2SDimitry Andric 1199*1db9f3b2SDimitry Andric /// Emit a FDE into the debug_frame section. \p FDEBytes 1200*1db9f3b2SDimitry Andric /// contains the FDE data without the length, CIE offset and address 1201*1db9f3b2SDimitry Andric /// which will be replaced with the parameter values. 1202*1db9f3b2SDimitry Andric void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize, 1203*1db9f3b2SDimitry Andric uint64_t Address, StringRef FDEBytes) { 1204*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); 1205*1db9f3b2SDimitry Andric 1206*1db9f3b2SDimitry Andric MS->emitIntValue(FDEBytes.size() + 4 + AddrSize, 4); 1207*1db9f3b2SDimitry Andric MS->emitIntValue(CIEOffset, 4); 1208*1db9f3b2SDimitry Andric MS->emitIntValue(Address, AddrSize); 1209*1db9f3b2SDimitry Andric MS->emitBytes(FDEBytes); 1210*1db9f3b2SDimitry Andric FrameSectionSize += FDEBytes.size() + 8 + AddrSize; 1211*1db9f3b2SDimitry Andric } 1212*1db9f3b2SDimitry Andric 1213*1db9f3b2SDimitry Andric void DwarfStreamer::emitMacroTables(DWARFContext *Context, 1214*1db9f3b2SDimitry Andric const Offset2UnitMap &UnitMacroMap, 1215*1db9f3b2SDimitry Andric OffsetsStringPool &StringPool) { 1216*1db9f3b2SDimitry Andric assert(Context != nullptr && "Empty DWARF context"); 1217*1db9f3b2SDimitry Andric 1218*1db9f3b2SDimitry Andric // Check for .debug_macinfo table. 1219*1db9f3b2SDimitry Andric if (const DWARFDebugMacro *Table = Context->getDebugMacinfo()) { 1220*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection()); 1221*1db9f3b2SDimitry Andric emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacInfoSectionSize); 1222*1db9f3b2SDimitry Andric } 1223*1db9f3b2SDimitry Andric 1224*1db9f3b2SDimitry Andric // Check for .debug_macro table. 1225*1db9f3b2SDimitry Andric if (const DWARFDebugMacro *Table = Context->getDebugMacro()) { 1226*1db9f3b2SDimitry Andric MS->switchSection(MC->getObjectFileInfo()->getDwarfMacroSection()); 1227*1db9f3b2SDimitry Andric emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacroSectionSize); 1228*1db9f3b2SDimitry Andric } 1229*1db9f3b2SDimitry Andric } 1230*1db9f3b2SDimitry Andric 1231*1db9f3b2SDimitry Andric void DwarfStreamer::emitMacroTableImpl(const DWARFDebugMacro *MacroTable, 1232*1db9f3b2SDimitry Andric const Offset2UnitMap &UnitMacroMap, 1233*1db9f3b2SDimitry Andric OffsetsStringPool &StringPool, 1234*1db9f3b2SDimitry Andric uint64_t &OutOffset) { 1235*1db9f3b2SDimitry Andric bool DefAttributeIsReported = false; 1236*1db9f3b2SDimitry Andric bool UndefAttributeIsReported = false; 1237*1db9f3b2SDimitry Andric bool ImportAttributeIsReported = false; 1238*1db9f3b2SDimitry Andric for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) { 1239*1db9f3b2SDimitry Andric Offset2UnitMap::const_iterator UnitIt = UnitMacroMap.find(List.Offset); 1240*1db9f3b2SDimitry Andric if (UnitIt == UnitMacroMap.end()) { 1241*1db9f3b2SDimitry Andric warn(formatv( 1242*1db9f3b2SDimitry Andric "couldn`t find compile unit for the macro table with offset = {0:x}", 1243*1db9f3b2SDimitry Andric List.Offset)); 1244*1db9f3b2SDimitry Andric continue; 1245*1db9f3b2SDimitry Andric } 1246*1db9f3b2SDimitry Andric 1247*1db9f3b2SDimitry Andric // Skip macro table if the unit was not cloned. 1248*1db9f3b2SDimitry Andric DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE(); 1249*1db9f3b2SDimitry Andric if (OutputUnitDIE == nullptr) 1250*1db9f3b2SDimitry Andric continue; 1251*1db9f3b2SDimitry Andric 1252*1db9f3b2SDimitry Andric // Update macro attribute of cloned compile unit with the proper offset to 1253*1db9f3b2SDimitry Andric // the macro table. 1254*1db9f3b2SDimitry Andric bool hasDWARFv5Header = false; 1255*1db9f3b2SDimitry Andric for (auto &V : OutputUnitDIE->values()) { 1256*1db9f3b2SDimitry Andric if (V.getAttribute() == dwarf::DW_AT_macro_info) { 1257*1db9f3b2SDimitry Andric V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset)); 1258*1db9f3b2SDimitry Andric break; 1259*1db9f3b2SDimitry Andric } else if (V.getAttribute() == dwarf::DW_AT_macros) { 1260*1db9f3b2SDimitry Andric hasDWARFv5Header = true; 1261*1db9f3b2SDimitry Andric V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset)); 1262*1db9f3b2SDimitry Andric break; 1263*1db9f3b2SDimitry Andric } 1264*1db9f3b2SDimitry Andric } 1265*1db9f3b2SDimitry Andric 1266*1db9f3b2SDimitry Andric // Write DWARFv5 header. 1267*1db9f3b2SDimitry Andric if (hasDWARFv5Header) { 1268*1db9f3b2SDimitry Andric // Write header version. 1269*1db9f3b2SDimitry Andric MS->emitIntValue(List.Header.Version, sizeof(List.Header.Version)); 1270*1db9f3b2SDimitry Andric OutOffset += sizeof(List.Header.Version); 1271*1db9f3b2SDimitry Andric 1272*1db9f3b2SDimitry Andric uint8_t Flags = List.Header.Flags; 1273*1db9f3b2SDimitry Andric 1274*1db9f3b2SDimitry Andric // Check for OPCODE_OPERANDS_TABLE. 1275*1db9f3b2SDimitry Andric if (Flags & 1276*1db9f3b2SDimitry Andric DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) { 1277*1db9f3b2SDimitry Andric Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE; 1278*1db9f3b2SDimitry Andric warn("opcode_operands_table is not supported yet."); 1279*1db9f3b2SDimitry Andric } 1280*1db9f3b2SDimitry Andric 1281*1db9f3b2SDimitry Andric // Check for DEBUG_LINE_OFFSET. 1282*1db9f3b2SDimitry Andric std::optional<uint64_t> StmtListOffset; 1283*1db9f3b2SDimitry Andric if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) { 1284*1db9f3b2SDimitry Andric // Get offset to the line table from the cloned compile unit. 1285*1db9f3b2SDimitry Andric for (auto &V : OutputUnitDIE->values()) { 1286*1db9f3b2SDimitry Andric if (V.getAttribute() == dwarf::DW_AT_stmt_list) { 1287*1db9f3b2SDimitry Andric StmtListOffset = V.getDIEInteger().getValue(); 1288*1db9f3b2SDimitry Andric break; 1289*1db9f3b2SDimitry Andric } 1290*1db9f3b2SDimitry Andric } 1291*1db9f3b2SDimitry Andric 1292*1db9f3b2SDimitry Andric if (!StmtListOffset) { 1293*1db9f3b2SDimitry Andric Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET; 1294*1db9f3b2SDimitry Andric warn("couldn`t find line table for macro table."); 1295*1db9f3b2SDimitry Andric } 1296*1db9f3b2SDimitry Andric } 1297*1db9f3b2SDimitry Andric 1298*1db9f3b2SDimitry Andric // Write flags. 1299*1db9f3b2SDimitry Andric MS->emitIntValue(Flags, sizeof(Flags)); 1300*1db9f3b2SDimitry Andric OutOffset += sizeof(Flags); 1301*1db9f3b2SDimitry Andric 1302*1db9f3b2SDimitry Andric // Write offset to line table. 1303*1db9f3b2SDimitry Andric if (StmtListOffset) { 1304*1db9f3b2SDimitry Andric MS->emitIntValue(*StmtListOffset, List.Header.getOffsetByteSize()); 1305*1db9f3b2SDimitry Andric OutOffset += List.Header.getOffsetByteSize(); 1306*1db9f3b2SDimitry Andric } 1307*1db9f3b2SDimitry Andric } 1308*1db9f3b2SDimitry Andric 1309*1db9f3b2SDimitry Andric // Write macro entries. 1310*1db9f3b2SDimitry Andric for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) { 1311*1db9f3b2SDimitry Andric if (MacroEntry.Type == 0) { 1312*1db9f3b2SDimitry Andric OutOffset += MS->emitULEB128IntValue(MacroEntry.Type); 1313*1db9f3b2SDimitry Andric continue; 1314*1db9f3b2SDimitry Andric } 1315*1db9f3b2SDimitry Andric 1316*1db9f3b2SDimitry Andric uint8_t MacroType = MacroEntry.Type; 1317*1db9f3b2SDimitry Andric switch (MacroType) { 1318*1db9f3b2SDimitry Andric default: { 1319*1db9f3b2SDimitry Andric bool HasVendorSpecificExtension = 1320*1db9f3b2SDimitry Andric (!hasDWARFv5Header && MacroType == dwarf::DW_MACINFO_vendor_ext) || 1321*1db9f3b2SDimitry Andric (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user && 1322*1db9f3b2SDimitry Andric MacroType <= dwarf::DW_MACRO_hi_user)); 1323*1db9f3b2SDimitry Andric 1324*1db9f3b2SDimitry Andric if (HasVendorSpecificExtension) { 1325*1db9f3b2SDimitry Andric // Write macinfo type. 1326*1db9f3b2SDimitry Andric MS->emitIntValue(MacroType, 1); 1327*1db9f3b2SDimitry Andric OutOffset++; 1328*1db9f3b2SDimitry Andric 1329*1db9f3b2SDimitry Andric // Write vendor extension constant. 1330*1db9f3b2SDimitry Andric OutOffset += MS->emitULEB128IntValue(MacroEntry.ExtConstant); 1331*1db9f3b2SDimitry Andric 1332*1db9f3b2SDimitry Andric // Write vendor extension string. 1333*1db9f3b2SDimitry Andric StringRef String = MacroEntry.ExtStr; 1334*1db9f3b2SDimitry Andric MS->emitBytes(String); 1335*1db9f3b2SDimitry Andric MS->emitIntValue(0, 1); 1336*1db9f3b2SDimitry Andric OutOffset += String.size() + 1; 1337*1db9f3b2SDimitry Andric } else 1338*1db9f3b2SDimitry Andric warn("unknown macro type. skip."); 1339*1db9f3b2SDimitry Andric } break; 1340*1db9f3b2SDimitry Andric // debug_macro and debug_macinfo share some common encodings. 1341*1db9f3b2SDimitry Andric // DW_MACRO_define == DW_MACINFO_define 1342*1db9f3b2SDimitry Andric // DW_MACRO_undef == DW_MACINFO_undef 1343*1db9f3b2SDimitry Andric // DW_MACRO_start_file == DW_MACINFO_start_file 1344*1db9f3b2SDimitry Andric // DW_MACRO_end_file == DW_MACINFO_end_file 1345*1db9f3b2SDimitry Andric // For readibility/uniformity we are using DW_MACRO_*. 1346*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_define: 1347*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_undef: { 1348*1db9f3b2SDimitry Andric // Write macinfo type. 1349*1db9f3b2SDimitry Andric MS->emitIntValue(MacroType, 1); 1350*1db9f3b2SDimitry Andric OutOffset++; 1351*1db9f3b2SDimitry Andric 1352*1db9f3b2SDimitry Andric // Write source line. 1353*1db9f3b2SDimitry Andric OutOffset += MS->emitULEB128IntValue(MacroEntry.Line); 1354*1db9f3b2SDimitry Andric 1355*1db9f3b2SDimitry Andric // Write macro string. 1356*1db9f3b2SDimitry Andric StringRef String = MacroEntry.MacroStr; 1357*1db9f3b2SDimitry Andric MS->emitBytes(String); 1358*1db9f3b2SDimitry Andric MS->emitIntValue(0, 1); 1359*1db9f3b2SDimitry Andric OutOffset += String.size() + 1; 1360*1db9f3b2SDimitry Andric } break; 1361*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_define_strp: 1362*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_undef_strp: 1363*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_define_strx: 1364*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_undef_strx: { 1365*1db9f3b2SDimitry Andric assert(UnitIt->second->getOrigUnit().getVersion() >= 5); 1366*1db9f3b2SDimitry Andric 1367*1db9f3b2SDimitry Andric // DW_MACRO_*_strx forms are not supported currently. 1368*1db9f3b2SDimitry Andric // Convert to *_strp. 1369*1db9f3b2SDimitry Andric switch (MacroType) { 1370*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_define_strx: { 1371*1db9f3b2SDimitry Andric MacroType = dwarf::DW_MACRO_define_strp; 1372*1db9f3b2SDimitry Andric if (!DefAttributeIsReported) { 1373*1db9f3b2SDimitry Andric warn("DW_MACRO_define_strx unsupported yet. Convert to " 1374*1db9f3b2SDimitry Andric "DW_MACRO_define_strp."); 1375*1db9f3b2SDimitry Andric DefAttributeIsReported = true; 1376*1db9f3b2SDimitry Andric } 1377*1db9f3b2SDimitry Andric } break; 1378*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_undef_strx: { 1379*1db9f3b2SDimitry Andric MacroType = dwarf::DW_MACRO_undef_strp; 1380*1db9f3b2SDimitry Andric if (!UndefAttributeIsReported) { 1381*1db9f3b2SDimitry Andric warn("DW_MACRO_undef_strx unsupported yet. Convert to " 1382*1db9f3b2SDimitry Andric "DW_MACRO_undef_strp."); 1383*1db9f3b2SDimitry Andric UndefAttributeIsReported = true; 1384*1db9f3b2SDimitry Andric } 1385*1db9f3b2SDimitry Andric } break; 1386*1db9f3b2SDimitry Andric default: 1387*1db9f3b2SDimitry Andric // Nothing to do. 1388*1db9f3b2SDimitry Andric break; 1389*1db9f3b2SDimitry Andric } 1390*1db9f3b2SDimitry Andric 1391*1db9f3b2SDimitry Andric // Write macinfo type. 1392*1db9f3b2SDimitry Andric MS->emitIntValue(MacroType, 1); 1393*1db9f3b2SDimitry Andric OutOffset++; 1394*1db9f3b2SDimitry Andric 1395*1db9f3b2SDimitry Andric // Write source line. 1396*1db9f3b2SDimitry Andric OutOffset += MS->emitULEB128IntValue(MacroEntry.Line); 1397*1db9f3b2SDimitry Andric 1398*1db9f3b2SDimitry Andric // Write macro string. 1399*1db9f3b2SDimitry Andric DwarfStringPoolEntryRef EntryRef = 1400*1db9f3b2SDimitry Andric StringPool.getEntry(MacroEntry.MacroStr); 1401*1db9f3b2SDimitry Andric MS->emitIntValue(EntryRef.getOffset(), List.Header.getOffsetByteSize()); 1402*1db9f3b2SDimitry Andric OutOffset += List.Header.getOffsetByteSize(); 1403*1db9f3b2SDimitry Andric break; 1404*1db9f3b2SDimitry Andric } 1405*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_start_file: { 1406*1db9f3b2SDimitry Andric // Write macinfo type. 1407*1db9f3b2SDimitry Andric MS->emitIntValue(MacroType, 1); 1408*1db9f3b2SDimitry Andric OutOffset++; 1409*1db9f3b2SDimitry Andric // Write source line. 1410*1db9f3b2SDimitry Andric OutOffset += MS->emitULEB128IntValue(MacroEntry.Line); 1411*1db9f3b2SDimitry Andric // Write source file id. 1412*1db9f3b2SDimitry Andric OutOffset += MS->emitULEB128IntValue(MacroEntry.File); 1413*1db9f3b2SDimitry Andric } break; 1414*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_end_file: { 1415*1db9f3b2SDimitry Andric // Write macinfo type. 1416*1db9f3b2SDimitry Andric MS->emitIntValue(MacroType, 1); 1417*1db9f3b2SDimitry Andric OutOffset++; 1418*1db9f3b2SDimitry Andric } break; 1419*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_import: 1420*1db9f3b2SDimitry Andric case dwarf::DW_MACRO_import_sup: { 1421*1db9f3b2SDimitry Andric if (!ImportAttributeIsReported) { 1422*1db9f3b2SDimitry Andric warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. " 1423*1db9f3b2SDimitry Andric "remove."); 1424*1db9f3b2SDimitry Andric ImportAttributeIsReported = true; 1425*1db9f3b2SDimitry Andric } 1426*1db9f3b2SDimitry Andric } break; 1427*1db9f3b2SDimitry Andric } 1428*1db9f3b2SDimitry Andric } 1429*1db9f3b2SDimitry Andric } 1430*1db9f3b2SDimitry Andric } 1431