//===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// The DWARF component of yaml2obj. Provided as library code for tests.
///
//===----------------------------------------------------------------------===//

#include "llvm/ObjectYAML/DWARFEmitter.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/ObjectYAML/DWARFYAML.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>

using namespace llvm;

template <typename T>
static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) {
  if (IsLittleEndian != sys::IsLittleEndianHost)
    sys::swapByteOrder(Integer);
  OS.write(reinterpret_cast<char *>(&Integer), sizeof(T));
}

static Error writeVariableSizedInteger(uint64_t Integer, size_t Size,
                                       raw_ostream &OS, bool IsLittleEndian) {
  if (8 == Size)
    writeInteger((uint64_t)Integer, OS, IsLittleEndian);
  else if (4 == Size)
    writeInteger((uint32_t)Integer, OS, IsLittleEndian);
  else if (2 == Size)
    writeInteger((uint16_t)Integer, OS, IsLittleEndian);
  else if (1 == Size)
    writeInteger((uint8_t)Integer, OS, IsLittleEndian);
  else
    return createStringError(errc::not_supported,
                             "invalid integer write size: %zu", Size);

  return Error::success();
}

static void ZeroFillBytes(raw_ostream &OS, size_t Size) {
  std::vector<uint8_t> FillData(Size, 0);
  OS.write(reinterpret_cast<char *>(FillData.data()), Size);
}

static void writeInitialLength(const dwarf::DwarfFormat Format,
                               const uint64_t Length, raw_ostream &OS,
                               bool IsLittleEndian) {
  bool IsDWARF64 = Format == dwarf::DWARF64;
  if (IsDWARF64)
    cantFail(writeVariableSizedInteger(dwarf::DW_LENGTH_DWARF64, 4, OS,
                                       IsLittleEndian));
  cantFail(
      writeVariableSizedInteger(Length, IsDWARF64 ? 8 : 4, OS, IsLittleEndian));
}

static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format,
                             raw_ostream &OS, bool IsLittleEndian) {
  cantFail(writeVariableSizedInteger(Offset, Format == dwarf::DWARF64 ? 8 : 4,
                                     OS, IsLittleEndian));
}

Error DWARFYAML::emitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) {
  for (StringRef Str : *DI.DebugStrings) {
    OS.write(Str.data(), Str.size());
    OS.write('\0');
  }

  return Error::success();
}

StringRef DWARFYAML::Data::getAbbrevTableContentByIndex(uint64_t Index) const {
  assert(Index < DebugAbbrev.size() &&
         "Index should be less than the size of DebugAbbrev array");
  auto It = AbbrevTableContents.find(Index);
  if (It != AbbrevTableContents.cend())
    return It->second;

  std::string AbbrevTableBuffer;
  raw_string_ostream OS(AbbrevTableBuffer);

  uint64_t AbbrevCode = 0;
  for (const DWARFYAML::Abbrev &AbbrevDecl : DebugAbbrev[Index].Table) {
    AbbrevCode = AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1;
    encodeULEB128(AbbrevCode, OS);
    encodeULEB128(AbbrevDecl.Tag, OS);
    OS.write(AbbrevDecl.Children);
    for (const auto &Attr : AbbrevDecl.Attributes) {
      encodeULEB128(Attr.Attribute, OS);
      encodeULEB128(Attr.Form, OS);
      if (Attr.Form == dwarf::DW_FORM_implicit_const)
        encodeSLEB128(Attr.Value, OS);
    }
    encodeULEB128(0, OS);
    encodeULEB128(0, OS);
  }

  // The abbreviations for a given compilation unit end with an entry
  // consisting of a 0 byte for the abbreviation code.
  OS.write_zeros(1);

  AbbrevTableContents.insert({Index, AbbrevTableBuffer});

  return AbbrevTableContents[Index];
}

Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
  for (uint64_t I = 0; I < DI.DebugAbbrev.size(); ++I) {
    StringRef AbbrevTableContent = DI.getAbbrevTableContentByIndex(I);
    OS.write(AbbrevTableContent.data(), AbbrevTableContent.size());
  }

  return Error::success();
}

Error DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
  assert(DI.DebugAranges && "unexpected emitDebugAranges() call");
  for (const auto &Range : *DI.DebugAranges) {
    uint8_t AddrSize;
    if (Range.AddrSize)
      AddrSize = *Range.AddrSize;
    else
      AddrSize = DI.Is64BitAddrSize ? 8 : 4;

    uint64_t Length = 4; // sizeof(version) 2 + sizeof(address_size) 1 +
                         // sizeof(segment_selector_size) 1
    Length +=
        Range.Format == dwarf::DWARF64 ? 8 : 4; // sizeof(debug_info_offset)

    const uint64_t HeaderLength =
        Length + (Range.Format == dwarf::DWARF64
                      ? 12
                      : 4); // sizeof(unit_header) = 12 (DWARF64) or 4 (DWARF32)
    const uint64_t PaddedHeaderLength = alignTo(HeaderLength, AddrSize * 2);

    if (Range.Length) {
      Length = *Range.Length;
    } else {
      Length += PaddedHeaderLength - HeaderLength;
      Length += AddrSize * 2 * (Range.Descriptors.size() + 1);
    }

    writeInitialLength(Range.Format, Length, OS, DI.IsLittleEndian);
    writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian);
    writeDWARFOffset(Range.CuOffset, Range.Format, OS, DI.IsLittleEndian);
    writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
    writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian);
    ZeroFillBytes(OS, PaddedHeaderLength - HeaderLength);

    for (const auto &Descriptor : Range.Descriptors) {
      if (Error Err = writeVariableSizedInteger(Descriptor.Address, AddrSize,
                                                OS, DI.IsLittleEndian))
        return createStringError(errc::not_supported,
                                 "unable to write debug_aranges address: %s",
                                 toString(std::move(Err)).c_str());
      cantFail(writeVariableSizedInteger(Descriptor.Length, AddrSize, OS,
                                         DI.IsLittleEndian));
    }
    ZeroFillBytes(OS, AddrSize * 2);
  }

  return Error::success();
}

Error DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
  const size_t RangesOffset = OS.tell();
  uint64_t EntryIndex = 0;
  for (const auto &DebugRanges : *DI.DebugRanges) {
    const size_t CurrOffset = OS.tell() - RangesOffset;
    if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset)
      return createStringError(errc::invalid_argument,
                               "'Offset' for 'debug_ranges' with index " +
                                   Twine(EntryIndex) +
                                   " must be greater than or equal to the "
                                   "number of bytes written already (0x" +
                                   Twine::utohexstr(CurrOffset) + ")");
    if (DebugRanges.Offset)
      ZeroFillBytes(OS, *DebugRanges.Offset - CurrOffset);

    uint8_t AddrSize;
    if (DebugRanges.AddrSize)
      AddrSize = *DebugRanges.AddrSize;
    else
      AddrSize = DI.Is64BitAddrSize ? 8 : 4;
    for (const auto &Entry : DebugRanges.Entries) {
      if (Error Err = writeVariableSizedInteger(Entry.LowOffset, AddrSize, OS,
                                                DI.IsLittleEndian))
        return createStringError(
            errc::not_supported,
            "unable to write debug_ranges address offset: %s",
            toString(std::move(Err)).c_str());
      cantFail(writeVariableSizedInteger(Entry.HighOffset, AddrSize, OS,
                                         DI.IsLittleEndian));
    }
    ZeroFillBytes(OS, AddrSize * 2);
    ++EntryIndex;
  }

  return Error::success();
}

static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect,
                            bool IsLittleEndian, bool IsGNUPubSec = false) {
  writeInitialLength(Sect.Format, Sect.Length, OS, IsLittleEndian);
  writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
  writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
  writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
  for (const auto &Entry : Sect.Entries) {
    writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
    if (IsGNUPubSec)
      writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian);
    OS.write(Entry.Name.data(), Entry.Name.size());
    OS.write('\0');
  }
  return Error::success();
}

Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, const Data &DI) {
  assert(DI.PubNames && "unexpected emitDebugPubnames() call");
  return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian);
}

Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, const Data &DI) {
  assert(DI.PubTypes && "unexpected emitDebugPubtypes() call");
  return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian);
}

Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, const Data &DI) {
  assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call");
  return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian,
                        /*IsGNUStyle=*/true);
}

Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI) {
  assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call");
  return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian,
                        /*IsGNUStyle=*/true);
}

static Expected<uint64_t> writeDIE(const DWARFYAML::Data &DI, uint64_t CUIndex,
                                   uint64_t AbbrevTableID,
                                   const dwarf::FormParams &Params,
                                   const DWARFYAML::Entry &Entry,
                                   raw_ostream &OS, bool IsLittleEndian) {
  uint64_t EntryBegin = OS.tell();
  encodeULEB128(Entry.AbbrCode, OS);
  uint32_t AbbrCode = Entry.AbbrCode;
  if (AbbrCode == 0 || Entry.Values.empty())
    return OS.tell() - EntryBegin;

  Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
      DI.getAbbrevTableInfoByID(AbbrevTableID);
  if (!AbbrevTableInfoOrErr)
    return createStringError(errc::invalid_argument,
                             toString(AbbrevTableInfoOrErr.takeError()) +
                                 " for compilation unit with index " +
                                 utostr(CUIndex));

  ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(
      DI.DebugAbbrev[AbbrevTableInfoOrErr->Index].Table);

  if (AbbrCode > AbbrevDecls.size())
    return createStringError(
        errc::invalid_argument,
        "abbrev code must be less than or equal to the number of "
        "entries in abbreviation table");
  const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1];
  auto FormVal = Entry.Values.begin();
  auto AbbrForm = Abbrev.Attributes.begin();
  for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
       ++FormVal, ++AbbrForm) {
    dwarf::Form Form = AbbrForm->Form;
    bool Indirect;
    do {
      Indirect = false;
      switch (Form) {
      case dwarf::DW_FORM_addr:
        // TODO: Test this error.
        if (Error Err = writeVariableSizedInteger(
                FormVal->Value, Params.AddrSize, OS, IsLittleEndian))
          return std::move(Err);
        break;
      case dwarf::DW_FORM_ref_addr:
        // TODO: Test this error.
        if (Error Err = writeVariableSizedInteger(FormVal->Value,
                                                  Params.getRefAddrByteSize(),
                                                  OS, IsLittleEndian))
          return std::move(Err);
        break;
      case dwarf::DW_FORM_exprloc:
      case dwarf::DW_FORM_block:
        encodeULEB128(FormVal->BlockData.size(), OS);
        OS.write((const char *)FormVal->BlockData.data(),
                 FormVal->BlockData.size());
        break;
      case dwarf::DW_FORM_block1: {
        writeInteger((uint8_t)FormVal->BlockData.size(), OS, IsLittleEndian);
        OS.write((const char *)FormVal->BlockData.data(),
                 FormVal->BlockData.size());
        break;
      }
      case dwarf::DW_FORM_block2: {
        writeInteger((uint16_t)FormVal->BlockData.size(), OS, IsLittleEndian);
        OS.write((const char *)FormVal->BlockData.data(),
                 FormVal->BlockData.size());
        break;
      }
      case dwarf::DW_FORM_block4: {
        writeInteger((uint32_t)FormVal->BlockData.size(), OS, IsLittleEndian);
        OS.write((const char *)FormVal->BlockData.data(),
                 FormVal->BlockData.size());
        break;
      }
      case dwarf::DW_FORM_strx:
      case dwarf::DW_FORM_addrx:
      case dwarf::DW_FORM_rnglistx:
      case dwarf::DW_FORM_loclistx:
      case dwarf::DW_FORM_udata:
      case dwarf::DW_FORM_ref_udata:
      case dwarf::DW_FORM_GNU_addr_index:
      case dwarf::DW_FORM_GNU_str_index:
        encodeULEB128(FormVal->Value, OS);
        break;
      case dwarf::DW_FORM_data1:
      case dwarf::DW_FORM_ref1:
      case dwarf::DW_FORM_flag:
      case dwarf::DW_FORM_strx1:
      case dwarf::DW_FORM_addrx1:
        writeInteger((uint8_t)FormVal->Value, OS, IsLittleEndian);
        break;
      case dwarf::DW_FORM_data2:
      case dwarf::DW_FORM_ref2:
      case dwarf::DW_FORM_strx2:
      case dwarf::DW_FORM_addrx2:
        writeInteger((uint16_t)FormVal->Value, OS, IsLittleEndian);
        break;
      case dwarf::DW_FORM_data4:
      case dwarf::DW_FORM_ref4:
      case dwarf::DW_FORM_ref_sup4:
      case dwarf::DW_FORM_strx4:
      case dwarf::DW_FORM_addrx4:
        writeInteger((uint32_t)FormVal->Value, OS, IsLittleEndian);
        break;
      case dwarf::DW_FORM_data8:
      case dwarf::DW_FORM_ref8:
      case dwarf::DW_FORM_ref_sup8:
      case dwarf::DW_FORM_ref_sig8:
        writeInteger((uint64_t)FormVal->Value, OS, IsLittleEndian);
        break;
      case dwarf::DW_FORM_sdata:
        encodeSLEB128(FormVal->Value, OS);
        break;
      case dwarf::DW_FORM_string:
        OS.write(FormVal->CStr.data(), FormVal->CStr.size());
        OS.write('\0');
        break;
      case dwarf::DW_FORM_indirect:
        encodeULEB128(FormVal->Value, OS);
        Indirect = true;
        Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
        ++FormVal;
        break;
      case dwarf::DW_FORM_strp:
      case dwarf::DW_FORM_sec_offset:
      case dwarf::DW_FORM_GNU_ref_alt:
      case dwarf::DW_FORM_GNU_strp_alt:
      case dwarf::DW_FORM_line_strp:
      case dwarf::DW_FORM_strp_sup:
        cantFail(writeVariableSizedInteger(FormVal->Value,
                                           Params.getDwarfOffsetByteSize(), OS,
                                           IsLittleEndian));
        break;
      default:
        break;
      }
    } while (Indirect);
  }

  return OS.tell() - EntryBegin;
}

Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
  for (uint64_t I = 0; I < DI.CompileUnits.size(); ++I) {
    const DWARFYAML::Unit &Unit = DI.CompileUnits[I];
    uint8_t AddrSize;
    if (Unit.AddrSize)
      AddrSize = *Unit.AddrSize;
    else
      AddrSize = DI.Is64BitAddrSize ? 8 : 4;
    dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format};
    uint64_t Length = 3; // sizeof(version) + sizeof(address_size)
    Length += Unit.Version >= 5 ? 1 : 0;       // sizeof(unit_type)
    Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset)

    // Since the length of the current compilation unit is undetermined yet, we
    // firstly write the content of the compilation unit to a buffer to
    // calculate it and then serialize the buffer content to the actual output
    // stream.
    std::string EntryBuffer;
    raw_string_ostream EntryBufferOS(EntryBuffer);

    uint64_t AbbrevTableID = Unit.AbbrevTableID.value_or(I);
    for (const DWARFYAML::Entry &Entry : Unit.Entries) {
      if (Expected<uint64_t> EntryLength =
              writeDIE(DI, I, AbbrevTableID, Params, Entry, EntryBufferOS,
                       DI.IsLittleEndian))
        Length += *EntryLength;
      else
        return EntryLength.takeError();
    }

    // If the length is specified in the YAML description, we use it instead of
    // the actual length.
    if (Unit.Length)
      Length = *Unit.Length;

    writeInitialLength(Unit.Format, Length, OS, DI.IsLittleEndian);
    writeInteger((uint16_t)Unit.Version, OS, DI.IsLittleEndian);

    uint64_t AbbrevTableOffset = 0;
    if (Unit.AbbrOffset) {
      AbbrevTableOffset = *Unit.AbbrOffset;
    } else {
      if (Expected<DWARFYAML::Data::AbbrevTableInfo> AbbrevTableInfoOrErr =
              DI.getAbbrevTableInfoByID(AbbrevTableID)) {
        AbbrevTableOffset = AbbrevTableInfoOrErr->Offset;
      } else {
        // The current compilation unit may not have DIEs and it will not be
        // able to find the associated abbrev table. We consume the error and
        // assign 0 to the debug_abbrev_offset in such circumstances.
        consumeError(AbbrevTableInfoOrErr.takeError());
      }
    }

    if (Unit.Version >= 5) {
      writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian);
      writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
      writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
    } else {
      writeDWARFOffset(AbbrevTableOffset, Unit.Format, OS, DI.IsLittleEndian);
      writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
    }

    OS.write(EntryBuffer.data(), EntryBuffer.size());
  }

  return Error::success();
}

static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
  OS.write(File.Name.data(), File.Name.size());
  OS.write('\0');
  encodeULEB128(File.DirIdx, OS);
  encodeULEB128(File.ModTime, OS);
  encodeULEB128(File.Length, OS);
}

static void writeExtendedOpcode(const DWARFYAML::LineTableOpcode &Op,
                                uint8_t AddrSize, bool IsLittleEndian,
                                raw_ostream &OS) {
  // The first byte of extended opcodes is a zero byte. The next bytes are an
  // ULEB128 integer giving the number of bytes in the instruction itself (does
  // not include the first zero byte or the size). We serialize the instruction
  // itself into the OpBuffer and then write the size of the buffer and the
  // buffer to the real output stream.
  std::string OpBuffer;
  raw_string_ostream OpBufferOS(OpBuffer);
  writeInteger((uint8_t)Op.SubOpcode, OpBufferOS, IsLittleEndian);
  switch (Op.SubOpcode) {
  case dwarf::DW_LNE_set_address:
    cantFail(writeVariableSizedInteger(Op.Data, AddrSize, OpBufferOS,
                                       IsLittleEndian));
    break;
  case dwarf::DW_LNE_define_file:
    emitFileEntry(OpBufferOS, Op.FileEntry);
    break;
  case dwarf::DW_LNE_set_discriminator:
    encodeULEB128(Op.Data, OpBufferOS);
    break;
  case dwarf::DW_LNE_end_sequence:
    break;
  default:
    for (auto OpByte : Op.UnknownOpcodeData)
      writeInteger((uint8_t)OpByte, OpBufferOS, IsLittleEndian);
  }
  uint64_t ExtLen = Op.ExtLen.value_or(OpBuffer.size());
  encodeULEB128(ExtLen, OS);
  OS.write(OpBuffer.data(), OpBuffer.size());
}

static void writeLineTableOpcode(const DWARFYAML::LineTableOpcode &Op,
                                 uint8_t OpcodeBase, uint8_t AddrSize,
                                 raw_ostream &OS, bool IsLittleEndian) {
  writeInteger((uint8_t)Op.Opcode, OS, IsLittleEndian);
  if (Op.Opcode == 0) {
    writeExtendedOpcode(Op, AddrSize, IsLittleEndian, OS);
  } else if (Op.Opcode < OpcodeBase) {
    switch (Op.Opcode) {
    case dwarf::DW_LNS_copy:
    case dwarf::DW_LNS_negate_stmt:
    case dwarf::DW_LNS_set_basic_block:
    case dwarf::DW_LNS_const_add_pc:
    case dwarf::DW_LNS_set_prologue_end:
    case dwarf::DW_LNS_set_epilogue_begin:
      break;

    case dwarf::DW_LNS_advance_pc:
    case dwarf::DW_LNS_set_file:
    case dwarf::DW_LNS_set_column:
    case dwarf::DW_LNS_set_isa:
      encodeULEB128(Op.Data, OS);
      break;

    case dwarf::DW_LNS_advance_line:
      encodeSLEB128(Op.SData, OS);
      break;

    case dwarf::DW_LNS_fixed_advance_pc:
      writeInteger((uint16_t)Op.Data, OS, IsLittleEndian);
      break;

    default:
      for (auto OpData : Op.StandardOpcodeData) {
        encodeULEB128(OpData, OS);
      }
    }
  }
}

static std::vector<uint8_t>
getStandardOpcodeLengths(uint16_t Version, Optional<uint8_t> OpcodeBase) {
  // If the opcode_base field isn't specified, we returns the
  // standard_opcode_lengths array according to the version by default.
  std::vector<uint8_t> StandardOpcodeLengths{0, 1, 1, 1, 1, 0,
                                             0, 0, 1, 0, 0, 1};
  if (Version == 2) {
    // DWARF v2 uses the same first 9 standard opcodes as v3-5.
    StandardOpcodeLengths.resize(9);
  } else if (OpcodeBase) {
    StandardOpcodeLengths.resize(*OpcodeBase > 0 ? *OpcodeBase - 1 : 0, 0);
  }
  return StandardOpcodeLengths;
}

Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
  for (const DWARFYAML::LineTable &LineTable : DI.DebugLines) {
    // Buffer holds the bytes following the header_length (or prologue_length in
    // DWARFv2) field to the end of the line number program itself.
    std::string Buffer;
    raw_string_ostream BufferOS(Buffer);

    writeInteger(LineTable.MinInstLength, BufferOS, DI.IsLittleEndian);
    // TODO: Add support for emitting DWARFv5 line table.
    if (LineTable.Version >= 4)
      writeInteger(LineTable.MaxOpsPerInst, BufferOS, DI.IsLittleEndian);
    writeInteger(LineTable.DefaultIsStmt, BufferOS, DI.IsLittleEndian);
    writeInteger(LineTable.LineBase, BufferOS, DI.IsLittleEndian);
    writeInteger(LineTable.LineRange, BufferOS, DI.IsLittleEndian);

    std::vector<uint8_t> StandardOpcodeLengths =
        LineTable.StandardOpcodeLengths.value_or(
            getStandardOpcodeLengths(LineTable.Version, LineTable.OpcodeBase));
    uint8_t OpcodeBase = LineTable.OpcodeBase
                             ? *LineTable.OpcodeBase
                             : StandardOpcodeLengths.size() + 1;
    writeInteger(OpcodeBase, BufferOS, DI.IsLittleEndian);
    for (uint8_t OpcodeLength : StandardOpcodeLengths)
      writeInteger(OpcodeLength, BufferOS, DI.IsLittleEndian);

    for (StringRef IncludeDir : LineTable.IncludeDirs) {
      BufferOS.write(IncludeDir.data(), IncludeDir.size());
      BufferOS.write('\0');
    }
    BufferOS.write('\0');

    for (const DWARFYAML::File &File : LineTable.Files)
      emitFileEntry(BufferOS, File);
    BufferOS.write('\0');

    uint64_t HeaderLength =
        LineTable.PrologueLength ? *LineTable.PrologueLength : Buffer.size();

    for (const DWARFYAML::LineTableOpcode &Op : LineTable.Opcodes)
      writeLineTableOpcode(Op, OpcodeBase, DI.Is64BitAddrSize ? 8 : 4, BufferOS,
                           DI.IsLittleEndian);

    uint64_t Length;
    if (LineTable.Length) {
      Length = *LineTable.Length;
    } else {
      Length = 2; // sizeof(version)
      Length +=
          (LineTable.Format == dwarf::DWARF64 ? 8 : 4); // sizeof(header_length)
      Length += Buffer.size();
    }

    writeInitialLength(LineTable.Format, Length, OS, DI.IsLittleEndian);
    writeInteger(LineTable.Version, OS, DI.IsLittleEndian);
    writeDWARFOffset(HeaderLength, LineTable.Format, OS, DI.IsLittleEndian);
    OS.write(Buffer.data(), Buffer.size());
  }

  return Error::success();
}

Error DWARFYAML::emitDebugAddr(raw_ostream &OS, const Data &DI) {
  for (const AddrTableEntry &TableEntry : *DI.DebugAddr) {
    uint8_t AddrSize;
    if (TableEntry.AddrSize)
      AddrSize = *TableEntry.AddrSize;
    else
      AddrSize = DI.Is64BitAddrSize ? 8 : 4;

    uint64_t Length;
    if (TableEntry.Length)
      Length = (uint64_t)*TableEntry.Length;
    else
      // 2 (version) + 1 (address_size) + 1 (segment_selector_size) = 4
      Length = 4 + (AddrSize + TableEntry.SegSelectorSize) *
                       TableEntry.SegAddrPairs.size();

    writeInitialLength(TableEntry.Format, Length, OS, DI.IsLittleEndian);
    writeInteger((uint16_t)TableEntry.Version, OS, DI.IsLittleEndian);
    writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian);
    writeInteger((uint8_t)TableEntry.SegSelectorSize, OS, DI.IsLittleEndian);

    for (const SegAddrPair &Pair : TableEntry.SegAddrPairs) {
      if (TableEntry.SegSelectorSize != yaml::Hex8{0})
        if (Error Err = writeVariableSizedInteger(Pair.Segment,
                                                  TableEntry.SegSelectorSize,
                                                  OS, DI.IsLittleEndian))
          return createStringError(errc::not_supported,
                                   "unable to write debug_addr segment: %s",
                                   toString(std::move(Err)).c_str());
      if (AddrSize != 0)
        if (Error Err = writeVariableSizedInteger(Pair.Address, AddrSize, OS,
                                                  DI.IsLittleEndian))
          return createStringError(errc::not_supported,
                                   "unable to write debug_addr address: %s",
                                   toString(std::move(Err)).c_str());
    }
  }

  return Error::success();
}

Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, const Data &DI) {
  assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call");
  for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) {
    uint64_t Length;
    if (Table.Length)
      Length = *Table.Length;
    else
      // sizeof(version) + sizeof(padding) = 4
      Length =
          4 + Table.Offsets.size() * (Table.Format == dwarf::DWARF64 ? 8 : 4);

    writeInitialLength(Table.Format, Length, OS, DI.IsLittleEndian);
    writeInteger((uint16_t)Table.Version, OS, DI.IsLittleEndian);
    writeInteger((uint16_t)Table.Padding, OS, DI.IsLittleEndian);

    for (uint64_t Offset : Table.Offsets)
      writeDWARFOffset(Offset, Table.Format, OS, DI.IsLittleEndian);
  }

  return Error::success();
}

static Error checkOperandCount(StringRef EncodingString,
                               ArrayRef<yaml::Hex64> Values,
                               uint64_t ExpectedOperands) {
  if (Values.size() != ExpectedOperands)
    return createStringError(
        errc::invalid_argument,
        "invalid number (%zu) of operands for the operator: %s, %" PRIu64
        " expected",
        Values.size(), EncodingString.str().c_str(), ExpectedOperands);

  return Error::success();
}

static Error writeListEntryAddress(StringRef EncodingName, raw_ostream &OS,
                                   uint64_t Addr, uint8_t AddrSize,
                                   bool IsLittleEndian) {
  if (Error Err = writeVariableSizedInteger(Addr, AddrSize, OS, IsLittleEndian))
    return createStringError(errc::invalid_argument,
                             "unable to write address for the operator %s: %s",
                             EncodingName.str().c_str(),
                             toString(std::move(Err)).c_str());

  return Error::success();
}

static Expected<uint64_t>
writeDWARFExpression(raw_ostream &OS,
                     const DWARFYAML::DWARFOperation &Operation,
                     uint8_t AddrSize, bool IsLittleEndian) {
  auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
    return checkOperandCount(dwarf::OperationEncodingString(Operation.Operator),
                             Operation.Values, ExpectedOperands);
  };

  uint64_t ExpressionBegin = OS.tell();
  writeInteger((uint8_t)Operation.Operator, OS, IsLittleEndian);
  switch (Operation.Operator) {
  case dwarf::DW_OP_consts:
    if (Error Err = CheckOperands(1))
      return std::move(Err);
    encodeSLEB128(Operation.Values[0], OS);
    break;
  case dwarf::DW_OP_stack_value:
    if (Error Err = CheckOperands(0))
      return std::move(Err);
    break;
  default:
    StringRef EncodingStr = dwarf::OperationEncodingString(Operation.Operator);
    return createStringError(errc::not_supported,
                             "DWARF expression: " +
                                 (EncodingStr.empty()
                                      ? "0x" + utohexstr(Operation.Operator)
                                      : EncodingStr) +
                                 " is not supported");
  }
  return OS.tell() - ExpressionBegin;
}

static Expected<uint64_t> writeListEntry(raw_ostream &OS,
                                         const DWARFYAML::RnglistEntry &Entry,
                                         uint8_t AddrSize,
                                         bool IsLittleEndian) {
  uint64_t BeginOffset = OS.tell();
  writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);

  StringRef EncodingName = dwarf::RangeListEncodingString(Entry.Operator);

  auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
    return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
  };

  auto WriteAddress = [&](uint64_t Addr) -> Error {
    return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
                                 IsLittleEndian);
  };

  switch (Entry.Operator) {
  case dwarf::DW_RLE_end_of_list:
    if (Error Err = CheckOperands(0))
      return std::move(Err);
    break;
  case dwarf::DW_RLE_base_addressx:
    if (Error Err = CheckOperands(1))
      return std::move(Err);
    encodeULEB128(Entry.Values[0], OS);
    break;
  case dwarf::DW_RLE_startx_endx:
  case dwarf::DW_RLE_startx_length:
  case dwarf::DW_RLE_offset_pair:
    if (Error Err = CheckOperands(2))
      return std::move(Err);
    encodeULEB128(Entry.Values[0], OS);
    encodeULEB128(Entry.Values[1], OS);
    break;
  case dwarf::DW_RLE_base_address:
    if (Error Err = CheckOperands(1))
      return std::move(Err);
    if (Error Err = WriteAddress(Entry.Values[0]))
      return std::move(Err);
    break;
  case dwarf::DW_RLE_start_end:
    if (Error Err = CheckOperands(2))
      return std::move(Err);
    if (Error Err = WriteAddress(Entry.Values[0]))
      return std::move(Err);
    cantFail(WriteAddress(Entry.Values[1]));
    break;
  case dwarf::DW_RLE_start_length:
    if (Error Err = CheckOperands(2))
      return std::move(Err);
    if (Error Err = WriteAddress(Entry.Values[0]))
      return std::move(Err);
    encodeULEB128(Entry.Values[1], OS);
    break;
  }

  return OS.tell() - BeginOffset;
}

static Expected<uint64_t> writeListEntry(raw_ostream &OS,
                                         const DWARFYAML::LoclistEntry &Entry,
                                         uint8_t AddrSize,
                                         bool IsLittleEndian) {
  uint64_t BeginOffset = OS.tell();
  writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian);

  StringRef EncodingName = dwarf::LocListEncodingString(Entry.Operator);

  auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error {
    return checkOperandCount(EncodingName, Entry.Values, ExpectedOperands);
  };

  auto WriteAddress = [&](uint64_t Addr) -> Error {
    return writeListEntryAddress(EncodingName, OS, Addr, AddrSize,
                                 IsLittleEndian);
  };

  auto WriteDWARFOperations = [&]() -> Error {
    std::string OpBuffer;
    raw_string_ostream OpBufferOS(OpBuffer);
    uint64_t DescriptionsLength = 0;

    for (const DWARFYAML::DWARFOperation &Op : Entry.Descriptions) {
      if (Expected<uint64_t> OpSize =
              writeDWARFExpression(OpBufferOS, Op, AddrSize, IsLittleEndian))
        DescriptionsLength += *OpSize;
      else
        return OpSize.takeError();
    }

    if (Entry.DescriptionsLength)
      DescriptionsLength = *Entry.DescriptionsLength;
    else
      DescriptionsLength = OpBuffer.size();

    encodeULEB128(DescriptionsLength, OS);
    OS.write(OpBuffer.data(), OpBuffer.size());

    return Error::success();
  };

  switch (Entry.Operator) {
  case dwarf::DW_LLE_end_of_list:
    if (Error Err = CheckOperands(0))
      return std::move(Err);
    break;
  case dwarf::DW_LLE_base_addressx:
    if (Error Err = CheckOperands(1))
      return std::move(Err);
    encodeULEB128(Entry.Values[0], OS);
    break;
  case dwarf::DW_LLE_startx_endx:
  case dwarf::DW_LLE_startx_length:
  case dwarf::DW_LLE_offset_pair:
    if (Error Err = CheckOperands(2))
      return std::move(Err);
    encodeULEB128(Entry.Values[0], OS);
    encodeULEB128(Entry.Values[1], OS);
    if (Error Err = WriteDWARFOperations())
      return std::move(Err);
    break;
  case dwarf::DW_LLE_default_location:
    if (Error Err = CheckOperands(0))
      return std::move(Err);
    if (Error Err = WriteDWARFOperations())
      return std::move(Err);
    break;
  case dwarf::DW_LLE_base_address:
    if (Error Err = CheckOperands(1))
      return std::move(Err);
    if (Error Err = WriteAddress(Entry.Values[0]))
      return std::move(Err);
    break;
  case dwarf::DW_LLE_start_end:
    if (Error Err = CheckOperands(2))
      return std::move(Err);
    if (Error Err = WriteAddress(Entry.Values[0]))
      return std::move(Err);
    cantFail(WriteAddress(Entry.Values[1]));
    if (Error Err = WriteDWARFOperations())
      return std::move(Err);
    break;
  case dwarf::DW_LLE_start_length:
    if (Error Err = CheckOperands(2))
      return std::move(Err);
    if (Error Err = WriteAddress(Entry.Values[0]))
      return std::move(Err);
    encodeULEB128(Entry.Values[1], OS);
    if (Error Err = WriteDWARFOperations())
      return std::move(Err);
    break;
  }

  return OS.tell() - BeginOffset;
}

template <typename EntryType>
static Error writeDWARFLists(raw_ostream &OS,
                             ArrayRef<DWARFYAML::ListTable<EntryType>> Tables,
                             bool IsLittleEndian, bool Is64BitAddrSize) {
  for (const DWARFYAML::ListTable<EntryType> &Table : Tables) {
    // sizeof(version) + sizeof(address_size) + sizeof(segment_selector_size) +
    // sizeof(offset_entry_count) = 8
    uint64_t Length = 8;

    uint8_t AddrSize;
    if (Table.AddrSize)
      AddrSize = *Table.AddrSize;
    else
      AddrSize = Is64BitAddrSize ? 8 : 4;

    // Since the length of the current range/location lists entry is
    // undetermined yet, we firstly write the content of the range/location
    // lists to a buffer to calculate the length and then serialize the buffer
    // content to the actual output stream.
    std::string ListBuffer;
    raw_string_ostream ListBufferOS(ListBuffer);

    // Offsets holds offsets for each range/location list. The i-th element is
    // the offset from the beginning of the first range/location list to the
    // location of the i-th range list.
    std::vector<uint64_t> Offsets;

    for (const DWARFYAML::ListEntries<EntryType> &List : Table.Lists) {
      Offsets.push_back(ListBufferOS.tell());
      if (List.Content) {
        List.Content->writeAsBinary(ListBufferOS, UINT64_MAX);
        Length += List.Content->binary_size();
      } else if (List.Entries) {
        for (const EntryType &Entry : *List.Entries) {
          Expected<uint64_t> EntrySize =
              writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian);
          if (!EntrySize)
            return EntrySize.takeError();
          Length += *EntrySize;
        }
      }
    }

    // If the offset_entry_count field isn't specified, yaml2obj will infer it
    // from the 'Offsets' field in the YAML description. If the 'Offsets' field
    // isn't specified either, yaml2obj will infer it from the auto-generated
    // offsets.
    uint32_t OffsetEntryCount;
    if (Table.OffsetEntryCount)
      OffsetEntryCount = *Table.OffsetEntryCount;
    else
      OffsetEntryCount = Table.Offsets ? Table.Offsets->size() : Offsets.size();
    uint64_t OffsetsSize =
        OffsetEntryCount * (Table.Format == dwarf::DWARF64 ? 8 : 4);
    Length += OffsetsSize;

    // If the length is specified in the YAML description, we use it instead of
    // the actual length.
    if (Table.Length)
      Length = *Table.Length;

    writeInitialLength(Table.Format, Length, OS, IsLittleEndian);
    writeInteger((uint16_t)Table.Version, OS, IsLittleEndian);
    writeInteger((uint8_t)AddrSize, OS, IsLittleEndian);
    writeInteger((uint8_t)Table.SegSelectorSize, OS, IsLittleEndian);
    writeInteger((uint32_t)OffsetEntryCount, OS, IsLittleEndian);

    auto EmitOffsets = [&](ArrayRef<uint64_t> Offsets, uint64_t OffsetsSize) {
      for (uint64_t Offset : Offsets)
        writeDWARFOffset(OffsetsSize + Offset, Table.Format, OS,
                         IsLittleEndian);
    };

    if (Table.Offsets)
      EmitOffsets(ArrayRef<uint64_t>((const uint64_t *)Table.Offsets->data(),
                                     Table.Offsets->size()),
                  0);
    else if (OffsetEntryCount != 0)
      EmitOffsets(Offsets, OffsetsSize);

    OS.write(ListBuffer.data(), ListBuffer.size());
  }

  return Error::success();
}

Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) {
  assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call");
  return writeDWARFLists<DWARFYAML::RnglistEntry>(
      OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize);
}

Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, const Data &DI) {
  assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call");
  return writeDWARFLists<DWARFYAML::LoclistEntry>(
      OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize);
}

std::function<Error(raw_ostream &, const DWARFYAML::Data &)>
DWARFYAML::getDWARFEmitterByName(StringRef SecName) {
  auto EmitFunc =
      StringSwitch<
          std::function<Error(raw_ostream &, const DWARFYAML::Data &)>>(SecName)
          .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev)
          .Case("debug_addr", DWARFYAML::emitDebugAddr)
          .Case("debug_aranges", DWARFYAML::emitDebugAranges)
          .Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames)
          .Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes)
          .Case("debug_info", DWARFYAML::emitDebugInfo)
          .Case("debug_line", DWARFYAML::emitDebugLine)
          .Case("debug_loclists", DWARFYAML::emitDebugLoclists)
          .Case("debug_pubnames", DWARFYAML::emitDebugPubnames)
          .Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes)
          .Case("debug_ranges", DWARFYAML::emitDebugRanges)
          .Case("debug_rnglists", DWARFYAML::emitDebugRnglists)
          .Case("debug_str", DWARFYAML::emitDebugStr)
          .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets)
          .Default([&](raw_ostream &, const DWARFYAML::Data &) {
            return createStringError(errc::not_supported,
                                     SecName + " is not supported");
          });

  return EmitFunc;
}

static Error
emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec,
                     StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) {
  std::string Data;
  raw_string_ostream DebugInfoStream(Data);

  auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec);

  if (Error Err = EmitFunc(DebugInfoStream, DI))
    return Err;
  DebugInfoStream.flush();
  if (!Data.empty())
    OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data);

  return Error::success();
}

Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
DWARFYAML::emitDebugSections(StringRef YAMLString, bool IsLittleEndian,
                             bool Is64BitAddrSize) {
  auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) {
    *static_cast<SMDiagnostic *>(DiagContext) = Diag;
  };

  SMDiagnostic GeneratedDiag;
  yaml::Input YIn(YAMLString, /*Ctxt=*/nullptr, CollectDiagnostic,
                  &GeneratedDiag);

  DWARFYAML::Data DI;
  DI.IsLittleEndian = IsLittleEndian;
  DI.Is64BitAddrSize = Is64BitAddrSize;

  YIn >> DI;
  if (YIn.error())
    return createStringError(YIn.error(), GeneratedDiag.getMessage());

  StringMap<std::unique_ptr<MemoryBuffer>> DebugSections;
  Error Err = Error::success();

  for (StringRef SecName : DI.getNonEmptySectionNames())
    Err = joinErrors(std::move(Err),
                     emitDebugSectionImpl(DI, SecName, DebugSections));

  if (Err)
    return std::move(Err);
  return std::move(DebugSections);
}
