//===------ dwarf2yaml.cpp - obj2yaml conversion tool -----------*- C++ -*-===//
//
// 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/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/ObjectYAML/DWARFYAML.h"

#include <algorithm>

using namespace llvm;

void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  auto AbbrevSetPtr = DCtx.getDebugAbbrev();
  if (AbbrevSetPtr) {
    uint64_t AbbrevTableID = 0;
    for (auto AbbrvDeclSet : *AbbrevSetPtr) {
      Y.DebugAbbrev.emplace_back();
      Y.DebugAbbrev.back().ID = AbbrevTableID++;
      for (auto AbbrvDecl : AbbrvDeclSet.second) {
        DWARFYAML::Abbrev Abbrv;
        Abbrv.Code = AbbrvDecl.getCode();
        Abbrv.Tag = AbbrvDecl.getTag();
        Abbrv.Children = AbbrvDecl.hasChildren() ? dwarf::DW_CHILDREN_yes
                                                 : dwarf::DW_CHILDREN_no;
        for (auto Attribute : AbbrvDecl.attributes()) {
          DWARFYAML::AttributeAbbrev AttAbrv;
          AttAbrv.Attribute = Attribute.Attr;
          AttAbrv.Form = Attribute.Form;
          if (AttAbrv.Form == dwarf::DW_FORM_implicit_const)
            AttAbrv.Value = Attribute.getImplicitConstValue();
          Abbrv.Attributes.push_back(AttAbrv);
        }
        Y.DebugAbbrev.back().Table.push_back(Abbrv);
      }
    }
  }
}

Error dumpDebugAddr(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  DWARFDebugAddrTable AddrTable;
  DWARFDataExtractor AddrData(DCtx.getDWARFObj(),
                              DCtx.getDWARFObj().getAddrSection(),
                              DCtx.isLittleEndian(), /*AddrSize=*/0);
  std::vector<DWARFYAML::AddrTableEntry> AddrTables;
  uint64_t Offset = 0;
  while (AddrData.isValidOffset(Offset)) {
    // We ignore any errors that don't prevent parsing the section, since we can
    // still represent such sections.
    if (Error Err = AddrTable.extractV5(AddrData, &Offset, /*CUAddrSize=*/0,
                                        consumeError))
      return Err;
    AddrTables.emplace_back();
    for (uint64_t Addr : AddrTable.getAddressEntries()) {
      // Currently, the parser doesn't support parsing an address table with non
      // linear addresses (segment_selector_size != 0). The segment selectors
      // are specified to be zero.
      AddrTables.back().SegAddrPairs.push_back(
          {/*SegmentSelector=*/0, /*Address=*/Addr});
    }

    AddrTables.back().Format = AddrTable.getFormat();
    AddrTables.back().Length = AddrTable.getLength();
    AddrTables.back().Version = AddrTable.getVersion();
    AddrTables.back().AddrSize = AddrTable.getAddressSize();
    AddrTables.back().SegSelectorSize = AddrTable.getSegmentSelectorSize();
  }
  Y.DebugAddr = std::move(AddrTables);
  return Error::success();
}

Error dumpDebugStrings(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  DataExtractor StrData = DCtx.getStringExtractor();
  uint64_t Offset = 0;
  std::vector<StringRef> DebugStr;
  Error Err = Error::success();
  while (StrData.isValidOffset(Offset)) {
    const char *CStr = StrData.getCStr(&Offset, &Err);
    if (Err)
      return Err;
    DebugStr.push_back(CStr);
  }

  Y.DebugStrings = DebugStr;
  return Err;
}

Error dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  DWARFDataExtractor ArangesData(DCtx.getDWARFObj().getArangesSection(),
                                 DCtx.isLittleEndian(), 0);
  uint64_t Offset = 0;
  DWARFDebugArangeSet Set;
  std::vector<DWARFYAML::ARange> DebugAranges;

  // We ignore any errors that don't prevent parsing the section, since we can
  // still represent such sections. These errors are recorded via the
  // WarningHandler parameter of Set.extract().
  auto DiscardError = [](Error Err) { consumeError(std::move(Err)); };

  while (ArangesData.isValidOffset(Offset)) {
    if (Error E = Set.extract(ArangesData, &Offset, DiscardError))
      return E;
    DWARFYAML::ARange Range;
    Range.Format = Set.getHeader().Format;
    Range.Length = Set.getHeader().Length;
    Range.Version = Set.getHeader().Version;
    Range.CuOffset = Set.getHeader().CuOffset;
    Range.AddrSize = Set.getHeader().AddrSize;
    Range.SegSize = Set.getHeader().SegSize;
    for (auto Descriptor : Set.descriptors()) {
      DWARFYAML::ARangeDescriptor Desc;
      Desc.Address = Descriptor.Address;
      Desc.Length = Descriptor.Length;
      Range.Descriptors.push_back(Desc);
    }
    DebugAranges.push_back(Range);
  }

  Y.DebugAranges = DebugAranges;
  return ErrorSuccess();
}

Error dumpDebugRanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  // We are assuming all address byte sizes will be consistent across all
  // compile units.
  uint8_t AddrSize = 0;
  for (const auto &CU : DCtx.compile_units()) {
    const uint8_t CUAddrSize = CU->getAddressByteSize();
    if (AddrSize == 0)
      AddrSize = CUAddrSize;
    else if (CUAddrSize != AddrSize)
      return createStringError(std::errc::invalid_argument,
                               "address sizes vary in different compile units");
  }

  DWARFDataExtractor Data(DCtx.getDWARFObj().getRangesSection().Data,
                          DCtx.isLittleEndian(), AddrSize);
  uint64_t Offset = 0;
  DWARFDebugRangeList DwarfRanges;
  std::vector<DWARFYAML::Ranges> DebugRanges;

  while (Data.isValidOffset(Offset)) {
    DWARFYAML::Ranges YamlRanges;
    YamlRanges.Offset = Offset;
    YamlRanges.AddrSize = AddrSize;
    if (Error E = DwarfRanges.extract(Data, &Offset))
      return E;
    for (const auto &RLE : DwarfRanges.getEntries())
      YamlRanges.Entries.push_back({RLE.StartAddress, RLE.EndAddress});
    DebugRanges.push_back(std::move(YamlRanges));
  }

  Y.DebugRanges = DebugRanges;
  return ErrorSuccess();
}

static Optional<DWARFYAML::PubSection>
dumpPubSection(const DWARFContext &DCtx, const DWARFSection &Section,
               bool IsGNUStyle) {
  DWARFYAML::PubSection Y;
  DWARFDataExtractor PubSectionData(DCtx.getDWARFObj(), Section,
                                    DCtx.isLittleEndian(), 0);
  DWARFDebugPubTable Table;
  // We ignore any errors that don't prevent parsing the section, since we can
  // still represent such sections.
  Table.extract(PubSectionData, IsGNUStyle,
                [](Error Err) { consumeError(std::move(Err)); });
  ArrayRef<DWARFDebugPubTable::Set> Sets = Table.getData();
  if (Sets.empty())
    return None;

  // FIXME: Currently, obj2yaml only supports dumping the first pubtable.
  Y.Format = Sets[0].Format;
  Y.Length = Sets[0].Length;
  Y.Version = Sets[0].Version;
  Y.UnitOffset = Sets[0].Offset;
  Y.UnitSize = Sets[0].Size;

  for (const DWARFDebugPubTable::Entry &E : Sets[0].Entries)
    Y.Entries.push_back(DWARFYAML::PubEntry{(uint32_t)E.SecOffset,
                                            E.Descriptor.toBits(), E.Name});

  return Y;
}

void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  const DWARFObject &D = DCtx.getDWARFObj();

  Y.PubNames =
      dumpPubSection(DCtx, D.getPubnamesSection(), /*IsGNUStyle=*/false);
  Y.PubTypes =
      dumpPubSection(DCtx, D.getPubtypesSection(), /*IsGNUStyle=*/false);
  // TODO: Test dumping .debug_gnu_pubnames section.
  Y.GNUPubNames =
      dumpPubSection(DCtx, D.getGnuPubnamesSection(), /*IsGNUStyle=*/true);
  // TODO: Test dumping .debug_gnu_pubtypes section.
  Y.GNUPubTypes =
      dumpPubSection(DCtx, D.getGnuPubtypesSection(), /*IsGNUStyle=*/true);
}

void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  for (const auto &CU : DCtx.compile_units()) {
    DWARFYAML::Unit NewUnit;
    NewUnit.Format = CU->getFormat();
    NewUnit.Length = CU->getLength();
    NewUnit.Version = CU->getVersion();
    if (NewUnit.Version >= 5)
      NewUnit.Type = (dwarf::UnitType)CU->getUnitType();
    const DWARFDebugAbbrev *DebugAbbrev = DCtx.getDebugAbbrev();
    NewUnit.AbbrevTableID = std::distance(
        DebugAbbrev->begin(),
        llvm::find_if(
            *DebugAbbrev,
            [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) {
              return P.first == CU->getAbbreviations()->getOffset();
            }));
    NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset();
    NewUnit.AddrSize = CU->getAddressByteSize();
    for (auto DIE : CU->dies()) {
      DWARFYAML::Entry NewEntry;
      DataExtractor EntryData = CU->getDebugInfoExtractor();
      uint64_t offset = DIE.getOffset();

      assert(EntryData.isValidOffset(offset) && "Invalid DIE Offset");
      if (!EntryData.isValidOffset(offset))
        continue;

      NewEntry.AbbrCode = EntryData.getULEB128(&offset);

      auto AbbrevDecl = DIE.getAbbreviationDeclarationPtr();
      if (AbbrevDecl) {
        for (const auto &AttrSpec : AbbrevDecl->attributes()) {
          DWARFYAML::FormValue NewValue;
          NewValue.Value = 0xDEADBEEFDEADBEEF;
          DWARFDie DIEWrapper(CU.get(), &DIE);
          auto FormValue = DIEWrapper.find(AttrSpec.Attr);
          if (!FormValue)
            return;
          auto Form = FormValue.getValue().getForm();
          bool indirect = false;
          do {
            indirect = false;
            switch (Form) {
            case dwarf::DW_FORM_addr:
            case dwarf::DW_FORM_GNU_addr_index:
              if (auto Val = FormValue.getValue().getAsAddress())
                NewValue.Value = Val.getValue();
              break;
            case dwarf::DW_FORM_ref_addr:
            case dwarf::DW_FORM_ref1:
            case dwarf::DW_FORM_ref2:
            case dwarf::DW_FORM_ref4:
            case dwarf::DW_FORM_ref8:
            case dwarf::DW_FORM_ref_udata:
            case dwarf::DW_FORM_ref_sig8:
              if (auto Val = FormValue.getValue().getAsReferenceUVal())
                NewValue.Value = Val.getValue();
              break;
            case dwarf::DW_FORM_exprloc:
            case dwarf::DW_FORM_block:
            case dwarf::DW_FORM_block1:
            case dwarf::DW_FORM_block2:
            case dwarf::DW_FORM_block4:
              if (auto Val = FormValue.getValue().getAsBlock()) {
                auto BlockData = Val.getValue();
                std::copy(BlockData.begin(), BlockData.end(),
                          std::back_inserter(NewValue.BlockData));
              }
              NewValue.Value = NewValue.BlockData.size();
              break;
            case dwarf::DW_FORM_data1:
            case dwarf::DW_FORM_flag:
            case dwarf::DW_FORM_data2:
            case dwarf::DW_FORM_data4:
            case dwarf::DW_FORM_data8:
            case dwarf::DW_FORM_sdata:
            case dwarf::DW_FORM_udata:
            case dwarf::DW_FORM_ref_sup4:
            case dwarf::DW_FORM_ref_sup8:
              if (auto Val = FormValue.getValue().getAsUnsignedConstant())
                NewValue.Value = Val.getValue();
              break;
            case dwarf::DW_FORM_string:
              if (auto Val = FormValue.getValue().getAsCString())
                NewValue.CStr = Val.getValue();
              break;
            case dwarf::DW_FORM_indirect:
              indirect = true;
              if (auto Val = FormValue.getValue().getAsUnsignedConstant()) {
                NewValue.Value = Val.getValue();
                NewEntry.Values.push_back(NewValue);
                Form = static_cast<dwarf::Form>(Val.getValue());
              }
              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:
            case dwarf::DW_FORM_GNU_str_index:
            case dwarf::DW_FORM_strx:
              if (auto Val = FormValue.getValue().getAsCStringOffset())
                NewValue.Value = Val.getValue();
              break;
            case dwarf::DW_FORM_flag_present:
              NewValue.Value = 1;
              break;
            default:
              break;
            }
          } while (indirect);
          NewEntry.Values.push_back(NewValue);
        }
      }

      NewUnit.Entries.push_back(NewEntry);
    }
    Y.CompileUnits.push_back(NewUnit);
  }
}

bool dumpFileEntry(DataExtractor &Data, uint64_t &Offset,
                   DWARFYAML::File &File) {
  File.Name = Data.getCStr(&Offset);
  if (File.Name.empty())
    return false;
  File.DirIdx = Data.getULEB128(&Offset);
  File.ModTime = Data.getULEB128(&Offset);
  File.Length = Data.getULEB128(&Offset);
  return true;
}

void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
  for (const auto &CU : DCtx.compile_units()) {
    auto CUDIE = CU->getUnitDIE();
    if (!CUDIE)
      continue;
    if (auto StmtOffset =
            dwarf::toSectionOffset(CUDIE.find(dwarf::DW_AT_stmt_list))) {
      DWARFYAML::LineTable DebugLines;
      DataExtractor LineData(DCtx.getDWARFObj().getLineSection().Data,
                             DCtx.isLittleEndian(), CU->getAddressByteSize());
      uint64_t Offset = *StmtOffset;
      uint64_t LengthOrDWARF64Prefix = LineData.getU32(&Offset);
      if (LengthOrDWARF64Prefix == dwarf::DW_LENGTH_DWARF64) {
        DebugLines.Format = dwarf::DWARF64;
        DebugLines.Length = LineData.getU64(&Offset);
      } else {
        DebugLines.Format = dwarf::DWARF32;
        DebugLines.Length = LengthOrDWARF64Prefix;
      }
      assert(DebugLines.Length);
      uint64_t LineTableLength = *DebugLines.Length;
      uint64_t SizeOfPrologueLength =
          DebugLines.Format == dwarf::DWARF64 ? 8 : 4;
      DebugLines.Version = LineData.getU16(&Offset);
      DebugLines.PrologueLength =
          LineData.getUnsigned(&Offset, SizeOfPrologueLength);
      assert(DebugLines.PrologueLength);
      const uint64_t EndPrologue = *DebugLines.PrologueLength + Offset;

      DebugLines.MinInstLength = LineData.getU8(&Offset);
      if (DebugLines.Version >= 4)
        DebugLines.MaxOpsPerInst = LineData.getU8(&Offset);
      DebugLines.DefaultIsStmt = LineData.getU8(&Offset);
      DebugLines.LineBase = LineData.getU8(&Offset);
      DebugLines.LineRange = LineData.getU8(&Offset);
      DebugLines.OpcodeBase = LineData.getU8(&Offset);

      DebugLines.StandardOpcodeLengths.emplace();
      for (uint8_t i = 1; i < DebugLines.OpcodeBase; ++i)
        DebugLines.StandardOpcodeLengths->push_back(LineData.getU8(&Offset));

      while (Offset < EndPrologue) {
        StringRef Dir = LineData.getCStr(&Offset);
        if (!Dir.empty())
          DebugLines.IncludeDirs.push_back(Dir);
        else
          break;
      }

      while (Offset < EndPrologue) {
        DWARFYAML::File TmpFile;
        if (dumpFileEntry(LineData, Offset, TmpFile))
          DebugLines.Files.push_back(TmpFile);
        else
          break;
      }

      const uint64_t LineEnd =
          LineTableLength + *StmtOffset + SizeOfPrologueLength;
      while (Offset < LineEnd) {
        DWARFYAML::LineTableOpcode NewOp = {};
        NewOp.Opcode = (dwarf::LineNumberOps)LineData.getU8(&Offset);
        if (NewOp.Opcode == 0) {
          auto StartExt = Offset;
          NewOp.ExtLen = LineData.getULEB128(&Offset);
          NewOp.SubOpcode =
              (dwarf::LineNumberExtendedOps)LineData.getU8(&Offset);
          switch (NewOp.SubOpcode) {
          case dwarf::DW_LNE_set_address:
          case dwarf::DW_LNE_set_discriminator:
            NewOp.Data = LineData.getAddress(&Offset);
            break;
          case dwarf::DW_LNE_define_file:
            dumpFileEntry(LineData, Offset, NewOp.FileEntry);
            break;
          case dwarf::DW_LNE_end_sequence:
            break;
          default:
            while (Offset < StartExt + *NewOp.ExtLen)
              NewOp.UnknownOpcodeData.push_back(LineData.getU8(&Offset));
          }
        } else if (NewOp.Opcode < *DebugLines.OpcodeBase) {
          switch (NewOp.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:
            NewOp.Data = LineData.getULEB128(&Offset);
            break;

          case dwarf::DW_LNS_advance_line:
            NewOp.SData = LineData.getSLEB128(&Offset);
            break;

          case dwarf::DW_LNS_fixed_advance_pc:
            NewOp.Data = LineData.getU16(&Offset);
            break;

          default:
            for (uint8_t i = 0;
                 i <
                 DebugLines.StandardOpcodeLengths.getValue()[NewOp.Opcode - 1];
                 ++i)
              NewOp.StandardOpcodeData.push_back(LineData.getULEB128(&Offset));
          }
        }
        DebugLines.Opcodes.push_back(NewOp);
      }
      Y.DebugLines.push_back(DebugLines);
    }
  }
}
