//=== OutputSections.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 "OutputSections.h"
#include "DWARFLinkerCompileUnit.h"
#include "DWARFLinkerTypeUnit.h"

using namespace llvm;
using namespace dwarf_linker;
using namespace dwarf_linker::parallel;

DebugDieRefPatch::DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU,
                                   CompileUnit *RefCU, uint32_t RefIdx)
    : SectionPatch({PatchOffset}),
      RefCU(RefCU, (SrcCU != nullptr) &&
                       (SrcCU->getUniqueID() == RefCU->getUniqueID())),
      RefDieIdxOrClonedOffset(RefIdx) {}

DebugULEB128DieRefPatch::DebugULEB128DieRefPatch(uint64_t PatchOffset,
                                                 CompileUnit *SrcCU,
                                                 CompileUnit *RefCU,
                                                 uint32_t RefIdx)
    : SectionPatch({PatchOffset}),
      RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()),
      RefDieIdxOrClonedOffset(RefIdx) {}

DebugDieTypeRefPatch::DebugDieTypeRefPatch(uint64_t PatchOffset,
                                           TypeEntry *RefTypeName)
    : SectionPatch({PatchOffset}), RefTypeName(RefTypeName) {}

DebugType2TypeDieRefPatch::DebugType2TypeDieRefPatch(uint64_t PatchOffset,
                                                     DIE *Die,
                                                     TypeEntry *TypeName,
                                                     TypeEntry *RefTypeName)
    : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
      RefTypeName(RefTypeName) {}

DebugTypeStrPatch::DebugTypeStrPatch(uint64_t PatchOffset, DIE *Die,
                                     TypeEntry *TypeName, StringEntry *String)
    : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
      String(String) {}

DebugTypeLineStrPatch::DebugTypeLineStrPatch(uint64_t PatchOffset, DIE *Die,
                                             TypeEntry *TypeName,
                                             StringEntry *String)
    : SectionPatch({PatchOffset}), Die(Die), TypeName(TypeName),
      String(String) {}

DebugTypeDeclFilePatch::DebugTypeDeclFilePatch(DIE *Die, TypeEntry *TypeName,
                                               StringEntry *Directory,
                                               StringEntry *FilePath)
    : Die(Die), TypeName(TypeName), Directory(Directory), FilePath(FilePath) {}

void SectionDescriptor::clearAllSectionData() {
  StartOffset = 0;
  clearSectionContent();
  ListDebugStrPatch.erase();
  ListDebugLineStrPatch.erase();
  ListDebugRangePatch.erase();
  ListDebugLocPatch.erase();
  ListDebugDieRefPatch.erase();
  ListDebugULEB128DieRefPatch.erase();
  ListDebugOffsetPatch.erase();
  ListDebugType2TypeDieRefPatch.erase();
  ListDebugTypeDeclFilePatch.erase();
  ListDebugTypeLineStrPatch.erase();
  ListDebugTypeStrPatch.erase();
}

void SectionDescriptor::clearSectionContent() { Contents = OutSectionDataTy(); }

void SectionDescriptor::setSizesForSectionCreatedByAsmPrinter() {
  if (Contents.empty())
    return;

  MemoryBufferRef Mem(Contents, "obj");
  Expected<std::unique_ptr<object::ObjectFile>> Obj =
      object::ObjectFile::createObjectFile(Mem);
  if (!Obj) {
    consumeError(Obj.takeError());
    Contents.clear();
    return;
  }

  for (const object::SectionRef &Sect : (*Obj).get()->sections()) {
    Expected<StringRef> SectNameOrErr = Sect.getName();
    if (!SectNameOrErr) {
      consumeError(SectNameOrErr.takeError());
      continue;
    }
    if (std::optional<DebugSectionKind> SectKind =
            parseDebugTableName(*SectNameOrErr)) {
      if (*SectKind == SectionKind) {
        Expected<StringRef> Data = Sect.getContents();
        if (!Data) {
          consumeError(SectNameOrErr.takeError());
          Contents.clear();
          return;
        }

        SectionOffsetInsideAsmPrinterOutputStart =
            Data->data() - Contents.data();
        SectionOffsetInsideAsmPrinterOutputEnd =
            SectionOffsetInsideAsmPrinterOutputStart + Data->size();
      }
    }
  }
}

void SectionDescriptor::emitString(dwarf::Form StringForm,
                                   const char *StringVal) {
  assert(StringVal != nullptr);

  switch (StringForm) {
  case dwarf::DW_FORM_string: {
    emitInplaceString(StringVal);
  } break;
  case dwarf::DW_FORM_strp: {
    notePatch(DebugStrPatch{
        {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first});
    emitStringPlaceholder();
  } break;
  case dwarf::DW_FORM_line_strp: {
    notePatch(DebugLineStrPatch{
        {OS.tell()}, GlobalData.getStringPool().insert(StringVal).first});
    emitStringPlaceholder();
  } break;
  default:
    llvm_unreachable("Unsupported string form");
    break;
  };
}

void SectionDescriptor::emitIntVal(uint64_t Val, unsigned Size) {
  switch (Size) {
  case 1: {
    OS.write(static_cast<uint8_t>(Val));
  } break;
  case 2: {
    uint16_t ShortVal = static_cast<uint16_t>(Val);
    if (Endianess != llvm::endianness::native)
      sys::swapByteOrder(ShortVal);
    OS.write(reinterpret_cast<const char *>(&ShortVal), Size);
  } break;
  case 4: {
    uint32_t ShortVal = static_cast<uint32_t>(Val);
    if (Endianess != llvm::endianness::native)
      sys::swapByteOrder(ShortVal);
    OS.write(reinterpret_cast<const char *>(&ShortVal), Size);
  } break;
  case 8: {
    if (Endianess != llvm::endianness::native)
      sys::swapByteOrder(Val);
    OS.write(reinterpret_cast<const char *>(&Val), Size);
  } break;
  default:
    llvm_unreachable("Unsupported integer type size");
  }
}

void SectionDescriptor::emitBinaryData(llvm::StringRef Data) {
  OS.write(Data.data(), Data.size());
}

void SectionDescriptor::apply(uint64_t PatchOffset, dwarf::Form AttrForm,
                              uint64_t Val) {
  switch (AttrForm) {
  case dwarf::DW_FORM_strp:
  case dwarf::DW_FORM_line_strp: {
    applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize());
  } break;

  case dwarf::DW_FORM_ref_addr: {
    applyIntVal(PatchOffset, Val, Format.getRefAddrByteSize());
  } break;
  case dwarf::DW_FORM_ref1: {
    applyIntVal(PatchOffset, Val, 1);
  } break;
  case dwarf::DW_FORM_ref2: {
    applyIntVal(PatchOffset, Val, 2);
  } break;
  case dwarf::DW_FORM_ref4: {
    applyIntVal(PatchOffset, Val, 4);
  } break;
  case dwarf::DW_FORM_ref8: {
    applyIntVal(PatchOffset, Val, 8);
  } break;

  case dwarf::DW_FORM_data1: {
    applyIntVal(PatchOffset, Val, 1);
  } break;
  case dwarf::DW_FORM_data2: {
    applyIntVal(PatchOffset, Val, 2);
  } break;
  case dwarf::DW_FORM_data4: {
    applyIntVal(PatchOffset, Val, 4);
  } break;
  case dwarf::DW_FORM_data8: {
    applyIntVal(PatchOffset, Val, 8);
  } break;
  case dwarf::DW_FORM_udata: {
    applyULEB128(PatchOffset, Val);
  } break;
  case dwarf::DW_FORM_sdata: {
    applySLEB128(PatchOffset, Val);
  } break;
  case dwarf::DW_FORM_sec_offset: {
    applyIntVal(PatchOffset, Val, Format.getDwarfOffsetByteSize());
  } break;
  case dwarf::DW_FORM_flag: {
    applyIntVal(PatchOffset, Val, 1);
  } break;

  default:
    llvm_unreachable("Unsupported attribute form");
    break;
  }
}

uint64_t SectionDescriptor::getIntVal(uint64_t PatchOffset, unsigned Size) {
  assert(PatchOffset < getContents().size());
  switch (Size) {
  case 1: {
    return *reinterpret_cast<const uint8_t *>(
        (getContents().data() + PatchOffset));
  }
  case 2: {
    return support::endian::read16(getContents().data() + PatchOffset,
                                   Endianess);
  }
  case 4: {
    return support::endian::read32(getContents().data() + PatchOffset,
                                   Endianess);
  }
  case 8: {
    return support::endian::read64(getContents().data() + PatchOffset,
                                   Endianess);
  }
  }
  llvm_unreachable("Unsupported integer type size");
  return 0;
}

void SectionDescriptor::applyIntVal(uint64_t PatchOffset, uint64_t Val,
                                    unsigned Size) {
  assert(PatchOffset < getContents().size());

  switch (Size) {
  case 1: {
    support::endian::write(
        const_cast<char *>(getContents().data() + PatchOffset),
        static_cast<uint8_t>(Val), Endianess);
  } break;
  case 2: {
    support::endian::write(
        const_cast<char *>(getContents().data() + PatchOffset),
        static_cast<uint16_t>(Val), Endianess);
  } break;
  case 4: {
    support::endian::write(
        const_cast<char *>(getContents().data() + PatchOffset),
        static_cast<uint32_t>(Val), Endianess);
  } break;
  case 8: {
    support::endian::write(
        const_cast<char *>(getContents().data() + PatchOffset),
        static_cast<uint64_t>(Val), Endianess);
  } break;
  default:
    llvm_unreachable("Unsupported integer type size");
  }
}

void SectionDescriptor::applyULEB128(uint64_t PatchOffset, uint64_t Val) {
  assert(PatchOffset < getContents().size());

  uint8_t ULEB[16];
  uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1;
  uint8_t RealSize = encodeULEB128(Val, ULEB, DestSize);

  memcpy(const_cast<char *>(getContents().data() + PatchOffset), ULEB,
         RealSize);
}

/// Writes integer value \p Val of SLEB128 format by specified \p PatchOffset.
void SectionDescriptor::applySLEB128(uint64_t PatchOffset, uint64_t Val) {
  assert(PatchOffset < getContents().size());

  uint8_t SLEB[16];
  uint8_t DestSize = Format.getDwarfOffsetByteSize() + 1;
  uint8_t RealSize = encodeSLEB128(Val, SLEB, DestSize);

  memcpy(const_cast<char *>(getContents().data() + PatchOffset), SLEB,
         RealSize);
}

void OutputSections::applyPatches(
    SectionDescriptor &Section,
    StringEntryToDwarfStringPoolEntryMap &DebugStrStrings,
    StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings,
    TypeUnit *TypeUnitPtr) {
  Section.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
    DwarfStringPoolEntryWithExtString *Entry =
        DebugStrStrings.getExistingEntry(Patch.String);
    assert(Entry != nullptr);

    Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
  });
  Section.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) {
    assert(TypeUnitPtr != nullptr);
    TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
    assert(TypeEntry &&
           formatv("No data for type {0}", Patch.TypeName->getKey())
               .str()
               .c_str());

    if (&TypeEntry->getFinalDie() != Patch.Die)
      return;

    DwarfStringPoolEntryWithExtString *Entry =
        DebugStrStrings.getExistingEntry(Patch.String);
    assert(Entry != nullptr);

    Patch.PatchOffset +=
        Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber());

    Section.apply(Patch.PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
  });

  Section.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
    DwarfStringPoolEntryWithExtString *Entry =
        DebugLineStrStrings.getExistingEntry(Patch.String);
    assert(Entry != nullptr);

    Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
  });
  Section.ListDebugTypeLineStrPatch.forEach([&](DebugTypeLineStrPatch &Patch) {
    assert(TypeUnitPtr != nullptr);
    TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
    assert(TypeEntry &&
           formatv("No data for type {0}", Patch.TypeName->getKey())
               .str()
               .c_str());

    if (&TypeEntry->getFinalDie() != Patch.Die)
      return;

    DwarfStringPoolEntryWithExtString *Entry =
        DebugLineStrStrings.getExistingEntry(Patch.String);
    assert(Entry != nullptr);

    Patch.PatchOffset +=
        Patch.Die->getOffset() + getULEB128Size(Patch.Die->getAbbrevNumber());

    Section.apply(Patch.PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
  });

  std::optional<SectionDescriptor *> RangeSection;
  if (Format.Version >= 5)
    RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRngLists);
  else
    RangeSection = tryGetSectionDescriptor(DebugSectionKind::DebugRange);

  if (RangeSection) {
    Section.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
      uint64_t FinalValue =
          Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
      FinalValue += (*RangeSection)->StartOffset;

      Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
    });
  }

  std::optional<SectionDescriptor *> LocationSection;
  if (Format.Version >= 5)
    LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLocLists);
  else
    LocationSection = tryGetSectionDescriptor(DebugSectionKind::DebugLoc);

  if (LocationSection) {
    Section.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {
      uint64_t FinalValue =
          Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());
      FinalValue += (*LocationSection)->StartOffset;

      Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
    });
  }

  Section.ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) {
    uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset;
    dwarf::Form FinalForm = dwarf::DW_FORM_ref4;

    // Check whether it is local or inter-CU reference.
    if (!Patch.RefCU.getInt()) {
      SectionDescriptor &ReferencedSectionDescriptor =
          Patch.RefCU.getPointer()->getSectionDescriptor(
              DebugSectionKind::DebugInfo);

      FinalForm = dwarf::DW_FORM_ref_addr;
      FinalOffset += ReferencedSectionDescriptor.StartOffset;
    }

    Section.apply(Patch.PatchOffset, FinalForm, FinalOffset);
  });

  Section.ListDebugULEB128DieRefPatch.forEach(
      [&](DebugULEB128DieRefPatch &Patch) {
        assert(Patch.RefCU.getInt());
        Section.apply(Patch.PatchOffset, dwarf::DW_FORM_udata,
                      Patch.RefDieIdxOrClonedOffset);
      });

  Section.ListDebugDieTypeRefPatch.forEach([&](DebugDieTypeRefPatch &Patch) {
    assert(TypeUnitPtr != nullptr);
    assert(Patch.RefTypeName != nullptr);

    TypeEntryBody *TypeEntry = Patch.RefTypeName->getValue().load();
    assert(TypeEntry &&
           formatv("No data for type {0}", Patch.RefTypeName->getKey())
               .str()
               .c_str());

    Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref_addr,
                  TypeEntry->getFinalDie().getOffset());
  });

  Section.ListDebugType2TypeDieRefPatch.forEach(
      [&](DebugType2TypeDieRefPatch &Patch) {
        assert(TypeUnitPtr != nullptr);
        TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
        assert(TypeEntry &&
               formatv("No data for type {0}", Patch.TypeName->getKey())
                   .str()
                   .c_str());

        if (&TypeEntry->getFinalDie() != Patch.Die)
          return;

        Patch.PatchOffset += Patch.Die->getOffset() +
                             getULEB128Size(Patch.Die->getAbbrevNumber());

        assert(Patch.RefTypeName != nullptr);
        TypeEntryBody *RefTypeEntry = Patch.RefTypeName->getValue().load();
        assert(TypeEntry &&
               formatv("No data for type {0}", Patch.RefTypeName->getKey())
                   .str()
                   .c_str());

        Section.apply(Patch.PatchOffset, dwarf::DW_FORM_ref4,
                      RefTypeEntry->getFinalDie().getOffset());
      });

  Section.ListDebugOffsetPatch.forEach([&](DebugOffsetPatch &Patch) {
    uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset;

    // Check whether we need to read value from the original location.
    if (Patch.SectionPtr.getInt())
      FinalValue +=
          Section.getIntVal(Patch.PatchOffset, Format.getDwarfOffsetByteSize());

    Section.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
  });
}
