//===- DwarfStreamer.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/DWARFLinker/DWARFStreamer.h"
#include "llvm/CodeGen/NonRelocatableStringpool.h"
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/Triple.h"

namespace llvm {

Error DwarfStreamer::init(Triple TheTriple,
                          StringRef Swift5ReflectionSegmentName) {
  std::string ErrorStr;
  std::string TripleName;

  // Get the target.
  const Target *TheTarget =
      TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
  if (!TheTarget)
    return createStringError(std::errc::invalid_argument, ErrorStr.c_str());

  TripleName = TheTriple.getTriple();

  // Create all the MC Objects.
  MRI.reset(TheTarget->createMCRegInfo(TripleName));
  if (!MRI)
    return createStringError(std::errc::invalid_argument,
                             "no register info for target %s",
                             TripleName.c_str());

  MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
  MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
  if (!MAI)
    return createStringError(std::errc::invalid_argument,
                             "no asm info for target %s", TripleName.c_str());

  MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
  if (!MSTI)
    return createStringError(std::errc::invalid_argument,
                             "no subtarget info for target %s",
                             TripleName.c_str());

  MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,
                         nullptr, true, Swift5ReflectionSegmentName));
  MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false));
  MC->setObjectFileInfo(MOFI.get());

  MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);
  if (!MAB)
    return createStringError(std::errc::invalid_argument,
                             "no asm backend for target %s",
                             TripleName.c_str());

  MII.reset(TheTarget->createMCInstrInfo());
  if (!MII)
    return createStringError(std::errc::invalid_argument,
                             "no instr info info for target %s",
                             TripleName.c_str());

  MCE = TheTarget->createMCCodeEmitter(*MII, *MC);
  if (!MCE)
    return createStringError(std::errc::invalid_argument,
                             "no code emitter for target %s",
                             TripleName.c_str());

  switch (OutFileType) {
  case DWARFLinker::OutputFileType::Assembly: {
    MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),
                                         *MAI, *MII, *MRI);
    MS = TheTarget->createAsmStreamer(
        *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP,
        std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB),
        true);
    break;
  }
  case DWARFLinker::OutputFileType::Object: {
    MS = TheTarget->createMCObjectStreamer(
        TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),
        MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),
        *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ false);
    break;
  }
  }

  if (!MS)
    return createStringError(std::errc::invalid_argument,
                             "no object streamer for target %s",
                             TripleName.c_str());

  // Finally create the AsmPrinter we'll use to emit the DIEs.
  TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),
                                          std::nullopt));
  if (!TM)
    return createStringError(std::errc::invalid_argument,
                             "no target machine for target %s",
                             TripleName.c_str());

  Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));
  if (!Asm)
    return createStringError(std::errc::invalid_argument,
                             "no asm printer for target %s",
                             TripleName.c_str());
  Asm->setDwarfUsesRelocationsAcrossSections(false);

  RangesSectionSize = 0;
  RngListsSectionSize = 0;
  LocSectionSize = 0;
  LocListsSectionSize = 0;
  LineSectionSize = 0;
  FrameSectionSize = 0;
  DebugInfoSectionSize = 0;
  MacInfoSectionSize = 0;
  MacroSectionSize = 0;

  return Error::success();
}

void DwarfStreamer::finish() { MS->finish(); }

void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) {
  MS->switchSection(MOFI->getDwarfInfoSection());
  MC->setDwarfVersion(DwarfVersion);
}

/// Emit the compilation unit header for \p Unit in the debug_info section.
///
/// A Dwarf 4 section header is encoded as:
///  uint32_t   Unit length (omitting this field)
///  uint16_t   Version
///  uint32_t   Abbreviation table offset
///  uint8_t    Address size
/// Leading to a total of 11 bytes.
///
/// A Dwarf 5 section header is encoded as:
///  uint32_t   Unit length (omitting this field)
///  uint16_t   Version
///  uint8_t    Unit type
///  uint8_t    Address size
///  uint32_t   Abbreviation table offset
/// Leading to a total of 12 bytes.
void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit,
                                          unsigned DwarfVersion) {
  switchToDebugInfoSection(DwarfVersion);

  /// The start of the unit within its section.
  Unit.setLabelBegin(Asm->createTempSymbol("cu_begin"));
  Asm->OutStreamer->emitLabel(Unit.getLabelBegin());

  // Emit size of content not including length itself. The size has already
  // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
  // account for the length field.
  Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4);
  Asm->emitInt16(DwarfVersion);

  if (DwarfVersion >= 5) {
    Asm->emitInt8(dwarf::DW_UT_compile);
    Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
    // We share one abbreviations table across all units so it's always at the
    // start of the section.
    Asm->emitInt32(0);
    DebugInfoSectionSize += 12;
  } else {
    // We share one abbreviations table across all units so it's always at the
    // start of the section.
    Asm->emitInt32(0);
    Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize());
    DebugInfoSectionSize += 11;
  }

  // Remember this CU.
  EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()});
}

/// Emit the \p Abbrevs array as the shared abbreviation table
/// for the linked Dwarf file.
void DwarfStreamer::emitAbbrevs(
    const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
    unsigned DwarfVersion) {
  MS->switchSection(MOFI->getDwarfAbbrevSection());
  MC->setDwarfVersion(DwarfVersion);
  Asm->emitDwarfAbbrevs(Abbrevs);
}

/// Recursively emit the DIE tree rooted at \p Die.
void DwarfStreamer::emitDIE(DIE &Die) {
  MS->switchSection(MOFI->getDwarfInfoSection());
  Asm->emitDwarfDIE(Die);
  DebugInfoSectionSize += Die.getSize();
}

/// Emit contents of section SecName From Obj.
void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) {
  MCSection *Section =
      StringSwitch<MCSection *>(SecName)
          .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
          .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
          .Case("debug_ranges",
                MC->getObjectFileInfo()->getDwarfRangesSection())
          .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
          .Case("debug_aranges",
                MC->getObjectFileInfo()->getDwarfARangesSection())
          .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
          .Case("debug_rnglists",
                MC->getObjectFileInfo()->getDwarfRnglistsSection())
          .Case("debug_loclists",
                MC->getObjectFileInfo()->getDwarfLoclistsSection())
          .Default(nullptr);

  if (Section) {
    MS->switchSection(Section);

    MS->emitBytes(SecData);
  }
}

/// Emit the debug_str section stored in \p Pool.
void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
  Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());
  std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission();
  for (auto Entry : Entries) {
    // Emit the string itself.
    Asm->OutStreamer->emitBytes(Entry.getString());
    // Emit a null terminator.
    Asm->emitInt8(0);
  }
}

/// Emit the debug string offset table described by \p StringOffsets into the
/// .debug_str_offsets table.
void DwarfStreamer::emitStringOffsets(
    const SmallVector<uint64_t> &StringOffsets, uint16_t TargetDWARFVersion) {

  if (TargetDWARFVersion < 5 || StringOffsets.empty())
    return;

  Asm->OutStreamer->switchSection(MOFI->getDwarfStrOffSection());

  MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugstroff");
  MCSymbol *EndLabel = Asm->createTempSymbol("Edebugstroff");

  // Length.
  Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
  Asm->OutStreamer->emitLabel(BeginLabel);
  StrOffsetSectionSize += sizeof(uint32_t);

  // Version.
  MS->emitInt16(5);
  StrOffsetSectionSize += sizeof(uint16_t);

  // Padding.
  MS->emitInt16(0);
  StrOffsetSectionSize += sizeof(uint16_t);

  for (auto Off : StringOffsets) {
    Asm->OutStreamer->emitInt32(Off);
    StrOffsetSectionSize += sizeof(uint32_t);
  }
  Asm->OutStreamer->emitLabel(EndLabel);
}

/// Emit the debug_line_str section stored in \p Pool.
void DwarfStreamer::emitLineStrings(const NonRelocatableStringpool &Pool) {
  Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection());
  std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission();
  for (auto Entry : Entries) {
    // Emit the string itself.
    Asm->OutStreamer->emitBytes(Entry.getString());
    // Emit a null terminator.
    Asm->emitInt8(0);
  }
}

void DwarfStreamer::emitDebugNames(
    AccelTable<DWARF5AccelTableStaticData> &Table) {
  if (EmittedUnits.empty())
    return;

  // Build up data structures needed to emit this section.
  std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits;
  DenseMap<unsigned, size_t> UniqueIdToCuMap;
  unsigned Id = 0;
  for (auto &CU : EmittedUnits) {
    CompUnits.push_back(CU.LabelBegin);
    // We might be omitting CUs, so we need to remap them.
    UniqueIdToCuMap[CU.ID] = Id++;
  }

  Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());
  emitDWARF5AccelTable(
      Asm.get(), Table, CompUnits,
      [&UniqueIdToCuMap](const DWARF5AccelTableStaticData &Entry) {
        return UniqueIdToCuMap[Entry.getCUIndex()];
      });
}

void DwarfStreamer::emitAppleNamespaces(
    AccelTable<AppleAccelTableStaticOffsetData> &Table) {
  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());
  auto *SectionBegin = Asm->createTempSymbol("namespac_begin");
  Asm->OutStreamer->emitLabel(SectionBegin);
  emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);
}

void DwarfStreamer::emitAppleNames(
    AccelTable<AppleAccelTableStaticOffsetData> &Table) {
  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());
  auto *SectionBegin = Asm->createTempSymbol("names_begin");
  Asm->OutStreamer->emitLabel(SectionBegin);
  emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);
}

void DwarfStreamer::emitAppleObjc(
    AccelTable<AppleAccelTableStaticOffsetData> &Table) {
  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());
  auto *SectionBegin = Asm->createTempSymbol("objc_begin");
  Asm->OutStreamer->emitLabel(SectionBegin);
  emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);
}

void DwarfStreamer::emitAppleTypes(
    AccelTable<AppleAccelTableStaticTypeData> &Table) {
  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());
  auto *SectionBegin = Asm->createTempSymbol("types_begin");
  Asm->OutStreamer->emitLabel(SectionBegin);
  emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);
}

/// Emit the swift_ast section stored in \p Buffers.
void DwarfStreamer::emitSwiftAST(StringRef Buffer) {
  MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
  SwiftASTSection->setAlignment(Align(32));
  MS->switchSection(SwiftASTSection);
  MS->emitBytes(Buffer);
}

void DwarfStreamer::emitSwiftReflectionSection(
    llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
    StringRef Buffer, uint32_t Alignment, uint32_t Size) {
  MCSection *ReflectionSection =
      MOFI->getSwift5ReflectionSection(ReflSectionKind);
  if (ReflectionSection == nullptr)
    return;
  ReflectionSection->setAlignment(Align(Alignment));
  MS->switchSection(ReflectionSection);
  MS->emitBytes(Buffer);
}

void DwarfStreamer::emitDwarfDebugArangesTable(
    const CompileUnit &Unit, const AddressRanges &LinkedRanges) {
  unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();

  // Make .debug_aranges to be current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfARangesSection());

  // Emit Header.
  MCSymbol *BeginLabel = Asm->createTempSymbol("Barange");
  MCSymbol *EndLabel = Asm->createTempSymbol("Earange");

  unsigned HeaderSize =
      sizeof(int32_t) + // Size of contents (w/o this field
      sizeof(int16_t) + // DWARF ARange version number
      sizeof(int32_t) + // Offset of CU in the .debug_info section
      sizeof(int8_t) +  // Pointer Size (in bytes)
      sizeof(int8_t);   // Segment Size (in bytes)

  unsigned TupleSize = AddressSize * 2;
  unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));

  Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
  Asm->OutStreamer->emitLabel(BeginLabel);
  Asm->emitInt16(dwarf::DW_ARANGES_VERSION); // Version number
  Asm->emitInt32(Unit.getStartOffset());     // Corresponding unit's offset
  Asm->emitInt8(AddressSize);                // Address size
  Asm->emitInt8(0);                          // Segment size

  Asm->OutStreamer->emitFill(Padding, 0x0);

  // Emit linked ranges.
  for (const AddressRange &Range : LinkedRanges) {
    MS->emitIntValue(Range.start(), AddressSize);
    MS->emitIntValue(Range.end() - Range.start(), AddressSize);
  }

  // Emit terminator.
  Asm->OutStreamer->emitIntValue(0, AddressSize);
  Asm->OutStreamer->emitIntValue(0, AddressSize);
  Asm->OutStreamer->emitLabel(EndLabel);
}

void DwarfStreamer::emitDwarfDebugRangesTableFragment(
    const CompileUnit &Unit, const AddressRanges &LinkedRanges,
    PatchLocation Patch) {
  Patch.set(RangesSectionSize);

  // Make .debug_ranges to be current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
  unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();

  // Emit ranges.
  uint64_t BaseAddress = 0;
  if (std::optional<uint64_t> LowPC = Unit.getLowPc())
    BaseAddress = *LowPC;

  for (const AddressRange &Range : LinkedRanges) {
    MS->emitIntValue(Range.start() - BaseAddress, AddressSize);
    MS->emitIntValue(Range.end() - BaseAddress, AddressSize);

    RangesSectionSize += AddressSize;
    RangesSectionSize += AddressSize;
  }

  // Add the terminator entry.
  MS->emitIntValue(0, AddressSize);
  MS->emitIntValue(0, AddressSize);

  RangesSectionSize += AddressSize;
  RangesSectionSize += AddressSize;
}

MCSymbol *
DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit &Unit) {
  if (Unit.getOrigUnit().getVersion() < 5)
    return nullptr;

  // Make .debug_rnglists to be current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());

  MCSymbol *BeginLabel = Asm->createTempSymbol("Brnglists");
  MCSymbol *EndLabel = Asm->createTempSymbol("Ernglists");
  unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();

  // Length
  Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
  Asm->OutStreamer->emitLabel(BeginLabel);
  RngListsSectionSize += sizeof(uint32_t);

  // Version.
  MS->emitInt16(5);
  RngListsSectionSize += sizeof(uint16_t);

  // Address size.
  MS->emitInt8(AddressSize);
  RngListsSectionSize++;

  // Seg_size
  MS->emitInt8(0);
  RngListsSectionSize++;

  // Offset entry count
  MS->emitInt32(0);
  RngListsSectionSize += sizeof(uint32_t);

  return EndLabel;
}

void DwarfStreamer::emitDwarfDebugRangeListFragment(
    const CompileUnit &Unit, const AddressRanges &LinkedRanges,
    PatchLocation Patch, DebugDieValuePool &AddrPool) {
  if (Unit.getOrigUnit().getVersion() < 5) {
    emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch);
    return;
  }

  emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool);
}

void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
                                                  MCSymbol *EndLabel) {
  if (Unit.getOrigUnit().getVersion() < 5)
    return;

  // Make .debug_rnglists to be current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());

  if (EndLabel != nullptr)
    Asm->OutStreamer->emitLabel(EndLabel);
}

void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
    const CompileUnit &Unit, const AddressRanges &LinkedRanges,
    PatchLocation Patch, DebugDieValuePool &AddrPool) {
  Patch.set(RngListsSectionSize);

  // Make .debug_rnglists to be current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
  std::optional<uint64_t> BaseAddress;

  for (const AddressRange &Range : LinkedRanges) {

    if (!BaseAddress) {
      BaseAddress = Range.start();

      // Emit base address.
      MS->emitInt8(dwarf::DW_RLE_base_addressx);
      RngListsSectionSize += 1;
      RngListsSectionSize +=
          MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress));
    }

    // Emit type of entry.
    MS->emitInt8(dwarf::DW_RLE_offset_pair);
    RngListsSectionSize += 1;

    // Emit start offset relative to base address.
    RngListsSectionSize +=
        MS->emitULEB128IntValue(Range.start() - *BaseAddress);

    // Emit end offset relative to base address.
    RngListsSectionSize += MS->emitULEB128IntValue(Range.end() - *BaseAddress);
  }

  // Emit the terminator entry.
  MS->emitInt8(dwarf::DW_RLE_end_of_list);
  RngListsSectionSize += 1;
}

/// Emit debug locations(.debug_loc, .debug_loclists) header.
MCSymbol *DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit &Unit) {
  if (Unit.getOrigUnit().getVersion() < 5)
    return nullptr;

  // Make .debug_loclists the current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());

  MCSymbol *BeginLabel = Asm->createTempSymbol("Bloclists");
  MCSymbol *EndLabel = Asm->createTempSymbol("Eloclists");
  unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();

  // Length
  Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
  Asm->OutStreamer->emitLabel(BeginLabel);
  LocListsSectionSize += sizeof(uint32_t);

  // Version.
  MS->emitInt16(5);
  LocListsSectionSize += sizeof(uint16_t);

  // Address size.
  MS->emitInt8(AddressSize);
  LocListsSectionSize++;

  // Seg_size
  MS->emitInt8(0);
  LocListsSectionSize++;

  // Offset entry count
  MS->emitInt32(0);
  LocListsSectionSize += sizeof(uint32_t);

  return EndLabel;
}

/// Emit debug locations(.debug_loc, .debug_loclists) fragment.
void DwarfStreamer::emitDwarfDebugLocListFragment(
    const CompileUnit &Unit,
    const DWARFLocationExpressionsVector &LinkedLocationExpression,
    PatchLocation Patch, DebugDieValuePool &AddrPool) {
  if (Unit.getOrigUnit().getVersion() < 5) {
    emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch);
    return;
  }

  emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch,
                                      AddrPool);
}

/// Emit debug locations(.debug_loc, .debug_loclists) footer.
void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit &Unit,
                                                MCSymbol *EndLabel) {
  if (Unit.getOrigUnit().getVersion() < 5)
    return;

  // Make .debug_loclists the current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());

  if (EndLabel != nullptr)
    Asm->OutStreamer->emitLabel(EndLabel);
}

/// Emit piece of .debug_loc for \p LinkedLocationExpression.
void DwarfStreamer::emitDwarfDebugLocTableFragment(
    const CompileUnit &Unit,
    const DWARFLocationExpressionsVector &LinkedLocationExpression,
    PatchLocation Patch) {
  Patch.set(LocSectionSize);

  // Make .debug_loc to be current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection());
  unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();

  // Emit ranges.
  uint64_t BaseAddress = 0;
  if (std::optional<uint64_t> LowPC = Unit.getLowPc())
    BaseAddress = *LowPC;

  for (const DWARFLocationExpression &LocExpression :
       LinkedLocationExpression) {
    if (LocExpression.Range) {
      MS->emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize);
      MS->emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize);

      LocSectionSize += AddressSize;
      LocSectionSize += AddressSize;
    }

    Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2);
    Asm->OutStreamer->emitBytes(StringRef(
        (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
    LocSectionSize += LocExpression.Expr.size() + 2;
  }

  // Add the terminator entry.
  MS->emitIntValue(0, AddressSize);
  MS->emitIntValue(0, AddressSize);

  LocSectionSize += AddressSize;
  LocSectionSize += AddressSize;
}

/// Emit .debug_addr header.
MCSymbol *DwarfStreamer::emitDwarfDebugAddrsHeader(const CompileUnit &Unit) {

  // Make .debug_addr the current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());

  MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugaddr");
  MCSymbol *EndLabel = Asm->createTempSymbol("Edebugaddr");
  unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize();

  // Emit length.
  Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
  Asm->OutStreamer->emitLabel(BeginLabel);
  AddrSectionSize += sizeof(uint32_t);

  // Emit version.
  Asm->emitInt16(5);
  AddrSectionSize += 2;

  // Emit address size.
  Asm->emitInt8(AddrSize);
  AddrSectionSize += 1;

  // Emit segment size.
  Asm->emitInt8(0);
  AddrSectionSize += 1;

  return EndLabel;
}

/// Emit the .debug_addr addresses stored in \p Addrs.
void DwarfStreamer::emitDwarfDebugAddrs(const SmallVector<uint64_t> &Addrs,
                                        uint8_t AddrSize) {
  Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection());
  for (auto Addr : Addrs) {
    Asm->OutStreamer->emitIntValue(Addr, AddrSize);
    AddrSectionSize += AddrSize;
  }
}

/// Emit .debug_addr footer.
void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit &Unit,
                                              MCSymbol *EndLabel) {

  // Make .debug_addr the current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection());

  if (EndLabel != nullptr)
    Asm->OutStreamer->emitLabel(EndLabel);
}

/// Emit piece of .debug_loclists for \p LinkedLocationExpression.
void DwarfStreamer::emitDwarfDebugLocListsTableFragment(
    const CompileUnit &Unit,
    const DWARFLocationExpressionsVector &LinkedLocationExpression,
    PatchLocation Patch, DebugDieValuePool &AddrPool) {
  Patch.set(LocListsSectionSize);

  // Make .debug_loclists the current section.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection());
  std::optional<uint64_t> BaseAddress;

  for (const DWARFLocationExpression &LocExpression :
       LinkedLocationExpression) {
    if (LocExpression.Range) {

      if (!BaseAddress) {

        BaseAddress = LocExpression.Range->LowPC;

        // Emit base address.
        MS->emitInt8(dwarf::DW_LLE_base_addressx);
        LocListsSectionSize += 1;
        LocListsSectionSize +=
            MS->emitULEB128IntValue(AddrPool.getValueIndex(*BaseAddress));
      }

      // Emit type of entry.
      MS->emitInt8(dwarf::DW_LLE_offset_pair);
      LocListsSectionSize += 1;

      // Emit start offset relative to base address.
      LocListsSectionSize +=
          MS->emitULEB128IntValue(LocExpression.Range->LowPC - *BaseAddress);

      // Emit end offset relative to base address.
      LocListsSectionSize +=
          MS->emitULEB128IntValue(LocExpression.Range->HighPC - *BaseAddress);
    } else {
      // Emit type of entry.
      MS->emitInt8(dwarf::DW_LLE_default_location);
      LocListsSectionSize += 1;
    }

    LocListsSectionSize += MS->emitULEB128IntValue(LocExpression.Expr.size());
    Asm->OutStreamer->emitBytes(StringRef(
        (const char *)LocExpression.Expr.data(), LocExpression.Expr.size()));
    LocListsSectionSize += LocExpression.Expr.size();
  }

  // Emit the terminator entry.
  MS->emitInt8(dwarf::DW_LLE_end_of_list);
  LocListsSectionSize += 1;
}

void DwarfStreamer::emitLineTableForUnit(
    const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit,
    OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool) {
  // Switch to the section where the table will be emitted into.
  MS->switchSection(MC->getObjectFileInfo()->getDwarfLineSection());

  MCSymbol *LineStartSym = MC->createTempSymbol();
  MCSymbol *LineEndSym = MC->createTempSymbol();

  // unit_length.
  if (LineTable.Prologue.FormParams.Format == dwarf::DwarfFormat::DWARF64) {
    MS->emitInt32(dwarf::DW_LENGTH_DWARF64);
    LineSectionSize += 4;
  }
  emitLabelDifference(LineEndSym, LineStartSym,
                      LineTable.Prologue.FormParams.Format, LineSectionSize);
  Asm->OutStreamer->emitLabel(LineStartSym);

  // Emit prologue.
  emitLineTablePrologue(LineTable.Prologue, DebugStrPool, DebugLineStrPool);

  // Emit rows.
  emitLineTableRows(LineTable, LineEndSym,
                    Unit.getOrigUnit().getAddressByteSize());
}

void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
                                          OffsetsStringPool &DebugStrPool,
                                          OffsetsStringPool &DebugLineStrPool) {
  MCSymbol *PrologueStartSym = MC->createTempSymbol();
  MCSymbol *PrologueEndSym = MC->createTempSymbol();

  // version (uhalf).
  MS->emitInt16(P.getVersion());
  LineSectionSize += 2;
  if (P.getVersion() == 5) {
    // address_size (ubyte).
    MS->emitInt8(P.getAddressSize());
    LineSectionSize += 1;

    // segment_selector_size (ubyte).
    MS->emitInt8(P.SegSelectorSize);
    LineSectionSize += 1;
  }

  // header_length.
  emitLabelDifference(PrologueEndSym, PrologueStartSym, P.FormParams.Format,
                      LineSectionSize);

  Asm->OutStreamer->emitLabel(PrologueStartSym);
  emitLineTableProloguePayload(P, DebugStrPool, DebugLineStrPool);
  Asm->OutStreamer->emitLabel(PrologueEndSym);
}

void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable(
    const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
    OffsetsStringPool &DebugLineStrPool) {
  // include_directories (sequence of path names).
  for (const DWARFFormValue &Include : P.IncludeDirectories)
    emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);
  // The last entry is followed by a single null byte.
  MS->emitInt8(0);
  LineSectionSize += 1;

  // file_names (sequence of file entries).
  for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) {
    // A null-terminated string containing the full or relative path name of a
    // source file.
    emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
    // An unsigned LEB128 number representing the directory index of a directory
    // in the include_directories section.
    LineSectionSize += MS->emitULEB128IntValue(File.DirIdx);
    // An unsigned LEB128 number representing the (implementation-defined) time
    // of last modification for the file, or 0 if not available.
    LineSectionSize += MS->emitULEB128IntValue(File.ModTime);
    // An unsigned LEB128 number representing the length in bytes of the file,
    // or 0 if not available.
    LineSectionSize += MS->emitULEB128IntValue(File.Length);
  }
  // The last entry is followed by a single null byte.
  MS->emitInt8(0);
  LineSectionSize += 1;
}

void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
    const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
    OffsetsStringPool &DebugLineStrPool) {
  if (P.IncludeDirectories.empty()) {
    // directory_entry_format_count(ubyte).
    MS->emitInt8(0);
    LineSectionSize += 1;
  } else {
    // directory_entry_format_count(ubyte).
    MS->emitInt8(1);
    LineSectionSize += 1;

    // directory_entry_format (sequence of ULEB128 pairs).
    LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
    LineSectionSize +=
        MS->emitULEB128IntValue(P.IncludeDirectories[0].getForm());
  }

  // directories_count (ULEB128).
  LineSectionSize += MS->emitULEB128IntValue(P.IncludeDirectories.size());
  // directories (sequence of directory names).
  for (auto Include : P.IncludeDirectories)
    emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);

  if (P.FileNames.empty()) {
    // file_name_entry_format_count (ubyte).
    MS->emitInt8(0);
    LineSectionSize += 1;
  } else {
    // file_name_entry_format_count (ubyte).
    MS->emitInt8(2);
    LineSectionSize += 1;

    // file_name_entry_format (sequence of ULEB128 pairs).
    LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path);
    LineSectionSize += MS->emitULEB128IntValue(P.FileNames[0].Name.getForm());

    LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
    LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1);
  }

  // file_names_count (ULEB128).
  LineSectionSize += MS->emitULEB128IntValue(P.FileNames.size());

  // file_names (sequence of file name entries).
  for (auto File : P.FileNames) {
    emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
    MS->emitInt8(File.DirIdx);
    LineSectionSize += 1;
  }
}

void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P,
                                        const DWARFFormValue &String,
                                        OffsetsStringPool &DebugStrPool,
                                        OffsetsStringPool &DebugLineStrPool) {
  std::optional<const char *> StringVal = dwarf::toString(String);
  if (!StringVal) {
    warn("Cann't read string from line table.");
    return;
  }

  switch (String.getForm()) {
  case dwarf::DW_FORM_string: {
    StringRef TranslatedString =
        (Translator) ? Translator(*StringVal) : *StringVal;
    Asm->OutStreamer->emitBytes(TranslatedString.data());
    Asm->emitInt8(0);
    LineSectionSize += TranslatedString.size() + 1;
  } break;
  case dwarf::DW_FORM_strp:
  case dwarf::DW_FORM_line_strp: {
    DwarfStringPoolEntryRef StringRef =
        String.getForm() == dwarf::DW_FORM_strp
            ? DebugStrPool.getEntry(*StringVal)
            : DebugLineStrPool.getEntry(*StringVal);

    emitIntOffset(StringRef.getOffset(), P.FormParams.Format, LineSectionSize);
  } break;
  default:
    warn("Unsupported string form inside line table.");
    break;
  };
}

void DwarfStreamer::emitLineTableProloguePayload(
    const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool,
    OffsetsStringPool &DebugLineStrPool) {
  // minimum_instruction_length (ubyte).
  MS->emitInt8(P.MinInstLength);
  LineSectionSize += 1;
  if (P.FormParams.Version >= 4) {
    // maximum_operations_per_instruction (ubyte).
    MS->emitInt8(P.MaxOpsPerInst);
    LineSectionSize += 1;
  }
  // default_is_stmt (ubyte).
  MS->emitInt8(P.DefaultIsStmt);
  LineSectionSize += 1;
  // line_base (sbyte).
  MS->emitInt8(P.LineBase);
  LineSectionSize += 1;
  // line_range (ubyte).
  MS->emitInt8(P.LineRange);
  LineSectionSize += 1;
  // opcode_base (ubyte).
  MS->emitInt8(P.OpcodeBase);
  LineSectionSize += 1;

  // standard_opcode_lengths (array of ubyte).
  for (auto Length : P.StandardOpcodeLengths) {
    MS->emitInt8(Length);
    LineSectionSize += 1;
  }

  if (P.FormParams.Version < 5)
    emitLineTablePrologueV2IncludeAndFileTable(P, DebugStrPool,
                                               DebugLineStrPool);
  else
    emitLineTablePrologueV5IncludeAndFileTable(P, DebugStrPool,
                                               DebugLineStrPool);
}

void DwarfStreamer::emitLineTableRows(
    const DWARFDebugLine::LineTable &LineTable, MCSymbol *LineEndSym,
    unsigned AddressByteSize) {

  MCDwarfLineTableParams Params;
  Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
  Params.DWARF2LineBase = LineTable.Prologue.LineBase;
  Params.DWARF2LineRange = LineTable.Prologue.LineRange;

  SmallString<128> EncodingBuffer;

  if (LineTable.Rows.empty()) {
    // We only have the dummy entry, dsymutil emits an entry with a 0
    // address in that case.
    MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
                            EncodingBuffer);
    MS->emitBytes(EncodingBuffer);
    LineSectionSize += EncodingBuffer.size();
    MS->emitLabel(LineEndSym);
    return;
  }

  // Line table state machine fields
  unsigned FileNum = 1;
  unsigned LastLine = 1;
  unsigned Column = 0;
  unsigned IsStatement = 1;
  unsigned Isa = 0;
  uint64_t Address = -1ULL;

  unsigned RowsSinceLastSequence = 0;

  for (const DWARFDebugLine::Row &Row : LineTable.Rows) {
    int64_t AddressDelta;
    if (Address == -1ULL) {
      MS->emitIntValue(dwarf::DW_LNS_extended_op, 1);
      MS->emitULEB128IntValue(AddressByteSize + 1);
      MS->emitIntValue(dwarf::DW_LNE_set_address, 1);
      MS->emitIntValue(Row.Address.Address, AddressByteSize);
      LineSectionSize +=
          2 + AddressByteSize + getULEB128Size(AddressByteSize + 1);
      AddressDelta = 0;
    } else {
      AddressDelta =
          (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength;
    }

    // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable.
    // We should find a way to share this code, but the current compatibility
    // requirement with classic dsymutil makes it hard. Revisit that once this
    // requirement is dropped.

    if (FileNum != Row.File) {
      FileNum = Row.File;
      MS->emitIntValue(dwarf::DW_LNS_set_file, 1);
      MS->emitULEB128IntValue(FileNum);
      LineSectionSize += 1 + getULEB128Size(FileNum);
    }
    if (Column != Row.Column) {
      Column = Row.Column;
      MS->emitIntValue(dwarf::DW_LNS_set_column, 1);
      MS->emitULEB128IntValue(Column);
      LineSectionSize += 1 + getULEB128Size(Column);
    }

    // FIXME: We should handle the discriminator here, but dsymutil doesn't
    // consider it, thus ignore it for now.

    if (Isa != Row.Isa) {
      Isa = Row.Isa;
      MS->emitIntValue(dwarf::DW_LNS_set_isa, 1);
      MS->emitULEB128IntValue(Isa);
      LineSectionSize += 1 + getULEB128Size(Isa);
    }
    if (IsStatement != Row.IsStmt) {
      IsStatement = Row.IsStmt;
      MS->emitIntValue(dwarf::DW_LNS_negate_stmt, 1);
      LineSectionSize += 1;
    }
    if (Row.BasicBlock) {
      MS->emitIntValue(dwarf::DW_LNS_set_basic_block, 1);
      LineSectionSize += 1;
    }

    if (Row.PrologueEnd) {
      MS->emitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
      LineSectionSize += 1;
    }

    if (Row.EpilogueBegin) {
      MS->emitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
      LineSectionSize += 1;
    }

    int64_t LineDelta = int64_t(Row.Line) - LastLine;
    if (!Row.EndSequence) {
      MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta,
                              EncodingBuffer);
      MS->emitBytes(EncodingBuffer);
      LineSectionSize += EncodingBuffer.size();
      EncodingBuffer.resize(0);
      Address = Row.Address.Address;
      LastLine = Row.Line;
      RowsSinceLastSequence++;
    } else {
      if (LineDelta) {
        MS->emitIntValue(dwarf::DW_LNS_advance_line, 1);
        MS->emitSLEB128IntValue(LineDelta);
        LineSectionSize += 1 + getSLEB128Size(LineDelta);
      }
      if (AddressDelta) {
        MS->emitIntValue(dwarf::DW_LNS_advance_pc, 1);
        MS->emitULEB128IntValue(AddressDelta);
        LineSectionSize += 1 + getULEB128Size(AddressDelta);
      }
      MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(),
                              0, EncodingBuffer);
      MS->emitBytes(EncodingBuffer);
      LineSectionSize += EncodingBuffer.size();
      EncodingBuffer.resize(0);
      Address = -1ULL;
      LastLine = FileNum = IsStatement = 1;
      RowsSinceLastSequence = Column = Isa = 0;
    }
  }

  if (RowsSinceLastSequence) {
    MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
                            EncodingBuffer);
    MS->emitBytes(EncodingBuffer);
    LineSectionSize += EncodingBuffer.size();
    EncodingBuffer.resize(0);
  }

  MS->emitLabel(LineEndSym);
}

void DwarfStreamer::emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format,
                                  uint64_t &SectionSize) {
  uint8_t Size = dwarf::getDwarfOffsetByteSize(Format);
  MS->emitIntValue(Offset, Size);
  SectionSize += Size;
}

void DwarfStreamer::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
                                        dwarf::DwarfFormat Format,
                                        uint64_t &SectionSize) {
  uint8_t Size = dwarf::getDwarfOffsetByteSize(Format);
  Asm->emitLabelDifference(Hi, Lo, Size);
  SectionSize += Size;
}

/// Emit the pubnames or pubtypes section contribution for \p
/// Unit into \p Sec. The data is provided in \p Names.
void DwarfStreamer::emitPubSectionForUnit(
    MCSection *Sec, StringRef SecName, const CompileUnit &Unit,
    const std::vector<CompileUnit::AccelInfo> &Names) {
  if (Names.empty())
    return;

  // Start the dwarf pubnames section.
  Asm->OutStreamer->switchSection(Sec);
  MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin");
  MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end");

  bool HeaderEmitted = false;
  // Emit the pubnames for this compilation unit.
  for (const auto &Name : Names) {
    if (Name.SkipPubSection)
      continue;

    if (!HeaderEmitted) {
      // Emit the header.
      Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Length
      Asm->OutStreamer->emitLabel(BeginLabel);
      Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION); // Version
      Asm->emitInt32(Unit.getStartOffset());      // Unit offset
      Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size
      HeaderEmitted = true;
    }
    Asm->emitInt32(Name.Die->getOffset());

    // Emit the string itself.
    Asm->OutStreamer->emitBytes(Name.Name.getString());
    // Emit a null terminator.
    Asm->emitInt8(0);
  }

  if (!HeaderEmitted)
    return;
  Asm->emitInt32(0); // End marker.
  Asm->OutStreamer->emitLabel(EndLabel);
}

/// Emit .debug_pubnames for \p Unit.
void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) {
  emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(),
                        "names", Unit, Unit.getPubnames());
}

/// Emit .debug_pubtypes for \p Unit.
void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) {
  emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(),
                        "types", Unit, Unit.getPubtypes());
}

/// Emit a CIE into the debug_frame section.
void DwarfStreamer::emitCIE(StringRef CIEBytes) {
  MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());

  MS->emitBytes(CIEBytes);
  FrameSectionSize += CIEBytes.size();
}

/// Emit a FDE into the debug_frame section. \p FDEBytes
/// contains the FDE data without the length, CIE offset and address
/// which will be replaced with the parameter values.
void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize,
                            uint64_t Address, StringRef FDEBytes) {
  MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection());

  MS->emitIntValue(FDEBytes.size() + 4 + AddrSize, 4);
  MS->emitIntValue(CIEOffset, 4);
  MS->emitIntValue(Address, AddrSize);
  MS->emitBytes(FDEBytes);
  FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
}

void DwarfStreamer::emitMacroTables(DWARFContext *Context,
                                    const Offset2UnitMap &UnitMacroMap,
                                    OffsetsStringPool &StringPool) {
  assert(Context != nullptr && "Empty DWARF context");

  // Check for .debug_macinfo table.
  if (const DWARFDebugMacro *Table = Context->getDebugMacinfo()) {
    MS->switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection());
    emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacInfoSectionSize);
  }

  // Check for .debug_macro table.
  if (const DWARFDebugMacro *Table = Context->getDebugMacro()) {
    MS->switchSection(MC->getObjectFileInfo()->getDwarfMacroSection());
    emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacroSectionSize);
  }
}

void DwarfStreamer::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
                                       const Offset2UnitMap &UnitMacroMap,
                                       OffsetsStringPool &StringPool,
                                       uint64_t &OutOffset) {
  bool DefAttributeIsReported = false;
  bool UndefAttributeIsReported = false;
  bool ImportAttributeIsReported = false;
  for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
    Offset2UnitMap::const_iterator UnitIt = UnitMacroMap.find(List.Offset);
    if (UnitIt == UnitMacroMap.end()) {
      warn(formatv(
          "couldn`t find compile unit for the macro table with offset = {0:x}",
          List.Offset));
      continue;
    }

    // Skip macro table if the unit was not cloned.
    DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE();
    if (OutputUnitDIE == nullptr)
      continue;

    // Update macro attribute of cloned compile unit with the proper offset to
    // the macro table.
    bool hasDWARFv5Header = false;
    for (auto &V : OutputUnitDIE->values()) {
      if (V.getAttribute() == dwarf::DW_AT_macro_info) {
        V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset));
        break;
      } else if (V.getAttribute() == dwarf::DW_AT_macros) {
        hasDWARFv5Header = true;
        V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset));
        break;
      }
    }

    // Write DWARFv5 header.
    if (hasDWARFv5Header) {
      // Write header version.
      MS->emitIntValue(List.Header.Version, sizeof(List.Header.Version));
      OutOffset += sizeof(List.Header.Version);

      uint8_t Flags = List.Header.Flags;

      // Check for OPCODE_OPERANDS_TABLE.
      if (Flags &
          DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
        Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
        warn("opcode_operands_table is not supported yet.");
      }

      // Check for DEBUG_LINE_OFFSET.
      std::optional<uint64_t> StmtListOffset;
      if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
        // Get offset to the line table from the cloned compile unit.
        for (auto &V : OutputUnitDIE->values()) {
          if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
            StmtListOffset = V.getDIEInteger().getValue();
            break;
          }
        }

        if (!StmtListOffset) {
          Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
          warn("couldn`t find line table for macro table.");
        }
      }

      // Write flags.
      MS->emitIntValue(Flags, sizeof(Flags));
      OutOffset += sizeof(Flags);

      // Write offset to line table.
      if (StmtListOffset) {
        MS->emitIntValue(*StmtListOffset, List.Header.getOffsetByteSize());
        OutOffset += List.Header.getOffsetByteSize();
      }
    }

    // Write macro entries.
    for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
      if (MacroEntry.Type == 0) {
        OutOffset += MS->emitULEB128IntValue(MacroEntry.Type);
        continue;
      }

      uint8_t MacroType = MacroEntry.Type;
      switch (MacroType) {
      default: {
        bool HasVendorSpecificExtension =
            (!hasDWARFv5Header && MacroType == dwarf::DW_MACINFO_vendor_ext) ||
            (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
                                  MacroType <= dwarf::DW_MACRO_hi_user));

        if (HasVendorSpecificExtension) {
          // Write macinfo type.
          MS->emitIntValue(MacroType, 1);
          OutOffset++;

          // Write vendor extension constant.
          OutOffset += MS->emitULEB128IntValue(MacroEntry.ExtConstant);

          // Write vendor extension string.
          StringRef String = MacroEntry.ExtStr;
          MS->emitBytes(String);
          MS->emitIntValue(0, 1);
          OutOffset += String.size() + 1;
        } else
          warn("unknown macro type. skip.");
      } break;
      // debug_macro and debug_macinfo share some common encodings.
      // DW_MACRO_define     == DW_MACINFO_define
      // DW_MACRO_undef      == DW_MACINFO_undef
      // DW_MACRO_start_file == DW_MACINFO_start_file
      // DW_MACRO_end_file   == DW_MACINFO_end_file
      // For readibility/uniformity we are using DW_MACRO_*.
      case dwarf::DW_MACRO_define:
      case dwarf::DW_MACRO_undef: {
        // Write macinfo type.
        MS->emitIntValue(MacroType, 1);
        OutOffset++;

        // Write source line.
        OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);

        // Write macro string.
        StringRef String = MacroEntry.MacroStr;
        MS->emitBytes(String);
        MS->emitIntValue(0, 1);
        OutOffset += String.size() + 1;
      } break;
      case dwarf::DW_MACRO_define_strp:
      case dwarf::DW_MACRO_undef_strp:
      case dwarf::DW_MACRO_define_strx:
      case dwarf::DW_MACRO_undef_strx: {
        assert(UnitIt->second->getOrigUnit().getVersion() >= 5);

        // DW_MACRO_*_strx forms are not supported currently.
        // Convert to *_strp.
        switch (MacroType) {
        case dwarf::DW_MACRO_define_strx: {
          MacroType = dwarf::DW_MACRO_define_strp;
          if (!DefAttributeIsReported) {
            warn("DW_MACRO_define_strx unsupported yet. Convert to "
                 "DW_MACRO_define_strp.");
            DefAttributeIsReported = true;
          }
        } break;
        case dwarf::DW_MACRO_undef_strx: {
          MacroType = dwarf::DW_MACRO_undef_strp;
          if (!UndefAttributeIsReported) {
            warn("DW_MACRO_undef_strx unsupported yet. Convert to "
                 "DW_MACRO_undef_strp.");
            UndefAttributeIsReported = true;
          }
        } break;
        default:
          // Nothing to do.
          break;
        }

        // Write macinfo type.
        MS->emitIntValue(MacroType, 1);
        OutOffset++;

        // Write source line.
        OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);

        // Write macro string.
        DwarfStringPoolEntryRef EntryRef =
            StringPool.getEntry(MacroEntry.MacroStr);
        MS->emitIntValue(EntryRef.getOffset(), List.Header.getOffsetByteSize());
        OutOffset += List.Header.getOffsetByteSize();
        break;
      }
      case dwarf::DW_MACRO_start_file: {
        // Write macinfo type.
        MS->emitIntValue(MacroType, 1);
        OutOffset++;
        // Write source line.
        OutOffset += MS->emitULEB128IntValue(MacroEntry.Line);
        // Write source file id.
        OutOffset += MS->emitULEB128IntValue(MacroEntry.File);
      } break;
      case dwarf::DW_MACRO_end_file: {
        // Write macinfo type.
        MS->emitIntValue(MacroType, 1);
        OutOffset++;
      } break;
      case dwarf::DW_MACRO_import:
      case dwarf::DW_MACRO_import_sup: {
        if (!ImportAttributeIsReported) {
          warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. "
               "remove.");
          ImportAttributeIsReported = true;
        }
      } break;
      }
    }
  }
}

} // namespace llvm
