//=== 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"
#include "llvm/ADT/StringSwitch.h"

namespace llvm {
namespace dwarflinker_parallel {

static constexpr StringLiteral SectionNames[SectionKindsNum] = {
    "debug_info",     "debug_line",     "debug_frame",       "debug_ranges",
    "debug_rnglists", "debug_loc",      "debug_loclists",    "debug_aranges",
    "debug_abbrev",   "debug_macinfo",  "debug_macro",       "debug_addr",
    "debug_str",      "debug_line_str", "debug_str_offsets", "debug_pubnames",
    "debug_pubtypes", "debug_names",    "apple_names",       "apple_namespac",
    "apple_objc",     "apple_types"};

const StringLiteral &getSectionName(DebugSectionKind SectionKind) {
  return SectionNames[static_cast<uint8_t>(SectionKind)];
}

std::optional<DebugSectionKind> parseDebugTableName(llvm::StringRef SecName) {
  return llvm::StringSwitch<std::optional<DebugSectionKind>>(
             SecName.substr(SecName.find_first_not_of("._")))
      .Case(getSectionName(DebugSectionKind::DebugInfo),
            DebugSectionKind::DebugInfo)
      .Case(getSectionName(DebugSectionKind::DebugLine),
            DebugSectionKind::DebugLine)
      .Case(getSectionName(DebugSectionKind::DebugFrame),
            DebugSectionKind::DebugFrame)
      .Case(getSectionName(DebugSectionKind::DebugRange),
            DebugSectionKind::DebugRange)
      .Case(getSectionName(DebugSectionKind::DebugRngLists),
            DebugSectionKind::DebugRngLists)
      .Case(getSectionName(DebugSectionKind::DebugLoc),
            DebugSectionKind::DebugLoc)
      .Case(getSectionName(DebugSectionKind::DebugLocLists),
            DebugSectionKind::DebugLocLists)
      .Case(getSectionName(DebugSectionKind::DebugARanges),
            DebugSectionKind::DebugARanges)
      .Case(getSectionName(DebugSectionKind::DebugAbbrev),
            DebugSectionKind::DebugAbbrev)
      .Case(getSectionName(DebugSectionKind::DebugMacinfo),
            DebugSectionKind::DebugMacinfo)
      .Case(getSectionName(DebugSectionKind::DebugMacro),
            DebugSectionKind::DebugMacro)
      .Case(getSectionName(DebugSectionKind::DebugAddr),
            DebugSectionKind::DebugAddr)
      .Case(getSectionName(DebugSectionKind::DebugStr),
            DebugSectionKind::DebugStr)
      .Case(getSectionName(DebugSectionKind::DebugLineStr),
            DebugSectionKind::DebugLineStr)
      .Case(getSectionName(DebugSectionKind::DebugStrOffsets),
            DebugSectionKind::DebugStrOffsets)
      .Case(getSectionName(DebugSectionKind::DebugPubNames),
            DebugSectionKind::DebugPubNames)
      .Case(getSectionName(DebugSectionKind::DebugPubTypes),
            DebugSectionKind::DebugPubTypes)
      .Case(getSectionName(DebugSectionKind::DebugNames),
            DebugSectionKind::DebugNames)
      .Case(getSectionName(DebugSectionKind::AppleNames),
            DebugSectionKind::AppleNames)
      .Case(getSectionName(DebugSectionKind::AppleNamespaces),
            DebugSectionKind::AppleNamespaces)
      .Case(getSectionName(DebugSectionKind::AppleObjC),
            DebugSectionKind::AppleObjC)
      .Case(getSectionName(DebugSectionKind::AppleTypes),
            DebugSectionKind::AppleTypes)
      .Default(std::nullopt);

  return std::nullopt;
}

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::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);
  });
}

} // end of namespace dwarflinker_parallel
} // end of namespace llvm
