11db9f3b2SDimitry Andric //===- DwarfStreamer.cpp --------------------------------------------------===//
21db9f3b2SDimitry Andric //
31db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
51db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61db9f3b2SDimitry Andric //
71db9f3b2SDimitry Andric //===----------------------------------------------------------------------===//
81db9f3b2SDimitry Andric 
91db9f3b2SDimitry Andric #include "llvm/DWARFLinker/Classic/DWARFStreamer.h"
101db9f3b2SDimitry Andric #include "llvm/CodeGen/NonRelocatableStringpool.h"
111db9f3b2SDimitry Andric #include "llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h"
121db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFContext.h"
131db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
141db9f3b2SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
151db9f3b2SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
161db9f3b2SDimitry Andric #include "llvm/MC/MCDwarf.h"
171db9f3b2SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
181db9f3b2SDimitry Andric #include "llvm/MC/MCSection.h"
191db9f3b2SDimitry Andric #include "llvm/MC/MCStreamer.h"
201db9f3b2SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
211db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
221db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptionsCommandFlags.h"
231db9f3b2SDimitry Andric #include "llvm/MC/TargetRegistry.h"
241db9f3b2SDimitry Andric #include "llvm/Support/FormatVariadic.h"
251db9f3b2SDimitry Andric #include "llvm/Support/LEB128.h"
261db9f3b2SDimitry Andric #include "llvm/Target/TargetOptions.h"
271db9f3b2SDimitry Andric #include "llvm/TargetParser/Triple.h"
281db9f3b2SDimitry Andric 
291db9f3b2SDimitry Andric using namespace llvm;
301db9f3b2SDimitry Andric using namespace dwarf_linker;
311db9f3b2SDimitry Andric using namespace dwarf_linker::classic;
321db9f3b2SDimitry Andric 
createStreamer(const Triple & TheTriple,DWARFLinkerBase::OutputFileType FileType,raw_pwrite_stream & OutFile,DWARFLinkerBase::TranslatorFuncTy Translator,DWARFLinkerBase::MessageHandlerTy Warning)33*7a6dacacSDimitry Andric Expected<std::unique_ptr<DwarfStreamer>> DwarfStreamer::createStreamer(
34*7a6dacacSDimitry Andric     const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType,
35*7a6dacacSDimitry Andric     raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator,
36*7a6dacacSDimitry Andric     DWARFLinkerBase::MessageHandlerTy Warning) {
37*7a6dacacSDimitry Andric   std::unique_ptr<DwarfStreamer> Streamer =
38*7a6dacacSDimitry Andric       std::make_unique<DwarfStreamer>(FileType, OutFile, Translator, Warning);
39*7a6dacacSDimitry Andric   if (Error Err = Streamer->init(TheTriple, "__DWARF"))
40*7a6dacacSDimitry Andric     return std::move(Err);
41*7a6dacacSDimitry Andric 
42*7a6dacacSDimitry Andric   return std::move(Streamer);
43*7a6dacacSDimitry Andric }
44*7a6dacacSDimitry Andric 
init(Triple TheTriple,StringRef Swift5ReflectionSegmentName)451db9f3b2SDimitry Andric Error DwarfStreamer::init(Triple TheTriple,
461db9f3b2SDimitry Andric                           StringRef Swift5ReflectionSegmentName) {
471db9f3b2SDimitry Andric   std::string ErrorStr;
481db9f3b2SDimitry Andric   std::string TripleName;
491db9f3b2SDimitry Andric 
501db9f3b2SDimitry Andric   // Get the target.
511db9f3b2SDimitry Andric   const Target *TheTarget =
521db9f3b2SDimitry Andric       TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
531db9f3b2SDimitry Andric   if (!TheTarget)
541db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument, ErrorStr.c_str());
551db9f3b2SDimitry Andric 
561db9f3b2SDimitry Andric   TripleName = TheTriple.getTriple();
571db9f3b2SDimitry Andric 
581db9f3b2SDimitry Andric   // Create all the MC Objects.
591db9f3b2SDimitry Andric   MRI.reset(TheTarget->createMCRegInfo(TripleName));
601db9f3b2SDimitry Andric   if (!MRI)
611db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
621db9f3b2SDimitry Andric                              "no register info for target %s",
631db9f3b2SDimitry Andric                              TripleName.c_str());
641db9f3b2SDimitry Andric 
651db9f3b2SDimitry Andric   MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
661db9f3b2SDimitry Andric   MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
671db9f3b2SDimitry Andric   if (!MAI)
681db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
691db9f3b2SDimitry Andric                              "no asm info for target %s", TripleName.c_str());
701db9f3b2SDimitry Andric 
711db9f3b2SDimitry Andric   MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
721db9f3b2SDimitry Andric   if (!MSTI)
731db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
741db9f3b2SDimitry Andric                              "no subtarget info for target %s",
751db9f3b2SDimitry Andric                              TripleName.c_str());
761db9f3b2SDimitry Andric 
771db9f3b2SDimitry Andric   MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,
781db9f3b2SDimitry Andric                          nullptr, true, Swift5ReflectionSegmentName));
791db9f3b2SDimitry Andric   MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false));
801db9f3b2SDimitry Andric   MC->setObjectFileInfo(MOFI.get());
811db9f3b2SDimitry Andric 
821db9f3b2SDimitry Andric   MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
831db9f3b2SDimitry Andric   if (!MAB)
841db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
851db9f3b2SDimitry Andric                              "no asm backend for target %s",
861db9f3b2SDimitry Andric                              TripleName.c_str());
871db9f3b2SDimitry Andric 
881db9f3b2SDimitry Andric   MII.reset(TheTarget->createMCInstrInfo());
891db9f3b2SDimitry Andric   if (!MII)
901db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
911db9f3b2SDimitry Andric                              "no instr info info for target %s",
921db9f3b2SDimitry Andric                              TripleName.c_str());
931db9f3b2SDimitry Andric 
941db9f3b2SDimitry Andric   MCE = TheTarget->createMCCodeEmitter(*MII, *MC);
951db9f3b2SDimitry Andric   if (!MCE)
961db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
971db9f3b2SDimitry Andric                              "no code emitter for target %s",
981db9f3b2SDimitry Andric                              TripleName.c_str());
991db9f3b2SDimitry Andric 
1001db9f3b2SDimitry Andric   switch (OutFileType) {
1011db9f3b2SDimitry Andric   case DWARFLinker::OutputFileType::Assembly: {
1021db9f3b2SDimitry Andric     MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),
1031db9f3b2SDimitry Andric                                          *MAI, *MII, *MRI);
1041db9f3b2SDimitry Andric     MS = TheTarget->createAsmStreamer(
1051db9f3b2SDimitry Andric         *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP,
1061db9f3b2SDimitry Andric         std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
1071db9f3b2SDimitry Andric         true);
1081db9f3b2SDimitry Andric     break;
1091db9f3b2SDimitry Andric   }
1101db9f3b2SDimitry Andric   case DWARFLinker::OutputFileType::Object: {
1111db9f3b2SDimitry Andric     MS = TheTarget->createMCObjectStreamer(
1121db9f3b2SDimitry Andric         TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
1131db9f3b2SDimitry Andric         MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),
1141db9f3b2SDimitry Andric         *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
1151db9f3b2SDimitry Andric         /*DWARFMustBeAtTheEnd*/ false);
1161db9f3b2SDimitry Andric     break;
1171db9f3b2SDimitry Andric   }
1181db9f3b2SDimitry Andric   }
1191db9f3b2SDimitry Andric 
1201db9f3b2SDimitry Andric   if (!MS)
1211db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
1221db9f3b2SDimitry Andric                              "no object streamer for target %s",
1231db9f3b2SDimitry Andric                              TripleName.c_str());
1241db9f3b2SDimitry Andric 
1251db9f3b2SDimitry Andric   // Finally create the AsmPrinter we'll use to emit the DIEs.
1261db9f3b2SDimitry Andric   TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
1271db9f3b2SDimitry Andric                                           std::nullopt));
1281db9f3b2SDimitry Andric   if (!TM)
1291db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
1301db9f3b2SDimitry Andric                              "no target machine for target %s",
1311db9f3b2SDimitry Andric                              TripleName.c_str());
1321db9f3b2SDimitry Andric 
1331db9f3b2SDimitry Andric   Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
1341db9f3b2SDimitry Andric   if (!Asm)
1351db9f3b2SDimitry Andric     return createStringError(std::errc::invalid_argument,
1361db9f3b2SDimitry Andric                              "no asm printer for target %s",
1371db9f3b2SDimitry Andric                              TripleName.c_str());
1381db9f3b2SDimitry Andric   Asm->setDwarfUsesRelocationsAcrossSections(false);
1391db9f3b2SDimitry Andric 
1401db9f3b2SDimitry Andric   RangesSectionSize = 0;
1411db9f3b2SDimitry Andric   RngListsSectionSize = 0;
1421db9f3b2SDimitry Andric   LocSectionSize = 0;
1431db9f3b2SDimitry Andric   LocListsSectionSize = 0;
1441db9f3b2SDimitry Andric   LineSectionSize = 0;
1451db9f3b2SDimitry Andric   FrameSectionSize = 0;
1461db9f3b2SDimitry Andric   DebugInfoSectionSize = 0;
1471db9f3b2SDimitry Andric   MacInfoSectionSize = 0;
1481db9f3b2SDimitry Andric   MacroSectionSize = 0;
1491db9f3b2SDimitry Andric 
1501db9f3b2SDimitry Andric   return Error::success();
1511db9f3b2SDimitry Andric }
1521db9f3b2SDimitry Andric 
finish()1531db9f3b2SDimitry Andric void DwarfStreamer::finish() { MS->finish(); }
1541db9f3b2SDimitry Andric 
switchToDebugInfoSection(unsigned DwarfVersion)1551db9f3b2SDimitry Andric void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {
1561db9f3b2SDimitry Andric   MS->switchSection(MOFI->getDwarfInfoSection());
1571db9f3b2SDimitry Andric   MC->setDwarfVersion(DwarfVersion);
1581db9f3b2SDimitry Andric }
1591db9f3b2SDimitry Andric 
1601db9f3b2SDimitry Andric /// Emit the compilation unit header for \p Unit in the debug_info section.
1611db9f3b2SDimitry Andric ///
1621db9f3b2SDimitry Andric /// A Dwarf 4 section header is encoded as:
1631db9f3b2SDimitry Andric ///  uint32_t   Unit length (omitting this field)
1641db9f3b2SDimitry Andric ///  uint16_t   Version
1651db9f3b2SDimitry Andric ///  uint32_t   Abbreviation table offset
1661db9f3b2SDimitry Andric ///  uint8_t    Address size
1671db9f3b2SDimitry Andric /// Leading to a total of 11 bytes.
1681db9f3b2SDimitry Andric ///
1691db9f3b2SDimitry Andric /// A Dwarf 5 section header is encoded as:
1701db9f3b2SDimitry Andric ///  uint32_t   Unit length (omitting this field)
1711db9f3b2SDimitry Andric ///  uint16_t   Version
1721db9f3b2SDimitry Andric ///  uint8_t    Unit type
1731db9f3b2SDimitry Andric ///  uint8_t    Address size
1741db9f3b2SDimitry Andric ///  uint32_t   Abbreviation table offset
1751db9f3b2SDimitry Andric /// Leading to a total of 12 bytes.
emitCompileUnitHeader(CompileUnit & Unit,unsigned DwarfVersion)1761db9f3b2SDimitry Andric void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit,
1771db9f3b2SDimitry Andric                                           unsigned DwarfVersion) {
1781db9f3b2SDimitry Andric   switchToDebugInfoSection(DwarfVersion);
1791db9f3b2SDimitry Andric 
1801db9f3b2SDimitry Andric   /// The start of the unit within its section.
1811db9f3b2SDimitry Andric   Unit.setLabelBegin(Asm->createTempSymbol("cu_begin"));
1821db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(Unit.getLabelBegin());
1831db9f3b2SDimitry Andric 
1841db9f3b2SDimitry Andric   // Emit size of content not including length itself. The size has already
1851db9f3b2SDimitry Andric   // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
1861db9f3b2SDimitry Andric   // account for the length field.
1871db9f3b2SDimitry Andric   Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
1881db9f3b2SDimitry Andric   Asm->emitInt16(DwarfVersion);
1891db9f3b2SDimitry Andric 
1901db9f3b2SDimitry Andric   if (DwarfVersion >= 5) {
1911db9f3b2SDimitry Andric     Asm->emitInt8(dwarf::DW_UT_compile);
1921db9f3b2SDimitry Andric     Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
1931db9f3b2SDimitry Andric     // We share one abbreviations table across all units so it's always at the
1941db9f3b2SDimitry Andric     // start of the section.
1951db9f3b2SDimitry Andric     Asm->emitInt32(0);
1961db9f3b2SDimitry Andric     DebugInfoSectionSize += 12;
1971db9f3b2SDimitry Andric   } else {
1981db9f3b2SDimitry Andric     // We share one abbreviations table across all units so it's always at the
1991db9f3b2SDimitry Andric     // start of the section.
2001db9f3b2SDimitry Andric     Asm->emitInt32(0);
2011db9f3b2SDimitry Andric     Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
2021db9f3b2SDimitry Andric     DebugInfoSectionSize += 11;
2031db9f3b2SDimitry Andric   }
2041db9f3b2SDimitry Andric 
2051db9f3b2SDimitry Andric   // Remember this CU.
2061db9f3b2SDimitry Andric   EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
2071db9f3b2SDimitry Andric }
2081db9f3b2SDimitry Andric 
2091db9f3b2SDimitry Andric /// Emit the \p Abbrevs array as the shared abbreviation table
2101db9f3b2SDimitry Andric /// for the linked Dwarf file.
emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> & Abbrevs,unsigned DwarfVersion)2111db9f3b2SDimitry Andric void DwarfStreamer::emitAbbrevs(
2121db9f3b2SDimitry Andric     const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
2131db9f3b2SDimitry Andric     unsigned DwarfVersion) {
2141db9f3b2SDimitry Andric   MS->switchSection(MOFI->getDwarfAbbrevSection());
2151db9f3b2SDimitry Andric   MC->setDwarfVersion(DwarfVersion);
2161db9f3b2SDimitry Andric   Asm->emitDwarfAbbrevs(Abbrevs);
2171db9f3b2SDimitry Andric }
2181db9f3b2SDimitry Andric 
2191db9f3b2SDimitry Andric /// Recursively emit the DIE tree rooted at \p Die.
emitDIE(DIE & Die)2201db9f3b2SDimitry Andric void DwarfStreamer::emitDIE(DIE &Die) {
2211db9f3b2SDimitry Andric   MS->switchSection(MOFI->getDwarfInfoSection());
2221db9f3b2SDimitry Andric   Asm->emitDwarfDIE(Die);
2231db9f3b2SDimitry Andric   DebugInfoSectionSize += Die.getSize();
2241db9f3b2SDimitry Andric }
2251db9f3b2SDimitry Andric 
2261db9f3b2SDimitry Andric /// Emit contents of section SecName From Obj.
emitSectionContents(StringRef SecData,DebugSectionKind SecKind)227*7a6dacacSDimitry Andric void DwarfStreamer::emitSectionContents(StringRef SecData,
228*7a6dacacSDimitry Andric                                         DebugSectionKind SecKind) {
229*7a6dacacSDimitry Andric   if (SecData.empty())
230*7a6dacacSDimitry Andric     return;
2311db9f3b2SDimitry Andric 
232*7a6dacacSDimitry Andric   if (MCSection *Section = getMCSection(SecKind)) {
2331db9f3b2SDimitry Andric     MS->switchSection(Section);
2341db9f3b2SDimitry Andric 
2351db9f3b2SDimitry Andric     MS->emitBytes(SecData);
2361db9f3b2SDimitry Andric   }
2371db9f3b2SDimitry Andric }
2381db9f3b2SDimitry Andric 
getMCSection(DebugSectionKind SecKind)239*7a6dacacSDimitry Andric MCSection *DwarfStreamer::getMCSection(DebugSectionKind SecKind) {
240*7a6dacacSDimitry Andric   switch (SecKind) {
241*7a6dacacSDimitry Andric   case DebugSectionKind::DebugInfo:
242*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfInfoSection();
243*7a6dacacSDimitry Andric   case DebugSectionKind::DebugLine:
244*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfLineSection();
245*7a6dacacSDimitry Andric   case DebugSectionKind::DebugFrame:
246*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfFrameSection();
247*7a6dacacSDimitry Andric   case DebugSectionKind::DebugRange:
248*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfRangesSection();
249*7a6dacacSDimitry Andric   case DebugSectionKind::DebugRngLists:
250*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfRnglistsSection();
251*7a6dacacSDimitry Andric   case DebugSectionKind::DebugLoc:
252*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfLocSection();
253*7a6dacacSDimitry Andric   case DebugSectionKind::DebugLocLists:
254*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfLoclistsSection();
255*7a6dacacSDimitry Andric   case DebugSectionKind::DebugARanges:
256*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfARangesSection();
257*7a6dacacSDimitry Andric   case DebugSectionKind::DebugAbbrev:
258*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfAbbrevSection();
259*7a6dacacSDimitry Andric   case DebugSectionKind::DebugMacinfo:
260*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfMacinfoSection();
261*7a6dacacSDimitry Andric   case DebugSectionKind::DebugMacro:
262*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfMacroSection();
263*7a6dacacSDimitry Andric   case DebugSectionKind::DebugAddr:
264*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfAddrSection();
265*7a6dacacSDimitry Andric   case DebugSectionKind::DebugStr:
266*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfStrSection();
267*7a6dacacSDimitry Andric   case DebugSectionKind::DebugLineStr:
268*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfLineStrSection();
269*7a6dacacSDimitry Andric   case DebugSectionKind::DebugStrOffsets:
270*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfStrOffSection();
271*7a6dacacSDimitry Andric   case DebugSectionKind::DebugPubNames:
272*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfPubNamesSection();
273*7a6dacacSDimitry Andric   case DebugSectionKind::DebugPubTypes:
274*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfPubTypesSection();
275*7a6dacacSDimitry Andric   case DebugSectionKind::DebugNames:
276*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfDebugNamesSection();
277*7a6dacacSDimitry Andric   case DebugSectionKind::AppleNames:
278*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfAccelNamesSection();
279*7a6dacacSDimitry Andric   case DebugSectionKind::AppleNamespaces:
280*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfAccelNamespaceSection();
281*7a6dacacSDimitry Andric   case DebugSectionKind::AppleObjC:
282*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfAccelObjCSection();
283*7a6dacacSDimitry Andric   case DebugSectionKind::AppleTypes:
284*7a6dacacSDimitry Andric     return MC->getObjectFileInfo()->getDwarfAccelTypesSection();
285*7a6dacacSDimitry Andric   case DebugSectionKind::NumberOfEnumEntries:
286*7a6dacacSDimitry Andric     llvm_unreachable("Unknown DebugSectionKind value");
287*7a6dacacSDimitry Andric     break;
288*7a6dacacSDimitry Andric   }
289*7a6dacacSDimitry Andric 
290*7a6dacacSDimitry Andric   return nullptr;
291*7a6dacacSDimitry Andric }
292*7a6dacacSDimitry Andric 
2931db9f3b2SDimitry Andric /// Emit the debug_str section stored in \p Pool.
emitStrings(const NonRelocatableStringpool & Pool)2941db9f3b2SDimitry Andric void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
2951db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());
2961db9f3b2SDimitry Andric   std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission();
2971db9f3b2SDimitry Andric   for (auto Entry : Entries) {
2981db9f3b2SDimitry Andric     // Emit the string itself.
2991db9f3b2SDimitry Andric     Asm->OutStreamer->emitBytes(Entry.getString());
3001db9f3b2SDimitry Andric     // Emit a null terminator.
3011db9f3b2SDimitry Andric     Asm->emitInt8(0);
3021db9f3b2SDimitry Andric   }
3031db9f3b2SDimitry Andric }
3041db9f3b2SDimitry Andric 
3051db9f3b2SDimitry Andric /// Emit the debug string offset table described by \p StringOffsets into the
3061db9f3b2SDimitry Andric /// .debug_str_offsets table.
emitStringOffsets(const SmallVector<uint64_t> & StringOffsets,uint16_t TargetDWARFVersion)3071db9f3b2SDimitry Andric void DwarfStreamer::emitStringOffsets(
3081db9f3b2SDimitry Andric     const SmallVector<uint64_t> &StringOffsets, uint16_t TargetDWARFVersion) {
3091db9f3b2SDimitry Andric 
3101db9f3b2SDimitry Andric   if (TargetDWARFVersion < 5 || StringOffsets.empty())
3111db9f3b2SDimitry Andric     return;
3121db9f3b2SDimitry Andric 
3131db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfStrOffSection());
3141db9f3b2SDimitry Andric 
3151db9f3b2SDimitry Andric   MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugstroff");
3161db9f3b2SDimitry Andric   MCSymbol *EndLabel = Asm->createTempSymbol("Edebugstroff");
3171db9f3b2SDimitry Andric 
3181db9f3b2SDimitry Andric   // Length.
3191db9f3b2SDimitry Andric   Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
3201db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(BeginLabel);
3211db9f3b2SDimitry Andric   StrOffsetSectionSize += sizeof(uint32_t);
3221db9f3b2SDimitry Andric 
3231db9f3b2SDimitry Andric   // Version.
3241db9f3b2SDimitry Andric   MS->emitInt16(5);
3251db9f3b2SDimitry Andric   StrOffsetSectionSize += sizeof(uint16_t);
3261db9f3b2SDimitry Andric 
3271db9f3b2SDimitry Andric   // Padding.
3281db9f3b2SDimitry Andric   MS->emitInt16(0);
3291db9f3b2SDimitry Andric   StrOffsetSectionSize += sizeof(uint16_t);
3301db9f3b2SDimitry Andric 
3311db9f3b2SDimitry Andric   for (auto Off : StringOffsets) {
3321db9f3b2SDimitry Andric     Asm->OutStreamer->emitInt32(Off);
3331db9f3b2SDimitry Andric     StrOffsetSectionSize += sizeof(uint32_t);
3341db9f3b2SDimitry Andric   }
3351db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(EndLabel);
3361db9f3b2SDimitry Andric }
3371db9f3b2SDimitry Andric 
3381db9f3b2SDimitry Andric /// Emit the debug_line_str section stored in \p Pool.
emitLineStrings(const NonRelocatableStringpool & Pool)3391db9f3b2SDimitry Andric void DwarfStreamer::emitLineStrings(const NonRelocatableStringpool &Pool) {
3401db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection());
3411db9f3b2SDimitry Andric   std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission();
3421db9f3b2SDimitry Andric   for (auto Entry : Entries) {
3431db9f3b2SDimitry Andric     // Emit the string itself.
3441db9f3b2SDimitry Andric     Asm->OutStreamer->emitBytes(Entry.getString());
3451db9f3b2SDimitry Andric     // Emit a null terminator.
3461db9f3b2SDimitry Andric     Asm->emitInt8(0);
3471db9f3b2SDimitry Andric   }
3481db9f3b2SDimitry Andric }
3491db9f3b2SDimitry Andric 
emitDebugNames(DWARF5AccelTable & Table)3501db9f3b2SDimitry Andric void DwarfStreamer::emitDebugNames(DWARF5AccelTable &Table) {
3511db9f3b2SDimitry Andric   if (EmittedUnits.empty())
3521db9f3b2SDimitry Andric     return;
3531db9f3b2SDimitry Andric 
3541db9f3b2SDimitry Andric   // Build up data structures needed to emit this section.
3551db9f3b2SDimitry Andric   std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits;
3561db9f3b2SDimitry Andric   DenseMap<unsigned, unsigned> UniqueIdToCuMap;
3571db9f3b2SDimitry Andric   unsigned Id = 0;
3581db9f3b2SDimitry Andric   for (auto &CU : EmittedUnits) {
3591db9f3b2SDimitry Andric     CompUnits.push_back(CU.LabelBegin);
3601db9f3b2SDimitry Andric     // We might be omitting CUs, so we need to remap them.
3611db9f3b2SDimitry Andric     UniqueIdToCuMap[CU.ID] = Id++;
3621db9f3b2SDimitry Andric   }
3631db9f3b2SDimitry Andric 
3641db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
3651db9f3b2SDimitry Andric   dwarf::Form Form = DIEInteger::BestForm(/*IsSigned*/ false,
3661db9f3b2SDimitry Andric                                           (uint64_t)UniqueIdToCuMap.size() - 1);
3671db9f3b2SDimitry Andric   /// llvm-dwarfutil doesn't support type units + .debug_names right now.
3681db9f3b2SDimitry Andric   // FIXME: add support for type units + .debug_names. For now the behavior is
3691db9f3b2SDimitry Andric   // unsuported.
3701db9f3b2SDimitry Andric   emitDWARF5AccelTable(
3711db9f3b2SDimitry Andric       Asm.get(), Table, CompUnits,
3721db9f3b2SDimitry Andric       [&](const DWARF5AccelTableData &Entry)
3731db9f3b2SDimitry Andric           -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {
3741db9f3b2SDimitry Andric         if (UniqueIdToCuMap.size() > 1)
3751db9f3b2SDimitry Andric           return {{UniqueIdToCuMap[Entry.getUnitID()],
3761db9f3b2SDimitry Andric                    {dwarf::DW_IDX_compile_unit, Form}}};
3771db9f3b2SDimitry Andric         return std::nullopt;
3781db9f3b2SDimitry Andric       });
3791db9f3b2SDimitry Andric }
3801db9f3b2SDimitry Andric 
emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> & Table)3811db9f3b2SDimitry Andric void DwarfStreamer::emitAppleNamespaces(
3821db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
3831db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
3841db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("namespac_begin");
3851db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
3861db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);
3871db9f3b2SDimitry Andric }
3881db9f3b2SDimitry Andric 
emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> & Table)3891db9f3b2SDimitry Andric void DwarfStreamer::emitAppleNames(
3901db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
3911db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
3921db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("names_begin");
3931db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
3941db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);
3951db9f3b2SDimitry Andric }
3961db9f3b2SDimitry Andric 
emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> & Table)3971db9f3b2SDimitry Andric void DwarfStreamer::emitAppleObjc(
3981db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticOffsetData> &Table) {
3991db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
4001db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("objc_begin");
4011db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
4021db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);
4031db9f3b2SDimitry Andric }
4041db9f3b2SDimitry Andric 
emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> & Table)4051db9f3b2SDimitry Andric void DwarfStreamer::emitAppleTypes(
4061db9f3b2SDimitry Andric     AccelTable<AppleAccelTableStaticTypeData> &Table) {
4071db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
4081db9f3b2SDimitry Andric   auto *SectionBegin = Asm->createTempSymbol("types_begin");
4091db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(SectionBegin);
4101db9f3b2SDimitry Andric   emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);
4111db9f3b2SDimitry Andric }
4121db9f3b2SDimitry Andric 
4131db9f3b2SDimitry Andric /// Emit the swift_ast section stored in \p Buffers.
emitSwiftAST(StringRef Buffer)4141db9f3b2SDimitry Andric void DwarfStreamer::emitSwiftAST(StringRef Buffer) {
4151db9f3b2SDimitry Andric   MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
4161db9f3b2SDimitry Andric   SwiftASTSection->setAlignment(Align(32));
4171db9f3b2SDimitry Andric   MS->switchSection(SwiftASTSection);
4181db9f3b2SDimitry Andric   MS->emitBytes(Buffer);
4191db9f3b2SDimitry Andric }
4201db9f3b2SDimitry Andric 
emitSwiftReflectionSection(llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,StringRef Buffer,uint32_t Alignment,uint32_t Size)4211db9f3b2SDimitry Andric void DwarfStreamer::emitSwiftReflectionSection(
4221db9f3b2SDimitry Andric     llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
4231db9f3b2SDimitry Andric     StringRef Buffer, uint32_t Alignment, uint32_t Size) {
4241db9f3b2SDimitry Andric   MCSection *ReflectionSection =
4251db9f3b2SDimitry Andric       MOFI->getSwift5ReflectionSection(ReflSectionKind);
4261db9f3b2SDimitry Andric   if (ReflectionSection == nullptr)
4271db9f3b2SDimitry Andric     return;
4281db9f3b2SDimitry Andric   ReflectionSection->setAlignment(Align(Alignment));
4291db9f3b2SDimitry Andric   MS->switchSection(ReflectionSection);
4301db9f3b2SDimitry Andric   MS->emitBytes(Buffer);
4311db9f3b2SDimitry Andric }
4321db9f3b2SDimitry Andric 
emitDwarfDebugArangesTable(const CompileUnit & Unit,const AddressRanges & LinkedRanges)4331db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugArangesTable(
4341db9f3b2SDimitry Andric     const CompileUnit &Unit, const AddressRanges &LinkedRanges) {
4351db9f3b2SDimitry Andric   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
4361db9f3b2SDimitry Andric 
4371db9f3b2SDimitry Andric   // Make .debug_aranges to be current section.
4381db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
4391db9f3b2SDimitry Andric 
4401db9f3b2SDimitry Andric   // Emit Header.
4411db9f3b2SDimitry Andric   MCSymbol *BeginLabel = Asm->createTempSymbol("Barange");
4421db9f3b2SDimitry Andric   MCSymbol *EndLabel = Asm->createTempSymbol("Earange");
4431db9f3b2SDimitry Andric 
4441db9f3b2SDimitry Andric   unsigned HeaderSize =
4451db9f3b2SDimitry Andric       sizeof(int32_t) + // Size of contents (w/o this field
4461db9f3b2SDimitry Andric       sizeof(int16_t) + // DWARF ARange version number
4471db9f3b2SDimitry Andric       sizeof(int32_t) + // Offset of CU in the .debug_info section
4481db9f3b2SDimitry Andric       sizeof(int8_t) +  // Pointer Size (in bytes)
4491db9f3b2SDimitry Andric       sizeof(int8_t);   // Segment Size (in bytes)
4501db9f3b2SDimitry Andric 
4511db9f3b2SDimitry Andric   unsigned TupleSize = AddressSize * 2;
4521db9f3b2SDimitry Andric   unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
4531db9f3b2SDimitry Andric 
4541db9f3b2SDimitry Andric   Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
4551db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(BeginLabel);
4561db9f3b2SDimitry Andric   Asm->emitInt16(dwarf::DW_ARANGES_VERSION); // Version number
4571db9f3b2SDimitry Andric   Asm->emitInt32(Unit.getStartOffset());     // Corresponding unit's offset
4581db9f3b2SDimitry Andric   Asm->emitInt8(AddressSize);                // Address size
4591db9f3b2SDimitry Andric   Asm->emitInt8(0);                          // Segment size
4601db9f3b2SDimitry Andric 
4611db9f3b2SDimitry Andric   Asm->OutStreamer->emitFill(Padding, 0x0);
4621db9f3b2SDimitry Andric 
4631db9f3b2SDimitry Andric   // Emit linked ranges.
4641db9f3b2SDimitry Andric   for (const AddressRange &Range : LinkedRanges) {
4651db9f3b2SDimitry Andric     MS->emitIntValue(Range.start(), AddressSize);
4661db9f3b2SDimitry Andric     MS->emitIntValue(Range.end() - Range.start(), AddressSize);
4671db9f3b2SDimitry Andric   }
4681db9f3b2SDimitry Andric 
4691db9f3b2SDimitry Andric   // Emit terminator.
4701db9f3b2SDimitry Andric   Asm->OutStreamer->emitIntValue(0, AddressSize);
4711db9f3b2SDimitry Andric   Asm->OutStreamer->emitIntValue(0, AddressSize);
4721db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(EndLabel);
4731db9f3b2SDimitry Andric }
4741db9f3b2SDimitry Andric 
emitDwarfDebugRangesTableFragment(const CompileUnit & Unit,const AddressRanges & LinkedRanges,PatchLocation Patch)4751db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRangesTableFragment(
4761db9f3b2SDimitry Andric     const CompileUnit &Unit, const AddressRanges &LinkedRanges,
4771db9f3b2SDimitry Andric     PatchLocation Patch) {
4781db9f3b2SDimitry Andric   Patch.set(RangesSectionSize);
4791db9f3b2SDimitry Andric 
4801db9f3b2SDimitry Andric   // Make .debug_ranges to be current section.
4811db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
4821db9f3b2SDimitry Andric   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
4831db9f3b2SDimitry Andric 
4841db9f3b2SDimitry Andric   // Emit ranges.
4851db9f3b2SDimitry Andric   uint64_t BaseAddress = 0;
4861db9f3b2SDimitry Andric   if (std::optional<uint64_t> LowPC = Unit.getLowPc())
4871db9f3b2SDimitry Andric     BaseAddress = *LowPC;
4881db9f3b2SDimitry Andric 
4891db9f3b2SDimitry Andric   for (const AddressRange &Range : LinkedRanges) {
4901db9f3b2SDimitry Andric     MS->emitIntValue(Range.start() - BaseAddress, AddressSize);
4911db9f3b2SDimitry Andric     MS->emitIntValue(Range.end() - BaseAddress, AddressSize);
4921db9f3b2SDimitry Andric 
4931db9f3b2SDimitry Andric     RangesSectionSize += AddressSize;
4941db9f3b2SDimitry Andric     RangesSectionSize += AddressSize;
4951db9f3b2SDimitry Andric   }
4961db9f3b2SDimitry Andric 
4971db9f3b2SDimitry Andric   // Add the terminator entry.
4981db9f3b2SDimitry Andric   MS->emitIntValue(0, AddressSize);
4991db9f3b2SDimitry Andric   MS->emitIntValue(0, AddressSize);
5001db9f3b2SDimitry Andric 
5011db9f3b2SDimitry Andric   RangesSectionSize += AddressSize;
5021db9f3b2SDimitry Andric   RangesSectionSize += AddressSize;
5031db9f3b2SDimitry Andric }
5041db9f3b2SDimitry Andric 
5051db9f3b2SDimitry Andric MCSymbol *
emitDwarfDebugRangeListHeader(const CompileUnit & Unit)5061db9f3b2SDimitry Andric DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit &Unit) {
5071db9f3b2SDimitry Andric   if (Unit.getOrigUnit().getVersion() < 5)
5081db9f3b2SDimitry Andric     return nullptr;
5091db9f3b2SDimitry Andric 
5101db9f3b2SDimitry Andric   // Make .debug_rnglists to be current section.
5111db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
5121db9f3b2SDimitry Andric 
5131db9f3b2SDimitry Andric   MCSymbol *BeginLabel = Asm->createTempSymbol("Brnglists");
5141db9f3b2SDimitry Andric   MCSymbol *EndLabel = Asm->createTempSymbol("Ernglists");
5151db9f3b2SDimitry Andric   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
5161db9f3b2SDimitry Andric 
5171db9f3b2SDimitry Andric   // Length
5181db9f3b2SDimitry Andric   Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
5191db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(BeginLabel);
5201db9f3b2SDimitry Andric   RngListsSectionSize += sizeof(uint32_t);
5211db9f3b2SDimitry Andric 
5221db9f3b2SDimitry Andric   // Version.
5231db9f3b2SDimitry Andric   MS->emitInt16(5);
5241db9f3b2SDimitry Andric   RngListsSectionSize += sizeof(uint16_t);
5251db9f3b2SDimitry Andric 
5261db9f3b2SDimitry Andric   // Address size.
5271db9f3b2SDimitry Andric   MS->emitInt8(AddressSize);
5281db9f3b2SDimitry Andric   RngListsSectionSize++;
5291db9f3b2SDimitry Andric 
5301db9f3b2SDimitry Andric   // Seg_size
5311db9f3b2SDimitry Andric   MS->emitInt8(0);
5321db9f3b2SDimitry Andric   RngListsSectionSize++;
5331db9f3b2SDimitry Andric 
5341db9f3b2SDimitry Andric   // Offset entry count
5351db9f3b2SDimitry Andric   MS->emitInt32(0);
5361db9f3b2SDimitry Andric   RngListsSectionSize += sizeof(uint32_t);
5371db9f3b2SDimitry Andric 
5381db9f3b2SDimitry Andric   return EndLabel;
5391db9f3b2SDimitry Andric }
5401db9f3b2SDimitry Andric 
emitDwarfDebugRangeListFragment(const CompileUnit & Unit,const AddressRanges & LinkedRanges,PatchLocation Patch,DebugDieValuePool & AddrPool)5411db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRangeListFragment(
5421db9f3b2SDimitry Andric     const CompileUnit &Unit, const AddressRanges &LinkedRanges,
5431db9f3b2SDimitry Andric     PatchLocation Patch, DebugDieValuePool &AddrPool) {
5441db9f3b2SDimitry Andric   if (Unit.getOrigUnit().getVersion() < 5) {
5451db9f3b2SDimitry Andric     emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch);
5461db9f3b2SDimitry Andric     return;
5471db9f3b2SDimitry Andric   }
5481db9f3b2SDimitry Andric 
5491db9f3b2SDimitry Andric   emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool);
5501db9f3b2SDimitry Andric }
5511db9f3b2SDimitry Andric 
emitDwarfDebugRangeListFooter(const CompileUnit & Unit,MCSymbol * EndLabel)5521db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
5531db9f3b2SDimitry Andric                                                   MCSymbol *EndLabel) {
5541db9f3b2SDimitry Andric   if (Unit.getOrigUnit().getVersion() < 5)
5551db9f3b2SDimitry Andric     return;
5561db9f3b2SDimitry Andric 
5571db9f3b2SDimitry Andric   // Make .debug_rnglists to be current section.
5581db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
5591db9f3b2SDimitry Andric 
5601db9f3b2SDimitry Andric   if (EndLabel != nullptr)
5611db9f3b2SDimitry Andric     Asm->OutStreamer->emitLabel(EndLabel);
5621db9f3b2SDimitry Andric }
5631db9f3b2SDimitry Andric 
emitDwarfDebugRngListsTableFragment(const CompileUnit & Unit,const AddressRanges & LinkedRanges,PatchLocation Patch,DebugDieValuePool & AddrPool)5641db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
5651db9f3b2SDimitry Andric     const CompileUnit &Unit, const AddressRanges &LinkedRanges,
5661db9f3b2SDimitry Andric     PatchLocation Patch, DebugDieValuePool &AddrPool) {
5671db9f3b2SDimitry Andric   Patch.set(RngListsSectionSize);
5681db9f3b2SDimitry Andric 
5691db9f3b2SDimitry Andric   // Make .debug_rnglists to be current section.
5701db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
5711db9f3b2SDimitry Andric   std::optional<uint64_t> BaseAddress;
5721db9f3b2SDimitry Andric 
5731db9f3b2SDimitry Andric   for (const AddressRange &Range : LinkedRanges) {
5741db9f3b2SDimitry Andric 
5751db9f3b2SDimitry Andric     if (!BaseAddress) {
5761db9f3b2SDimitry Andric       BaseAddress = Range.start();
5771db9f3b2SDimitry Andric 
5781db9f3b2SDimitry Andric       // Emit base address.
5791db9f3b2SDimitry Andric       MS->emitInt8(dwarf::DW_RLE_base_addressx);
5801db9f3b2SDimitry Andric       RngListsSectionSize += 1;
5811db9f3b2SDimitry Andric       RngListsSectionSize +=
5821db9f3b2SDimitry Andric           MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress));
5831db9f3b2SDimitry Andric     }
5841db9f3b2SDimitry Andric 
5851db9f3b2SDimitry Andric     // Emit type of entry.
5861db9f3b2SDimitry Andric     MS->emitInt8(dwarf::DW_RLE_offset_pair);
5871db9f3b2SDimitry Andric     RngListsSectionSize += 1;
5881db9f3b2SDimitry Andric 
5891db9f3b2SDimitry Andric     // Emit start offset relative to base address.
5901db9f3b2SDimitry Andric     RngListsSectionSize +=
5911db9f3b2SDimitry Andric         MS->emitULEB128IntValue(Range.start() - *BaseAddress);
5921db9f3b2SDimitry Andric 
5931db9f3b2SDimitry Andric     // Emit end offset relative to base address.
5941db9f3b2SDimitry Andric     RngListsSectionSize += MS->emitULEB128IntValue(Range.end() - *BaseAddress);
5951db9f3b2SDimitry Andric   }
5961db9f3b2SDimitry Andric 
5971db9f3b2SDimitry Andric   // Emit the terminator entry.
5981db9f3b2SDimitry Andric   MS->emitInt8(dwarf::DW_RLE_end_of_list);
5991db9f3b2SDimitry Andric   RngListsSectionSize += 1;
6001db9f3b2SDimitry Andric }
6011db9f3b2SDimitry Andric 
6021db9f3b2SDimitry Andric /// Emit debug locations(.debug_loc, .debug_loclists) header.
emitDwarfDebugLocListHeader(const CompileUnit & Unit)6031db9f3b2SDimitry Andric MCSymbol *DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit &Unit) {
6041db9f3b2SDimitry Andric   if (Unit.getOrigUnit().getVersion() < 5)
6051db9f3b2SDimitry Andric     return nullptr;
6061db9f3b2SDimitry Andric 
6071db9f3b2SDimitry Andric   // Make .debug_loclists the current section.
6081db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
6091db9f3b2SDimitry Andric 
6101db9f3b2SDimitry Andric   MCSymbol *BeginLabel = Asm->createTempSymbol("Bloclists");
6111db9f3b2SDimitry Andric   MCSymbol *EndLabel = Asm->createTempSymbol("Eloclists");
6121db9f3b2SDimitry Andric   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
6131db9f3b2SDimitry Andric 
6141db9f3b2SDimitry Andric   // Length
6151db9f3b2SDimitry Andric   Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
6161db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(BeginLabel);
6171db9f3b2SDimitry Andric   LocListsSectionSize += sizeof(uint32_t);
6181db9f3b2SDimitry Andric 
6191db9f3b2SDimitry Andric   // Version.
6201db9f3b2SDimitry Andric   MS->emitInt16(5);
6211db9f3b2SDimitry Andric   LocListsSectionSize += sizeof(uint16_t);
6221db9f3b2SDimitry Andric 
6231db9f3b2SDimitry Andric   // Address size.
6241db9f3b2SDimitry Andric   MS->emitInt8(AddressSize);
6251db9f3b2SDimitry Andric   LocListsSectionSize++;
6261db9f3b2SDimitry Andric 
6271db9f3b2SDimitry Andric   // Seg_size
6281db9f3b2SDimitry Andric   MS->emitInt8(0);
6291db9f3b2SDimitry Andric   LocListsSectionSize++;
6301db9f3b2SDimitry Andric 
6311db9f3b2SDimitry Andric   // Offset entry count
6321db9f3b2SDimitry Andric   MS->emitInt32(0);
6331db9f3b2SDimitry Andric   LocListsSectionSize += sizeof(uint32_t);
6341db9f3b2SDimitry Andric 
6351db9f3b2SDimitry Andric   return EndLabel;
6361db9f3b2SDimitry Andric }
6371db9f3b2SDimitry Andric 
6381db9f3b2SDimitry Andric /// Emit debug locations(.debug_loc, .debug_loclists) fragment.
emitDwarfDebugLocListFragment(const CompileUnit & Unit,const DWARFLocationExpressionsVector & LinkedLocationExpression,PatchLocation Patch,DebugDieValuePool & AddrPool)6391db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocListFragment(
6401db9f3b2SDimitry Andric     const CompileUnit &Unit,
6411db9f3b2SDimitry Andric     const DWARFLocationExpressionsVector &LinkedLocationExpression,
6421db9f3b2SDimitry Andric     PatchLocation Patch, DebugDieValuePool &AddrPool) {
6431db9f3b2SDimitry Andric   if (Unit.getOrigUnit().getVersion() < 5) {
6441db9f3b2SDimitry Andric     emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch);
6451db9f3b2SDimitry Andric     return;
6461db9f3b2SDimitry Andric   }
6471db9f3b2SDimitry Andric 
6481db9f3b2SDimitry Andric   emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch,
6491db9f3b2SDimitry Andric                                       AddrPool);
6501db9f3b2SDimitry Andric }
6511db9f3b2SDimitry Andric 
6521db9f3b2SDimitry Andric /// Emit debug locations(.debug_loc, .debug_loclists) footer.
emitDwarfDebugLocListFooter(const CompileUnit & Unit,MCSymbol * EndLabel)6531db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit &Unit,
6541db9f3b2SDimitry Andric                                                 MCSymbol *EndLabel) {
6551db9f3b2SDimitry Andric   if (Unit.getOrigUnit().getVersion() < 5)
6561db9f3b2SDimitry Andric     return;
6571db9f3b2SDimitry Andric 
6581db9f3b2SDimitry Andric   // Make .debug_loclists the current section.
6591db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
6601db9f3b2SDimitry Andric 
6611db9f3b2SDimitry Andric   if (EndLabel != nullptr)
6621db9f3b2SDimitry Andric     Asm->OutStreamer->emitLabel(EndLabel);
6631db9f3b2SDimitry Andric }
6641db9f3b2SDimitry Andric 
6651db9f3b2SDimitry Andric /// Emit piece of .debug_loc for \p LinkedLocationExpression.
emitDwarfDebugLocTableFragment(const CompileUnit & Unit,const DWARFLocationExpressionsVector & LinkedLocationExpression,PatchLocation Patch)6661db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocTableFragment(
6671db9f3b2SDimitry Andric     const CompileUnit &Unit,
6681db9f3b2SDimitry Andric     const DWARFLocationExpressionsVector &LinkedLocationExpression,
6691db9f3b2SDimitry Andric     PatchLocation Patch) {
6701db9f3b2SDimitry Andric   Patch.set(LocSectionSize);
6711db9f3b2SDimitry Andric 
6721db9f3b2SDimitry Andric   // Make .debug_loc to be current section.
6731db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
6741db9f3b2SDimitry Andric   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
6751db9f3b2SDimitry Andric 
6761db9f3b2SDimitry Andric   // Emit ranges.
6771db9f3b2SDimitry Andric   uint64_t BaseAddress = 0;
6781db9f3b2SDimitry Andric   if (std::optional<uint64_t> LowPC = Unit.getLowPc())
6791db9f3b2SDimitry Andric     BaseAddress = *LowPC;
6801db9f3b2SDimitry Andric 
6811db9f3b2SDimitry Andric   for (const DWARFLocationExpression &LocExpression :
6821db9f3b2SDimitry Andric        LinkedLocationExpression) {
6831db9f3b2SDimitry Andric     if (LocExpression.Range) {
6841db9f3b2SDimitry Andric       MS->emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize);
6851db9f3b2SDimitry Andric       MS->emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize);
6861db9f3b2SDimitry Andric 
6871db9f3b2SDimitry Andric       LocSectionSize += AddressSize;
6881db9f3b2SDimitry Andric       LocSectionSize += AddressSize;
6891db9f3b2SDimitry Andric     }
6901db9f3b2SDimitry Andric 
6911db9f3b2SDimitry Andric     Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2);
6921db9f3b2SDimitry Andric     Asm->OutStreamer->emitBytes(StringRef(
6931db9f3b2SDimitry Andric         (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
6941db9f3b2SDimitry Andric     LocSectionSize += LocExpression.Expr.size() + 2;
6951db9f3b2SDimitry Andric   }
6961db9f3b2SDimitry Andric 
6971db9f3b2SDimitry Andric   // Add the terminator entry.
6981db9f3b2SDimitry Andric   MS->emitIntValue(0, AddressSize);
6991db9f3b2SDimitry Andric   MS->emitIntValue(0, AddressSize);
7001db9f3b2SDimitry Andric 
7011db9f3b2SDimitry Andric   LocSectionSize += AddressSize;
7021db9f3b2SDimitry Andric   LocSectionSize += AddressSize;
7031db9f3b2SDimitry Andric }
7041db9f3b2SDimitry Andric 
7051db9f3b2SDimitry Andric /// Emit .debug_addr header.
emitDwarfDebugAddrsHeader(const CompileUnit & Unit)7061db9f3b2SDimitry Andric MCSymbol *DwarfStreamer::emitDwarfDebugAddrsHeader(const CompileUnit &Unit) {
7071db9f3b2SDimitry Andric 
7081db9f3b2SDimitry Andric   // Make .debug_addr the current section.
7091db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
7101db9f3b2SDimitry Andric 
7111db9f3b2SDimitry Andric   MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugaddr");
7121db9f3b2SDimitry Andric   MCSymbol *EndLabel = Asm->createTempSymbol("Edebugaddr");
7131db9f3b2SDimitry Andric   unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize();
7141db9f3b2SDimitry Andric 
7151db9f3b2SDimitry Andric   // Emit length.
7161db9f3b2SDimitry Andric   Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
7171db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(BeginLabel);
7181db9f3b2SDimitry Andric   AddrSectionSize += sizeof(uint32_t);
7191db9f3b2SDimitry Andric 
7201db9f3b2SDimitry Andric   // Emit version.
7211db9f3b2SDimitry Andric   Asm->emitInt16(5);
7221db9f3b2SDimitry Andric   AddrSectionSize += 2;
7231db9f3b2SDimitry Andric 
7241db9f3b2SDimitry Andric   // Emit address size.
7251db9f3b2SDimitry Andric   Asm->emitInt8(AddrSize);
7261db9f3b2SDimitry Andric   AddrSectionSize += 1;
7271db9f3b2SDimitry Andric 
7281db9f3b2SDimitry Andric   // Emit segment size.
7291db9f3b2SDimitry Andric   Asm->emitInt8(0);
7301db9f3b2SDimitry Andric   AddrSectionSize += 1;
7311db9f3b2SDimitry Andric 
7321db9f3b2SDimitry Andric   return EndLabel;
7331db9f3b2SDimitry Andric }
7341db9f3b2SDimitry Andric 
7351db9f3b2SDimitry Andric /// Emit the .debug_addr addresses stored in \p Addrs.
emitDwarfDebugAddrs(const SmallVector<uint64_t> & Addrs,uint8_t AddrSize)7361db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
7371db9f3b2SDimitry Andric                                         uint8_t AddrSize) {
7381db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection());
7391db9f3b2SDimitry Andric   for (auto Addr : Addrs) {
7401db9f3b2SDimitry Andric     Asm->OutStreamer->emitIntValue(Addr, AddrSize);
7411db9f3b2SDimitry Andric     AddrSectionSize += AddrSize;
7421db9f3b2SDimitry Andric   }
7431db9f3b2SDimitry Andric }
7441db9f3b2SDimitry Andric 
7451db9f3b2SDimitry Andric /// Emit .debug_addr footer.
emitDwarfDebugAddrsFooter(const CompileUnit & Unit,MCSymbol * EndLabel)7461db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
7471db9f3b2SDimitry Andric                                               MCSymbol *EndLabel) {
7481db9f3b2SDimitry Andric 
7491db9f3b2SDimitry Andric   // Make .debug_addr the current section.
7501db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());
7511db9f3b2SDimitry Andric 
7521db9f3b2SDimitry Andric   if (EndLabel != nullptr)
7531db9f3b2SDimitry Andric     Asm->OutStreamer->emitLabel(EndLabel);
7541db9f3b2SDimitry Andric }
7551db9f3b2SDimitry Andric 
7561db9f3b2SDimitry Andric /// Emit piece of .debug_loclists for \p LinkedLocationExpression.
emitDwarfDebugLocListsTableFragment(const CompileUnit & Unit,const DWARFLocationExpressionsVector & LinkedLocationExpression,PatchLocation Patch,DebugDieValuePool & AddrPool)7571db9f3b2SDimitry Andric void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
7581db9f3b2SDimitry Andric     const CompileUnit &Unit,
7591db9f3b2SDimitry Andric     const DWARFLocationExpressionsVector &LinkedLocationExpression,
7601db9f3b2SDimitry Andric     PatchLocation Patch, DebugDieValuePool &AddrPool) {
7611db9f3b2SDimitry Andric   Patch.set(LocListsSectionSize);
7621db9f3b2SDimitry Andric 
7631db9f3b2SDimitry Andric   // Make .debug_loclists the current section.
7641db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
7651db9f3b2SDimitry Andric   std::optional<uint64_t> BaseAddress;
7661db9f3b2SDimitry Andric 
7671db9f3b2SDimitry Andric   for (const DWARFLocationExpression &LocExpression :
7681db9f3b2SDimitry Andric        LinkedLocationExpression) {
7691db9f3b2SDimitry Andric     if (LocExpression.Range) {
7701db9f3b2SDimitry Andric 
7711db9f3b2SDimitry Andric       if (!BaseAddress) {
7721db9f3b2SDimitry Andric 
7731db9f3b2SDimitry Andric         BaseAddress = LocExpression.Range->LowPC;
7741db9f3b2SDimitry Andric 
7751db9f3b2SDimitry Andric         // Emit base address.
7761db9f3b2SDimitry Andric         MS->emitInt8(dwarf::DW_LLE_base_addressx);
7771db9f3b2SDimitry Andric         LocListsSectionSize += 1;
7781db9f3b2SDimitry Andric         LocListsSectionSize +=
7791db9f3b2SDimitry Andric             MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress));
7801db9f3b2SDimitry Andric       }
7811db9f3b2SDimitry Andric 
7821db9f3b2SDimitry Andric       // Emit type of entry.
7831db9f3b2SDimitry Andric       MS->emitInt8(dwarf::DW_LLE_offset_pair);
7841db9f3b2SDimitry Andric       LocListsSectionSize += 1;
7851db9f3b2SDimitry Andric 
7861db9f3b2SDimitry Andric       // Emit start offset relative to base address.
7871db9f3b2SDimitry Andric       LocListsSectionSize +=
7881db9f3b2SDimitry Andric           MS->emitULEB128IntValue(LocExpression.Range->LowPC - *BaseAddress);
7891db9f3b2SDimitry Andric 
7901db9f3b2SDimitry Andric       // Emit end offset relative to base address.
7911db9f3b2SDimitry Andric       LocListsSectionSize +=
7921db9f3b2SDimitry Andric           MS->emitULEB128IntValue(LocExpression.Range->HighPC - *BaseAddress);
7931db9f3b2SDimitry Andric     } else {
7941db9f3b2SDimitry Andric       // Emit type of entry.
7951db9f3b2SDimitry Andric       MS->emitInt8(dwarf::DW_LLE_default_location);
7961db9f3b2SDimitry Andric       LocListsSectionSize += 1;
7971db9f3b2SDimitry Andric     }
7981db9f3b2SDimitry Andric 
7991db9f3b2SDimitry Andric     LocListsSectionSize += MS->emitULEB128IntValue(LocExpression.Expr.size());
8001db9f3b2SDimitry Andric     Asm->OutStreamer->emitBytes(StringRef(
8011db9f3b2SDimitry Andric         (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
8021db9f3b2SDimitry Andric     LocListsSectionSize += LocExpression.Expr.size();
8031db9f3b2SDimitry Andric   }
8041db9f3b2SDimitry Andric 
8051db9f3b2SDimitry Andric   // Emit the terminator entry.
8061db9f3b2SDimitry Andric   MS->emitInt8(dwarf::DW_LLE_end_of_list);
8071db9f3b2SDimitry Andric   LocListsSectionSize += 1;
8081db9f3b2SDimitry Andric }
8091db9f3b2SDimitry Andric 
emitLineTableForUnit(const DWARFDebugLine::LineTable & LineTable,const CompileUnit & Unit,OffsetsStringPool & DebugStrPool,OffsetsStringPool & DebugLineStrPool)8101db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableForUnit(
8111db9f3b2SDimitry Andric     const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit,
8121db9f3b2SDimitry Andric     OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool) {
8131db9f3b2SDimitry Andric   // Switch to the section where the table will be emitted into.
8141db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfLineSection());
8151db9f3b2SDimitry Andric 
8161db9f3b2SDimitry Andric   MCSymbol *LineStartSym = MC->createTempSymbol();
8171db9f3b2SDimitry Andric   MCSymbol *LineEndSym = MC->createTempSymbol();
8181db9f3b2SDimitry Andric 
8191db9f3b2SDimitry Andric   // unit_length.
8201db9f3b2SDimitry Andric   if (LineTable.Prologue.FormParams.Format == dwarf::DwarfFormat::DWARF64) {
8211db9f3b2SDimitry Andric     MS->emitInt32(dwarf::DW_LENGTH_DWARF64);
8221db9f3b2SDimitry Andric     LineSectionSize += 4;
8231db9f3b2SDimitry Andric   }
8241db9f3b2SDimitry Andric   emitLabelDifference(LineEndSym, LineStartSym,
8251db9f3b2SDimitry Andric                       LineTable.Prologue.FormParams.Format, LineSectionSize);
8261db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(LineStartSym);
8271db9f3b2SDimitry Andric 
8281db9f3b2SDimitry Andric   // Emit prologue.
8291db9f3b2SDimitry Andric   emitLineTablePrologue(LineTable.Prologue, DebugStrPool, DebugLineStrPool);
8301db9f3b2SDimitry Andric 
8311db9f3b2SDimitry Andric   // Emit rows.
8321db9f3b2SDimitry Andric   emitLineTableRows(LineTable, LineEndSym,
8331db9f3b2SDimitry Andric                     Unit.getOrigUnit().getAddressByteSize());
8341db9f3b2SDimitry Andric }
8351db9f3b2SDimitry Andric 
emitLineTablePrologue(const DWARFDebugLine::Prologue & P,OffsetsStringPool & DebugStrPool,OffsetsStringPool & DebugLineStrPool)8361db9f3b2SDimitry Andric void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
8371db9f3b2SDimitry Andric                                           OffsetsStringPool &DebugStrPool,
8381db9f3b2SDimitry Andric                                           OffsetsStringPool &DebugLineStrPool) {
8391db9f3b2SDimitry Andric   MCSymbol *PrologueStartSym = MC->createTempSymbol();
8401db9f3b2SDimitry Andric   MCSymbol *PrologueEndSym = MC->createTempSymbol();
8411db9f3b2SDimitry Andric 
8421db9f3b2SDimitry Andric   // version (uhalf).
8431db9f3b2SDimitry Andric   MS->emitInt16(P.getVersion());
8441db9f3b2SDimitry Andric   LineSectionSize += 2;
8451db9f3b2SDimitry Andric   if (P.getVersion() == 5) {
8461db9f3b2SDimitry Andric     // address_size (ubyte).
8471db9f3b2SDimitry Andric     MS->emitInt8(P.getAddressSize());
8481db9f3b2SDimitry Andric     LineSectionSize += 1;
8491db9f3b2SDimitry Andric 
8501db9f3b2SDimitry Andric     // segment_selector_size (ubyte).
8511db9f3b2SDimitry Andric     MS->emitInt8(P.SegSelectorSize);
8521db9f3b2SDimitry Andric     LineSectionSize += 1;
8531db9f3b2SDimitry Andric   }
8541db9f3b2SDimitry Andric 
8551db9f3b2SDimitry Andric   // header_length.
8561db9f3b2SDimitry Andric   emitLabelDifference(PrologueEndSym, PrologueStartSym, P.FormParams.Format,
8571db9f3b2SDimitry Andric                       LineSectionSize);
8581db9f3b2SDimitry Andric 
8591db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(PrologueStartSym);
8601db9f3b2SDimitry Andric   emitLineTableProloguePayload(P, DebugStrPool, DebugLineStrPool);
8611db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(PrologueEndSym);
8621db9f3b2SDimitry Andric }
8631db9f3b2SDimitry Andric 
emitLineTablePrologueV2IncludeAndFileTable(const DWARFDebugLine::Prologue & P,OffsetsStringPool & DebugStrPool,OffsetsStringPool & DebugLineStrPool)8641db9f3b2SDimitry Andric void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
8651db9f3b2SDimitry Andric     const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
8661db9f3b2SDimitry Andric     OffsetsStringPool &DebugLineStrPool) {
8671db9f3b2SDimitry Andric   // include_directories (sequence of path names).
8681db9f3b2SDimitry Andric   for (const DWARFFormValue &Include : P.IncludeDirectories)
8691db9f3b2SDimitry Andric     emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);
8701db9f3b2SDimitry Andric   // The last entry is followed by a single null byte.
8711db9f3b2SDimitry Andric   MS->emitInt8(0);
8721db9f3b2SDimitry Andric   LineSectionSize += 1;
8731db9f3b2SDimitry Andric 
8741db9f3b2SDimitry Andric   // file_names (sequence of file entries).
8751db9f3b2SDimitry Andric   for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) {
8761db9f3b2SDimitry Andric     // A null-terminated string containing the full or relative path name of a
8771db9f3b2SDimitry Andric     // source file.
8781db9f3b2SDimitry Andric     emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
8791db9f3b2SDimitry Andric     // An unsigned LEB128 number representing the directory index of a directory
8801db9f3b2SDimitry Andric     // in the include_directories section.
8811db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(File.DirIdx);
8821db9f3b2SDimitry Andric     // An unsigned LEB128 number representing the (implementation-defined) time
8831db9f3b2SDimitry Andric     // of last modification for the file, or 0 if not available.
8841db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(File.ModTime);
8851db9f3b2SDimitry Andric     // An unsigned LEB128 number representing the length in bytes of the file,
8861db9f3b2SDimitry Andric     // or 0 if not available.
8871db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(File.Length);
8881db9f3b2SDimitry Andric   }
8891db9f3b2SDimitry Andric   // The last entry is followed by a single null byte.
8901db9f3b2SDimitry Andric   MS->emitInt8(0);
8911db9f3b2SDimitry Andric   LineSectionSize += 1;
8921db9f3b2SDimitry Andric }
8931db9f3b2SDimitry Andric 
emitLineTablePrologueV5IncludeAndFileTable(const DWARFDebugLine::Prologue & P,OffsetsStringPool & DebugStrPool,OffsetsStringPool & DebugLineStrPool)8941db9f3b2SDimitry Andric void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
8951db9f3b2SDimitry Andric     const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
8961db9f3b2SDimitry Andric     OffsetsStringPool &DebugLineStrPool) {
8971db9f3b2SDimitry Andric   if (P.IncludeDirectories.empty()) {
8981db9f3b2SDimitry Andric     // directory_entry_format_count(ubyte).
8991db9f3b2SDimitry Andric     MS->emitInt8(0);
9001db9f3b2SDimitry Andric     LineSectionSize += 1;
9011db9f3b2SDimitry Andric   } else {
9021db9f3b2SDimitry Andric     // directory_entry_format_count(ubyte).
9031db9f3b2SDimitry Andric     MS->emitInt8(1);
9041db9f3b2SDimitry Andric     LineSectionSize += 1;
9051db9f3b2SDimitry Andric 
9061db9f3b2SDimitry Andric     // directory_entry_format (sequence of ULEB128 pairs).
9071db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
9081db9f3b2SDimitry Andric     LineSectionSize +=
9091db9f3b2SDimitry Andric         MS->emitULEB128IntValue(P.IncludeDirectories[0].getForm());
9101db9f3b2SDimitry Andric   }
9111db9f3b2SDimitry Andric 
9121db9f3b2SDimitry Andric   // directories_count (ULEB128).
9131db9f3b2SDimitry Andric   LineSectionSize += MS->emitULEB128IntValue(P.IncludeDirectories.size());
9141db9f3b2SDimitry Andric   // directories (sequence of directory names).
9151db9f3b2SDimitry Andric   for (auto Include : P.IncludeDirectories)
9161db9f3b2SDimitry Andric     emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);
9171db9f3b2SDimitry Andric 
9181db9f3b2SDimitry Andric   bool HasChecksums = P.ContentTypes.HasMD5;
9191db9f3b2SDimitry Andric   bool HasInlineSources = P.ContentTypes.HasSource;
9201db9f3b2SDimitry Andric 
9211db9f3b2SDimitry Andric   if (P.FileNames.empty()) {
9221db9f3b2SDimitry Andric     // file_name_entry_format_count (ubyte).
9231db9f3b2SDimitry Andric     MS->emitInt8(0);
9241db9f3b2SDimitry Andric     LineSectionSize += 1;
9251db9f3b2SDimitry Andric   } else {
9261db9f3b2SDimitry Andric     // file_name_entry_format_count (ubyte).
9271db9f3b2SDimitry Andric     MS->emitInt8(2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0));
9281db9f3b2SDimitry Andric     LineSectionSize += 1;
9291db9f3b2SDimitry Andric 
9301db9f3b2SDimitry Andric     // file_name_entry_format (sequence of ULEB128 pairs).
9311db9f3b2SDimitry Andric     auto StrForm = P.FileNames[0].Name.getForm();
9321db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
9331db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(StrForm);
9341db9f3b2SDimitry Andric 
9351db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
9361db9f3b2SDimitry Andric     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1);
9371db9f3b2SDimitry Andric 
9381db9f3b2SDimitry Andric     if (HasChecksums) {
9391db9f3b2SDimitry Andric       LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_MD5);
9401db9f3b2SDimitry Andric       LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data16);
9411db9f3b2SDimitry Andric     }
9421db9f3b2SDimitry Andric 
9431db9f3b2SDimitry Andric     if (HasInlineSources) {
9441db9f3b2SDimitry Andric       LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
9451db9f3b2SDimitry Andric       LineSectionSize += MS->emitULEB128IntValue(StrForm);
9461db9f3b2SDimitry Andric     }
9471db9f3b2SDimitry Andric   }
9481db9f3b2SDimitry Andric 
9491db9f3b2SDimitry Andric   // file_names_count (ULEB128).
9501db9f3b2SDimitry Andric   LineSectionSize += MS->emitULEB128IntValue(P.FileNames.size());
9511db9f3b2SDimitry Andric 
9521db9f3b2SDimitry Andric   // file_names (sequence of file name entries).
9531db9f3b2SDimitry Andric   for (auto File : P.FileNames) {
9541db9f3b2SDimitry Andric     emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
9551db9f3b2SDimitry Andric     MS->emitInt8(File.DirIdx);
9561db9f3b2SDimitry Andric     LineSectionSize += 1;
9571db9f3b2SDimitry Andric     if (HasChecksums) {
9581db9f3b2SDimitry Andric       MS->emitBinaryData(
9591db9f3b2SDimitry Andric           StringRef(reinterpret_cast<const char *>(File.Checksum.data()),
9601db9f3b2SDimitry Andric                     File.Checksum.size()));
9611db9f3b2SDimitry Andric       LineSectionSize += File.Checksum.size();
9621db9f3b2SDimitry Andric     }
9631db9f3b2SDimitry Andric     if (HasInlineSources)
9641db9f3b2SDimitry Andric       emitLineTableString(P, File.Source, DebugStrPool, DebugLineStrPool);
9651db9f3b2SDimitry Andric   }
9661db9f3b2SDimitry Andric }
9671db9f3b2SDimitry Andric 
emitLineTableString(const DWARFDebugLine::Prologue & P,const DWARFFormValue & String,OffsetsStringPool & DebugStrPool,OffsetsStringPool & DebugLineStrPool)9681db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P,
9691db9f3b2SDimitry Andric                                         const DWARFFormValue &String,
9701db9f3b2SDimitry Andric                                         OffsetsStringPool &DebugStrPool,
9711db9f3b2SDimitry Andric                                         OffsetsStringPool &DebugLineStrPool) {
9721db9f3b2SDimitry Andric   std::optional<const char *> StringVal = dwarf::toString(String);
9731db9f3b2SDimitry Andric   if (!StringVal) {
9741db9f3b2SDimitry Andric     warn("Cann't read string from line table.");
9751db9f3b2SDimitry Andric     return;
9761db9f3b2SDimitry Andric   }
9771db9f3b2SDimitry Andric 
9781db9f3b2SDimitry Andric   switch (String.getForm()) {
9791db9f3b2SDimitry Andric   case dwarf::DW_FORM_string: {
9801db9f3b2SDimitry Andric     StringRef TranslatedString =
9811db9f3b2SDimitry Andric         (Translator) ? Translator(*StringVal) : *StringVal;
9821db9f3b2SDimitry Andric     Asm->OutStreamer->emitBytes(TranslatedString.data());
9831db9f3b2SDimitry Andric     Asm->emitInt8(0);
9841db9f3b2SDimitry Andric     LineSectionSize += TranslatedString.size() + 1;
9851db9f3b2SDimitry Andric   } break;
9861db9f3b2SDimitry Andric   case dwarf::DW_FORM_strp:
9871db9f3b2SDimitry Andric   case dwarf::DW_FORM_line_strp: {
9881db9f3b2SDimitry Andric     DwarfStringPoolEntryRef StringRef =
9891db9f3b2SDimitry Andric         String.getForm() == dwarf::DW_FORM_strp
9901db9f3b2SDimitry Andric             ? DebugStrPool.getEntry(*StringVal)
9911db9f3b2SDimitry Andric             : DebugLineStrPool.getEntry(*StringVal);
9921db9f3b2SDimitry Andric 
9931db9f3b2SDimitry Andric     emitIntOffset(StringRef.getOffset(), P.FormParams.Format, LineSectionSize);
9941db9f3b2SDimitry Andric   } break;
9951db9f3b2SDimitry Andric   default:
9961db9f3b2SDimitry Andric     warn("Unsupported string form inside line table.");
9971db9f3b2SDimitry Andric     break;
9981db9f3b2SDimitry Andric   };
9991db9f3b2SDimitry Andric }
10001db9f3b2SDimitry Andric 
emitLineTableProloguePayload(const DWARFDebugLine::Prologue & P,OffsetsStringPool & DebugStrPool,OffsetsStringPool & DebugLineStrPool)10011db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableProloguePayload(
10021db9f3b2SDimitry Andric     const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
10031db9f3b2SDimitry Andric     OffsetsStringPool &DebugLineStrPool) {
10041db9f3b2SDimitry Andric   // minimum_instruction_length (ubyte).
10051db9f3b2SDimitry Andric   MS->emitInt8(P.MinInstLength);
10061db9f3b2SDimitry Andric   LineSectionSize += 1;
10071db9f3b2SDimitry Andric   if (P.FormParams.Version >= 4) {
10081db9f3b2SDimitry Andric     // maximum_operations_per_instruction (ubyte).
10091db9f3b2SDimitry Andric     MS->emitInt8(P.MaxOpsPerInst);
10101db9f3b2SDimitry Andric     LineSectionSize += 1;
10111db9f3b2SDimitry Andric   }
10121db9f3b2SDimitry Andric   // default_is_stmt (ubyte).
10131db9f3b2SDimitry Andric   MS->emitInt8(P.DefaultIsStmt);
10141db9f3b2SDimitry Andric   LineSectionSize += 1;
10151db9f3b2SDimitry Andric   // line_base (sbyte).
10161db9f3b2SDimitry Andric   MS->emitInt8(P.LineBase);
10171db9f3b2SDimitry Andric   LineSectionSize += 1;
10181db9f3b2SDimitry Andric   // line_range (ubyte).
10191db9f3b2SDimitry Andric   MS->emitInt8(P.LineRange);
10201db9f3b2SDimitry Andric   LineSectionSize += 1;
10211db9f3b2SDimitry Andric   // opcode_base (ubyte).
10221db9f3b2SDimitry Andric   MS->emitInt8(P.OpcodeBase);
10231db9f3b2SDimitry Andric   LineSectionSize += 1;
10241db9f3b2SDimitry Andric 
10251db9f3b2SDimitry Andric   // standard_opcode_lengths (array of ubyte).
10261db9f3b2SDimitry Andric   for (auto Length : P.StandardOpcodeLengths) {
10271db9f3b2SDimitry Andric     MS->emitInt8(Length);
10281db9f3b2SDimitry Andric     LineSectionSize += 1;
10291db9f3b2SDimitry Andric   }
10301db9f3b2SDimitry Andric 
10311db9f3b2SDimitry Andric   if (P.FormParams.Version < 5)
10321db9f3b2SDimitry Andric     emitLineTablePrologueV2IncludeAndFileTable(P, DebugStrPool,
10331db9f3b2SDimitry Andric                                                DebugLineStrPool);
10341db9f3b2SDimitry Andric   else
10351db9f3b2SDimitry Andric     emitLineTablePrologueV5IncludeAndFileTable(P, DebugStrPool,
10361db9f3b2SDimitry Andric                                                DebugLineStrPool);
10371db9f3b2SDimitry Andric }
10381db9f3b2SDimitry Andric 
emitLineTableRows(const DWARFDebugLine::LineTable & LineTable,MCSymbol * LineEndSym,unsigned AddressByteSize)10391db9f3b2SDimitry Andric void DwarfStreamer::emitLineTableRows(
10401db9f3b2SDimitry Andric     const DWARFDebugLine::LineTable &LineTable, MCSymbol *LineEndSym,
10411db9f3b2SDimitry Andric     unsigned AddressByteSize) {
10421db9f3b2SDimitry Andric 
10431db9f3b2SDimitry Andric   MCDwarfLineTableParams Params;
10441db9f3b2SDimitry Andric   Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
10451db9f3b2SDimitry Andric   Params.DWARF2LineBase = LineTable.Prologue.LineBase;
10461db9f3b2SDimitry Andric   Params.DWARF2LineRange = LineTable.Prologue.LineRange;
10471db9f3b2SDimitry Andric 
10481db9f3b2SDimitry Andric   SmallString<128> EncodingBuffer;
10491db9f3b2SDimitry Andric 
10501db9f3b2SDimitry Andric   if (LineTable.Rows.empty()) {
10511db9f3b2SDimitry Andric     // We only have the dummy entry, dsymutil emits an entry with a 0
10521db9f3b2SDimitry Andric     // address in that case.
10531db9f3b2SDimitry Andric     MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
10541db9f3b2SDimitry Andric                             EncodingBuffer);
10551db9f3b2SDimitry Andric     MS->emitBytes(EncodingBuffer);
10561db9f3b2SDimitry Andric     LineSectionSize += EncodingBuffer.size();
10571db9f3b2SDimitry Andric     MS->emitLabel(LineEndSym);
10581db9f3b2SDimitry Andric     return;
10591db9f3b2SDimitry Andric   }
10601db9f3b2SDimitry Andric 
10611db9f3b2SDimitry Andric   // Line table state machine fields
10621db9f3b2SDimitry Andric   unsigned FileNum = 1;
10631db9f3b2SDimitry Andric   unsigned LastLine = 1;
10641db9f3b2SDimitry Andric   unsigned Column = 0;
10651db9f3b2SDimitry Andric   unsigned IsStatement = 1;
10661db9f3b2SDimitry Andric   unsigned Isa = 0;
10671db9f3b2SDimitry Andric   uint64_t Address = -1ULL;
10681db9f3b2SDimitry Andric 
10691db9f3b2SDimitry Andric   unsigned RowsSinceLastSequence = 0;
10701db9f3b2SDimitry Andric 
10711db9f3b2SDimitry Andric   for (const DWARFDebugLine::Row &Row : LineTable.Rows) {
10721db9f3b2SDimitry Andric     int64_t AddressDelta;
10731db9f3b2SDimitry Andric     if (Address == -1ULL) {
10741db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_extended_op, 1);
10751db9f3b2SDimitry Andric       MS->emitULEB128IntValue(AddressByteSize + 1);
10761db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNE_set_address, 1);
10771db9f3b2SDimitry Andric       MS->emitIntValue(Row.Address.Address, AddressByteSize);
10781db9f3b2SDimitry Andric       LineSectionSize +=
10791db9f3b2SDimitry Andric           2 + AddressByteSize + getULEB128Size(AddressByteSize + 1);
10801db9f3b2SDimitry Andric       AddressDelta = 0;
10811db9f3b2SDimitry Andric     } else {
10821db9f3b2SDimitry Andric       AddressDelta =
10831db9f3b2SDimitry Andric           (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength;
10841db9f3b2SDimitry Andric     }
10851db9f3b2SDimitry Andric 
10861db9f3b2SDimitry Andric     // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable.
10871db9f3b2SDimitry Andric     // We should find a way to share this code, but the current compatibility
10881db9f3b2SDimitry Andric     // requirement with classic dsymutil makes it hard. Revisit that once this
10891db9f3b2SDimitry Andric     // requirement is dropped.
10901db9f3b2SDimitry Andric 
10911db9f3b2SDimitry Andric     if (FileNum != Row.File) {
10921db9f3b2SDimitry Andric       FileNum = Row.File;
10931db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_set_file, 1);
10941db9f3b2SDimitry Andric       MS->emitULEB128IntValue(FileNum);
10951db9f3b2SDimitry Andric       LineSectionSize += 1 + getULEB128Size(FileNum);
10961db9f3b2SDimitry Andric     }
10971db9f3b2SDimitry Andric     if (Column != Row.Column) {
10981db9f3b2SDimitry Andric       Column = Row.Column;
10991db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_set_column, 1);
11001db9f3b2SDimitry Andric       MS->emitULEB128IntValue(Column);
11011db9f3b2SDimitry Andric       LineSectionSize += 1 + getULEB128Size(Column);
11021db9f3b2SDimitry Andric     }
11031db9f3b2SDimitry Andric 
11041db9f3b2SDimitry Andric     // FIXME: We should handle the discriminator here, but dsymutil doesn't
11051db9f3b2SDimitry Andric     // consider it, thus ignore it for now.
11061db9f3b2SDimitry Andric 
11071db9f3b2SDimitry Andric     if (Isa != Row.Isa) {
11081db9f3b2SDimitry Andric       Isa = Row.Isa;
11091db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_set_isa, 1);
11101db9f3b2SDimitry Andric       MS->emitULEB128IntValue(Isa);
11111db9f3b2SDimitry Andric       LineSectionSize += 1 + getULEB128Size(Isa);
11121db9f3b2SDimitry Andric     }
11131db9f3b2SDimitry Andric     if (IsStatement != Row.IsStmt) {
11141db9f3b2SDimitry Andric       IsStatement = Row.IsStmt;
11151db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_negate_stmt, 1);
11161db9f3b2SDimitry Andric       LineSectionSize += 1;
11171db9f3b2SDimitry Andric     }
11181db9f3b2SDimitry Andric     if (Row.BasicBlock) {
11191db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_set_basic_block, 1);
11201db9f3b2SDimitry Andric       LineSectionSize += 1;
11211db9f3b2SDimitry Andric     }
11221db9f3b2SDimitry Andric 
11231db9f3b2SDimitry Andric     if (Row.PrologueEnd) {
11241db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
11251db9f3b2SDimitry Andric       LineSectionSize += 1;
11261db9f3b2SDimitry Andric     }
11271db9f3b2SDimitry Andric 
11281db9f3b2SDimitry Andric     if (Row.EpilogueBegin) {
11291db9f3b2SDimitry Andric       MS->emitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
11301db9f3b2SDimitry Andric       LineSectionSize += 1;
11311db9f3b2SDimitry Andric     }
11321db9f3b2SDimitry Andric 
11331db9f3b2SDimitry Andric     int64_t LineDelta = int64_t(Row.Line) - LastLine;
11341db9f3b2SDimitry Andric     if (!Row.EndSequence) {
11351db9f3b2SDimitry Andric       MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta,
11361db9f3b2SDimitry Andric                               EncodingBuffer);
11371db9f3b2SDimitry Andric       MS->emitBytes(EncodingBuffer);
11381db9f3b2SDimitry Andric       LineSectionSize += EncodingBuffer.size();
11391db9f3b2SDimitry Andric       EncodingBuffer.resize(0);
11401db9f3b2SDimitry Andric       Address = Row.Address.Address;
11411db9f3b2SDimitry Andric       LastLine = Row.Line;
11421db9f3b2SDimitry Andric       RowsSinceLastSequence++;
11431db9f3b2SDimitry Andric     } else {
11441db9f3b2SDimitry Andric       if (LineDelta) {
11451db9f3b2SDimitry Andric         MS->emitIntValue(dwarf::DW_LNS_advance_line, 1);
11461db9f3b2SDimitry Andric         MS->emitSLEB128IntValue(LineDelta);
11471db9f3b2SDimitry Andric         LineSectionSize += 1 + getSLEB128Size(LineDelta);
11481db9f3b2SDimitry Andric       }
11491db9f3b2SDimitry Andric       if (AddressDelta) {
11501db9f3b2SDimitry Andric         MS->emitIntValue(dwarf::DW_LNS_advance_pc, 1);
11511db9f3b2SDimitry Andric         MS->emitULEB128IntValue(AddressDelta);
11521db9f3b2SDimitry Andric         LineSectionSize += 1 + getULEB128Size(AddressDelta);
11531db9f3b2SDimitry Andric       }
11541db9f3b2SDimitry Andric       MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(),
11551db9f3b2SDimitry Andric                               0, EncodingBuffer);
11561db9f3b2SDimitry Andric       MS->emitBytes(EncodingBuffer);
11571db9f3b2SDimitry Andric       LineSectionSize += EncodingBuffer.size();
11581db9f3b2SDimitry Andric       EncodingBuffer.resize(0);
11591db9f3b2SDimitry Andric       Address = -1ULL;
11601db9f3b2SDimitry Andric       LastLine = FileNum = IsStatement = 1;
11611db9f3b2SDimitry Andric       RowsSinceLastSequence = Column = Isa = 0;
11621db9f3b2SDimitry Andric     }
11631db9f3b2SDimitry Andric   }
11641db9f3b2SDimitry Andric 
11651db9f3b2SDimitry Andric   if (RowsSinceLastSequence) {
11661db9f3b2SDimitry Andric     MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
11671db9f3b2SDimitry Andric                             EncodingBuffer);
11681db9f3b2SDimitry Andric     MS->emitBytes(EncodingBuffer);
11691db9f3b2SDimitry Andric     LineSectionSize += EncodingBuffer.size();
11701db9f3b2SDimitry Andric     EncodingBuffer.resize(0);
11711db9f3b2SDimitry Andric   }
11721db9f3b2SDimitry Andric 
11731db9f3b2SDimitry Andric   MS->emitLabel(LineEndSym);
11741db9f3b2SDimitry Andric }
11751db9f3b2SDimitry Andric 
emitIntOffset(uint64_t Offset,dwarf::DwarfFormat Format,uint64_t & SectionSize)11761db9f3b2SDimitry Andric void DwarfStreamer::emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format,
11771db9f3b2SDimitry Andric                                   uint64_t &SectionSize) {
11781db9f3b2SDimitry Andric   uint8_t Size = dwarf::getDwarfOffsetByteSize(Format);
11791db9f3b2SDimitry Andric   MS->emitIntValue(Offset, Size);
11801db9f3b2SDimitry Andric   SectionSize += Size;
11811db9f3b2SDimitry Andric }
11821db9f3b2SDimitry Andric 
emitLabelDifference(const MCSymbol * Hi,const MCSymbol * Lo,dwarf::DwarfFormat Format,uint64_t & SectionSize)11831db9f3b2SDimitry Andric void DwarfStreamer::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
11841db9f3b2SDimitry Andric                                         dwarf::DwarfFormat Format,
11851db9f3b2SDimitry Andric                                         uint64_t &SectionSize) {
11861db9f3b2SDimitry Andric   uint8_t Size = dwarf::getDwarfOffsetByteSize(Format);
11871db9f3b2SDimitry Andric   Asm->emitLabelDifference(Hi, Lo, Size);
11881db9f3b2SDimitry Andric   SectionSize += Size;
11891db9f3b2SDimitry Andric }
11901db9f3b2SDimitry Andric 
11911db9f3b2SDimitry Andric /// Emit the pubnames or pubtypes section contribution for \p
11921db9f3b2SDimitry Andric /// Unit into \p Sec. The data is provided in \p Names.
emitPubSectionForUnit(MCSection * Sec,StringRef SecName,const CompileUnit & Unit,const std::vector<CompileUnit::AccelInfo> & Names)11931db9f3b2SDimitry Andric void DwarfStreamer::emitPubSectionForUnit(
11941db9f3b2SDimitry Andric     MCSection *Sec, StringRef SecName, const CompileUnit &Unit,
11951db9f3b2SDimitry Andric     const std::vector<CompileUnit::AccelInfo> &Names) {
11961db9f3b2SDimitry Andric   if (Names.empty())
11971db9f3b2SDimitry Andric     return;
11981db9f3b2SDimitry Andric 
11991db9f3b2SDimitry Andric   // Start the dwarf pubnames section.
12001db9f3b2SDimitry Andric   Asm->OutStreamer->switchSection(Sec);
12011db9f3b2SDimitry Andric   MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin");
12021db9f3b2SDimitry Andric   MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end");
12031db9f3b2SDimitry Andric 
12041db9f3b2SDimitry Andric   bool HeaderEmitted = false;
12051db9f3b2SDimitry Andric   // Emit the pubnames for this compilation unit.
12061db9f3b2SDimitry Andric   for (const auto &Name : Names) {
12071db9f3b2SDimitry Andric     if (Name.SkipPubSection)
12081db9f3b2SDimitry Andric       continue;
12091db9f3b2SDimitry Andric 
12101db9f3b2SDimitry Andric     if (!HeaderEmitted) {
12111db9f3b2SDimitry Andric       // Emit the header.
12121db9f3b2SDimitry Andric       Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Length
12131db9f3b2SDimitry Andric       Asm->OutStreamer->emitLabel(BeginLabel);
12141db9f3b2SDimitry Andric       Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION); // Version
12151db9f3b2SDimitry Andric       Asm->emitInt32(Unit.getStartOffset());      // Unit offset
12161db9f3b2SDimitry Andric       Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size
12171db9f3b2SDimitry Andric       HeaderEmitted = true;
12181db9f3b2SDimitry Andric     }
12191db9f3b2SDimitry Andric     Asm->emitInt32(Name.Die->getOffset());
12201db9f3b2SDimitry Andric 
12211db9f3b2SDimitry Andric     // Emit the string itself.
12221db9f3b2SDimitry Andric     Asm->OutStreamer->emitBytes(Name.Name.getString());
12231db9f3b2SDimitry Andric     // Emit a null terminator.
12241db9f3b2SDimitry Andric     Asm->emitInt8(0);
12251db9f3b2SDimitry Andric   }
12261db9f3b2SDimitry Andric 
12271db9f3b2SDimitry Andric   if (!HeaderEmitted)
12281db9f3b2SDimitry Andric     return;
12291db9f3b2SDimitry Andric   Asm->emitInt32(0); // End marker.
12301db9f3b2SDimitry Andric   Asm->OutStreamer->emitLabel(EndLabel);
12311db9f3b2SDimitry Andric }
12321db9f3b2SDimitry Andric 
12331db9f3b2SDimitry Andric /// Emit .debug_pubnames for \p Unit.
emitPubNamesForUnit(const CompileUnit & Unit)12341db9f3b2SDimitry Andric void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
12351db9f3b2SDimitry Andric   emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
12361db9f3b2SDimitry Andric                         "names", Unit, Unit.getPubnames());
12371db9f3b2SDimitry Andric }
12381db9f3b2SDimitry Andric 
12391db9f3b2SDimitry Andric /// Emit .debug_pubtypes for \p Unit.
emitPubTypesForUnit(const CompileUnit & Unit)12401db9f3b2SDimitry Andric void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) {
12411db9f3b2SDimitry Andric   emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
12421db9f3b2SDimitry Andric                         "types", Unit, Unit.getPubtypes());
12431db9f3b2SDimitry Andric }
12441db9f3b2SDimitry Andric 
12451db9f3b2SDimitry Andric /// Emit a CIE into the debug_frame section.
emitCIE(StringRef CIEBytes)12461db9f3b2SDimitry Andric void DwarfStreamer::emitCIE(StringRef CIEBytes) {
12471db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
12481db9f3b2SDimitry Andric 
12491db9f3b2SDimitry Andric   MS->emitBytes(CIEBytes);
12501db9f3b2SDimitry Andric   FrameSectionSize += CIEBytes.size();
12511db9f3b2SDimitry Andric }
12521db9f3b2SDimitry Andric 
12531db9f3b2SDimitry Andric /// Emit a FDE into the debug_frame section. \p FDEBytes
12541db9f3b2SDimitry Andric /// contains the FDE data without the length, CIE offset and address
12551db9f3b2SDimitry Andric /// which will be replaced with the parameter values.
emitFDE(uint32_t CIEOffset,uint32_t AddrSize,uint64_t Address,StringRef FDEBytes)12561db9f3b2SDimitry Andric void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize,
12571db9f3b2SDimitry Andric                             uint64_t Address, StringRef FDEBytes) {
12581db9f3b2SDimitry Andric   MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
12591db9f3b2SDimitry Andric 
12601db9f3b2SDimitry Andric   MS->emitIntValue(FDEBytes.size() + 4 + AddrSize, 4);
12611db9f3b2SDimitry Andric   MS->emitIntValue(CIEOffset, 4);
12621db9f3b2SDimitry Andric   MS->emitIntValue(Address, AddrSize);
12631db9f3b2SDimitry Andric   MS->emitBytes(FDEBytes);
12641db9f3b2SDimitry Andric   FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
12651db9f3b2SDimitry Andric }
12661db9f3b2SDimitry Andric 
emitMacroTables(DWARFContext * Context,const Offset2UnitMap & UnitMacroMap,OffsetsStringPool & StringPool)12671db9f3b2SDimitry Andric void DwarfStreamer::emitMacroTables(DWARFContext *Context,
12681db9f3b2SDimitry Andric                                     const Offset2UnitMap &UnitMacroMap,
12691db9f3b2SDimitry Andric                                     OffsetsStringPool &StringPool) {
12701db9f3b2SDimitry Andric   assert(Context != nullptr && "Empty DWARF context");
12711db9f3b2SDimitry Andric 
12721db9f3b2SDimitry Andric   // Check for .debug_macinfo table.
12731db9f3b2SDimitry Andric   if (const DWARFDebugMacro *Table = Context->getDebugMacinfo()) {
12741db9f3b2SDimitry Andric     MS->switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection());
12751db9f3b2SDimitry Andric     emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacInfoSectionSize);
12761db9f3b2SDimitry Andric   }
12771db9f3b2SDimitry Andric 
12781db9f3b2SDimitry Andric   // Check for .debug_macro table.
12791db9f3b2SDimitry Andric   if (const DWARFDebugMacro *Table = Context->getDebugMacro()) {
12801db9f3b2SDimitry Andric     MS->switchSection(MC->getObjectFileInfo()->getDwarfMacroSection());
12811db9f3b2SDimitry Andric     emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacroSectionSize);
12821db9f3b2SDimitry Andric   }
12831db9f3b2SDimitry Andric }
12841db9f3b2SDimitry Andric 
emitMacroTableImpl(const DWARFDebugMacro * MacroTable,const Offset2UnitMap & UnitMacroMap,OffsetsStringPool & StringPool,uint64_t & OutOffset)12851db9f3b2SDimitry Andric void DwarfStreamer::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
12861db9f3b2SDimitry Andric                                        const Offset2UnitMap &UnitMacroMap,
12871db9f3b2SDimitry Andric                                        OffsetsStringPool &StringPool,
12881db9f3b2SDimitry Andric                                        uint64_t &OutOffset) {
12891db9f3b2SDimitry Andric   bool DefAttributeIsReported = false;
12901db9f3b2SDimitry Andric   bool UndefAttributeIsReported = false;
12911db9f3b2SDimitry Andric   bool ImportAttributeIsReported = false;
12921db9f3b2SDimitry Andric   for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
12931db9f3b2SDimitry Andric     Offset2UnitMap::const_iterator UnitIt = UnitMacroMap.find(List.Offset);
12941db9f3b2SDimitry Andric     if (UnitIt == UnitMacroMap.end()) {
12951db9f3b2SDimitry Andric       warn(formatv(
12961db9f3b2SDimitry Andric           "couldn`t find compile unit for the macro table with offset = {0:x}",
12971db9f3b2SDimitry Andric           List.Offset));
12981db9f3b2SDimitry Andric       continue;
12991db9f3b2SDimitry Andric     }
13001db9f3b2SDimitry Andric 
13011db9f3b2SDimitry Andric     // Skip macro table if the unit was not cloned.
13021db9f3b2SDimitry Andric     DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE();
13031db9f3b2SDimitry Andric     if (OutputUnitDIE == nullptr)
13041db9f3b2SDimitry Andric       continue;
13051db9f3b2SDimitry Andric 
13061db9f3b2SDimitry Andric     // Update macro attribute of cloned compile unit with the proper offset to
13071db9f3b2SDimitry Andric     // the macro table.
13081db9f3b2SDimitry Andric     bool hasDWARFv5Header = false;
13091db9f3b2SDimitry Andric     for (auto &V : OutputUnitDIE->values()) {
13101db9f3b2SDimitry Andric       if (V.getAttribute() == dwarf::DW_AT_macro_info) {
13111db9f3b2SDimitry Andric         V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset));
13121db9f3b2SDimitry Andric         break;
13131db9f3b2SDimitry Andric       } else if (V.getAttribute() == dwarf::DW_AT_macros) {
13141db9f3b2SDimitry Andric         hasDWARFv5Header = true;
13151db9f3b2SDimitry Andric         V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset));
13161db9f3b2SDimitry Andric         break;
13171db9f3b2SDimitry Andric       }
13181db9f3b2SDimitry Andric     }
13191db9f3b2SDimitry Andric 
13201db9f3b2SDimitry Andric     // Write DWARFv5 header.
13211db9f3b2SDimitry Andric     if (hasDWARFv5Header) {
13221db9f3b2SDimitry Andric       // Write header version.
13231db9f3b2SDimitry Andric       MS->emitIntValue(List.Header.Version, sizeof(List.Header.Version));
13241db9f3b2SDimitry Andric       OutOffset += sizeof(List.Header.Version);
13251db9f3b2SDimitry Andric 
13261db9f3b2SDimitry Andric       uint8_t Flags = List.Header.Flags;
13271db9f3b2SDimitry Andric 
13281db9f3b2SDimitry Andric       // Check for OPCODE_OPERANDS_TABLE.
13291db9f3b2SDimitry Andric       if (Flags &
13301db9f3b2SDimitry Andric           DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
13311db9f3b2SDimitry Andric         Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
13321db9f3b2SDimitry Andric         warn("opcode_operands_table is not supported yet.");
13331db9f3b2SDimitry Andric       }
13341db9f3b2SDimitry Andric 
13351db9f3b2SDimitry Andric       // Check for DEBUG_LINE_OFFSET.
13361db9f3b2SDimitry Andric       std::optional<uint64_t> StmtListOffset;
13371db9f3b2SDimitry Andric       if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
13381db9f3b2SDimitry Andric         // Get offset to the line table from the cloned compile unit.
13391db9f3b2SDimitry Andric         for (auto &V : OutputUnitDIE->values()) {
13401db9f3b2SDimitry Andric           if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
13411db9f3b2SDimitry Andric             StmtListOffset = V.getDIEInteger().getValue();
13421db9f3b2SDimitry Andric             break;
13431db9f3b2SDimitry Andric           }
13441db9f3b2SDimitry Andric         }
13451db9f3b2SDimitry Andric 
13461db9f3b2SDimitry Andric         if (!StmtListOffset) {
13471db9f3b2SDimitry Andric           Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
13481db9f3b2SDimitry Andric           warn("couldn`t find line table for macro table.");
13491db9f3b2SDimitry Andric         }
13501db9f3b2SDimitry Andric       }
13511db9f3b2SDimitry Andric 
13521db9f3b2SDimitry Andric       // Write flags.
13531db9f3b2SDimitry Andric       MS->emitIntValue(Flags, sizeof(Flags));
13541db9f3b2SDimitry Andric       OutOffset += sizeof(Flags);
13551db9f3b2SDimitry Andric 
13561db9f3b2SDimitry Andric       // Write offset to line table.
13571db9f3b2SDimitry Andric       if (StmtListOffset) {
13581db9f3b2SDimitry Andric         MS->emitIntValue(*StmtListOffset, List.Header.getOffsetByteSize());
13591db9f3b2SDimitry Andric         OutOffset += List.Header.getOffsetByteSize();
13601db9f3b2SDimitry Andric       }
13611db9f3b2SDimitry Andric     }
13621db9f3b2SDimitry Andric 
13631db9f3b2SDimitry Andric     // Write macro entries.
13641db9f3b2SDimitry Andric     for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
13651db9f3b2SDimitry Andric       if (MacroEntry.Type == 0) {
13661db9f3b2SDimitry Andric         OutOffset += MS->emitULEB128IntValue(MacroEntry.Type);
13671db9f3b2SDimitry Andric         continue;
13681db9f3b2SDimitry Andric       }
13691db9f3b2SDimitry Andric 
13701db9f3b2SDimitry Andric       uint8_t MacroType = MacroEntry.Type;
13711db9f3b2SDimitry Andric       switch (MacroType) {
13721db9f3b2SDimitry Andric       default: {
13731db9f3b2SDimitry Andric         bool HasVendorSpecificExtension =
13741db9f3b2SDimitry Andric             (!hasDWARFv5Header && MacroType == dwarf::DW_MACINFO_vendor_ext) ||
13751db9f3b2SDimitry Andric             (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
13761db9f3b2SDimitry Andric                                   MacroType <= dwarf::DW_MACRO_hi_user));
13771db9f3b2SDimitry Andric 
13781db9f3b2SDimitry Andric         if (HasVendorSpecificExtension) {
13791db9f3b2SDimitry Andric           // Write macinfo type.
13801db9f3b2SDimitry Andric           MS->emitIntValue(MacroType, 1);
13811db9f3b2SDimitry Andric           OutOffset++;
13821db9f3b2SDimitry Andric 
13831db9f3b2SDimitry Andric           // Write vendor extension constant.
13841db9f3b2SDimitry Andric           OutOffset += MS->emitULEB128IntValue(MacroEntry.ExtConstant);
13851db9f3b2SDimitry Andric 
13861db9f3b2SDimitry Andric           // Write vendor extension string.
13871db9f3b2SDimitry Andric           StringRef String = MacroEntry.ExtStr;
13881db9f3b2SDimitry Andric           MS->emitBytes(String);
13891db9f3b2SDimitry Andric           MS->emitIntValue(0, 1);
13901db9f3b2SDimitry Andric           OutOffset += String.size() + 1;
13911db9f3b2SDimitry Andric         } else
13921db9f3b2SDimitry Andric           warn("unknown macro type. skip.");
13931db9f3b2SDimitry Andric       } break;
13941db9f3b2SDimitry Andric       // debug_macro and debug_macinfo share some common encodings.
13951db9f3b2SDimitry Andric       // DW_MACRO_define     == DW_MACINFO_define
13961db9f3b2SDimitry Andric       // DW_MACRO_undef      == DW_MACINFO_undef
13971db9f3b2SDimitry Andric       // DW_MACRO_start_file == DW_MACINFO_start_file
13981db9f3b2SDimitry Andric       // DW_MACRO_end_file   == DW_MACINFO_end_file
13991db9f3b2SDimitry Andric       // For readibility/uniformity we are using DW_MACRO_*.
14001db9f3b2SDimitry Andric       case dwarf::DW_MACRO_define:
14011db9f3b2SDimitry Andric       case dwarf::DW_MACRO_undef: {
14021db9f3b2SDimitry Andric         // Write macinfo type.
14031db9f3b2SDimitry Andric         MS->emitIntValue(MacroType, 1);
14041db9f3b2SDimitry Andric         OutOffset++;
14051db9f3b2SDimitry Andric 
14061db9f3b2SDimitry Andric         // Write source line.
14071db9f3b2SDimitry Andric         OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
14081db9f3b2SDimitry Andric 
14091db9f3b2SDimitry Andric         // Write macro string.
14101db9f3b2SDimitry Andric         StringRef String = MacroEntry.MacroStr;
14111db9f3b2SDimitry Andric         MS->emitBytes(String);
14121db9f3b2SDimitry Andric         MS->emitIntValue(0, 1);
14131db9f3b2SDimitry Andric         OutOffset += String.size() + 1;
14141db9f3b2SDimitry Andric       } break;
14151db9f3b2SDimitry Andric       case dwarf::DW_MACRO_define_strp:
14161db9f3b2SDimitry Andric       case dwarf::DW_MACRO_undef_strp:
14171db9f3b2SDimitry Andric       case dwarf::DW_MACRO_define_strx:
14181db9f3b2SDimitry Andric       case dwarf::DW_MACRO_undef_strx: {
14191db9f3b2SDimitry Andric         assert(UnitIt->second->getOrigUnit().getVersion() >= 5);
14201db9f3b2SDimitry Andric 
14211db9f3b2SDimitry Andric         // DW_MACRO_*_strx forms are not supported currently.
14221db9f3b2SDimitry Andric         // Convert to *_strp.
14231db9f3b2SDimitry Andric         switch (MacroType) {
14241db9f3b2SDimitry Andric         case dwarf::DW_MACRO_define_strx: {
14251db9f3b2SDimitry Andric           MacroType = dwarf::DW_MACRO_define_strp;
14261db9f3b2SDimitry Andric           if (!DefAttributeIsReported) {
14271db9f3b2SDimitry Andric             warn("DW_MACRO_define_strx unsupported yet. Convert to "
14281db9f3b2SDimitry Andric                  "DW_MACRO_define_strp.");
14291db9f3b2SDimitry Andric             DefAttributeIsReported = true;
14301db9f3b2SDimitry Andric           }
14311db9f3b2SDimitry Andric         } break;
14321db9f3b2SDimitry Andric         case dwarf::DW_MACRO_undef_strx: {
14331db9f3b2SDimitry Andric           MacroType = dwarf::DW_MACRO_undef_strp;
14341db9f3b2SDimitry Andric           if (!UndefAttributeIsReported) {
14351db9f3b2SDimitry Andric             warn("DW_MACRO_undef_strx unsupported yet. Convert to "
14361db9f3b2SDimitry Andric                  "DW_MACRO_undef_strp.");
14371db9f3b2SDimitry Andric             UndefAttributeIsReported = true;
14381db9f3b2SDimitry Andric           }
14391db9f3b2SDimitry Andric         } break;
14401db9f3b2SDimitry Andric         default:
14411db9f3b2SDimitry Andric           // Nothing to do.
14421db9f3b2SDimitry Andric           break;
14431db9f3b2SDimitry Andric         }
14441db9f3b2SDimitry Andric 
14451db9f3b2SDimitry Andric         // Write macinfo type.
14461db9f3b2SDimitry Andric         MS->emitIntValue(MacroType, 1);
14471db9f3b2SDimitry Andric         OutOffset++;
14481db9f3b2SDimitry Andric 
14491db9f3b2SDimitry Andric         // Write source line.
14501db9f3b2SDimitry Andric         OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
14511db9f3b2SDimitry Andric 
14521db9f3b2SDimitry Andric         // Write macro string.
14531db9f3b2SDimitry Andric         DwarfStringPoolEntryRef EntryRef =
14541db9f3b2SDimitry Andric             StringPool.getEntry(MacroEntry.MacroStr);
14551db9f3b2SDimitry Andric         MS->emitIntValue(EntryRef.getOffset(), List.Header.getOffsetByteSize());
14561db9f3b2SDimitry Andric         OutOffset += List.Header.getOffsetByteSize();
14571db9f3b2SDimitry Andric         break;
14581db9f3b2SDimitry Andric       }
14591db9f3b2SDimitry Andric       case dwarf::DW_MACRO_start_file: {
14601db9f3b2SDimitry Andric         // Write macinfo type.
14611db9f3b2SDimitry Andric         MS->emitIntValue(MacroType, 1);
14621db9f3b2SDimitry Andric         OutOffset++;
14631db9f3b2SDimitry Andric         // Write source line.
14641db9f3b2SDimitry Andric         OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
14651db9f3b2SDimitry Andric         // Write source file id.
14661db9f3b2SDimitry Andric         OutOffset += MS->emitULEB128IntValue(MacroEntry.File);
14671db9f3b2SDimitry Andric       } break;
14681db9f3b2SDimitry Andric       case dwarf::DW_MACRO_end_file: {
14691db9f3b2SDimitry Andric         // Write macinfo type.
14701db9f3b2SDimitry Andric         MS->emitIntValue(MacroType, 1);
14711db9f3b2SDimitry Andric         OutOffset++;
14721db9f3b2SDimitry Andric       } break;
14731db9f3b2SDimitry Andric       case dwarf::DW_MACRO_import:
14741db9f3b2SDimitry Andric       case dwarf::DW_MACRO_import_sup: {
14751db9f3b2SDimitry Andric         if (!ImportAttributeIsReported) {
14761db9f3b2SDimitry Andric           warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
14771db9f3b2SDimitry Andric                "remove.");
14781db9f3b2SDimitry Andric           ImportAttributeIsReported = true;
14791db9f3b2SDimitry Andric         }
14801db9f3b2SDimitry Andric       } break;
14811db9f3b2SDimitry Andric       }
14821db9f3b2SDimitry Andric     }
14831db9f3b2SDimitry Andric   }
14841db9f3b2SDimitry Andric }
1485