//===------- DebuggerSupportPlugin.cpp - Utils for debugger support -------===//
//
// 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/ExecutionEngine/Orc/DebuggerSupportPlugin.h"

#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/BinaryFormat/MachO.h"

#define DEBUG_TYPE "orc"

using namespace llvm;
using namespace llvm::jitlink;
using namespace llvm::orc;

static const char *SynthDebugSectionName = "__jitlink_synth_debug_object";

namespace {

struct MachO64LE {
  using UIntPtr = uint64_t;

  using Header = MachO::mach_header_64;
  using SegmentLC = MachO::segment_command_64;
  using Section = MachO::section_64;
  using NList = MachO::nlist_64;

  static constexpr support::endianness Endianness = support::little;
  static constexpr const uint32_t Magic = MachO::MH_MAGIC_64;
  static constexpr const uint32_t SegmentCmd = MachO::LC_SEGMENT_64;
};

class MachODebugObjectSynthesizerBase
    : public GDBJITDebugInfoRegistrationPlugin::DebugSectionSynthesizer {
public:
  static bool isDebugSection(Section &Sec) {
    return Sec.getName().startswith("__DWARF,");
  }

  MachODebugObjectSynthesizerBase(LinkGraph &G, ExecutorAddr RegisterActionAddr)
      : G(G), RegisterActionAddr(RegisterActionAddr) {}
  virtual ~MachODebugObjectSynthesizerBase() = default;

  Error preserveDebugSections() {
    if (G.findSectionByName(SynthDebugSectionName)) {
      LLVM_DEBUG({
        dbgs() << "MachODebugObjectSynthesizer skipping graph " << G.getName()
               << " which contains an unexpected existing "
               << SynthDebugSectionName << " section.\n";
      });
      return Error::success();
    }

    LLVM_DEBUG({
      dbgs() << "MachODebugObjectSynthesizer visiting graph " << G.getName()
             << "\n";
    });
    for (auto &Sec : G.sections()) {
      if (!isDebugSection(Sec))
        continue;
      // Preserve blocks in this debug section by marking one existing symbol
      // live for each block, and introducing a new live, anonymous symbol for
      // each currently unreferenced block.
      LLVM_DEBUG({
        dbgs() << "  Preserving debug section " << Sec.getName() << "\n";
      });
      SmallSet<Block *, 8> PreservedBlocks;
      for (auto *Sym : Sec.symbols()) {
        bool NewPreservedBlock =
            PreservedBlocks.insert(&Sym->getBlock()).second;
        if (NewPreservedBlock)
          Sym->setLive(true);
      }
      for (auto *B : Sec.blocks())
        if (!PreservedBlocks.count(B))
          G.addAnonymousSymbol(*B, 0, 0, false, true);
    }
    return Error::success();
  }

protected:
  LinkGraph &G;
  ExecutorAddr RegisterActionAddr;
};

template <typename MachOTraits>
class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
private:
  class MachOStructWriter {
  public:
    MachOStructWriter(MutableArrayRef<char> Buffer) : Buffer(Buffer) {}

    size_t getOffset() const { return Offset; }

    template <typename MachOStruct> void write(MachOStruct S) {
      assert(Offset + sizeof(S) <= Buffer.size() &&
             "Container block overflow while constructing debug MachO");
      if (MachOTraits::Endianness != support::endian::system_endianness())
        MachO::swapStruct(S);
      memcpy(Buffer.data() + Offset, &S, sizeof(S));
      Offset += sizeof(S);
    }

  private:
    MutableArrayRef<char> Buffer;
    size_t Offset = 0;
  };

public:
  using MachODebugObjectSynthesizerBase::MachODebugObjectSynthesizerBase;

  Error startSynthesis() override {
    LLVM_DEBUG({
      dbgs() << "Creating " << SynthDebugSectionName << " for " << G.getName()
             << "\n";
    });
    auto &SDOSec = G.createSection(SynthDebugSectionName, MemProt::Read);

    struct DebugSectionInfo {
      Section *Sec = nullptr;
      StringRef SegName;
      StringRef SecName;
      uint64_t Alignment = 0;
      orc::ExecutorAddr StartAddr;
      uint64_t Size = 0;
    };

    SmallVector<DebugSectionInfo, 12> DebugSecInfos;
    size_t NumSections = 0;
    for (auto &Sec : G.sections()) {
      if (Sec.blocks().empty())
        continue;

      ++NumSections;
      if (isDebugSection(Sec)) {
        size_t SepPos = Sec.getName().find(',');
        if (SepPos > 16 || (Sec.getName().size() - (SepPos + 1) > 16)) {
          LLVM_DEBUG({
            dbgs() << "Skipping debug object synthesis for graph "
                   << G.getName()
                   << ": encountered non-standard DWARF section name \""
                   << Sec.getName() << "\"\n";
          });
          return Error::success();
        }
        DebugSecInfos.push_back({&Sec, Sec.getName().substr(0, SepPos),
                                 Sec.getName().substr(SepPos + 1), 0,
                                 orc::ExecutorAddr(), 0});
      } else {
        NonDebugSections.push_back(&Sec);

        // If the first block in the section has a non-zero alignment offset
        // then we need to add a padding block, since the section command in
        // the header doesn't allow for aligment offsets.
        SectionRange R(Sec);
        if (!R.empty()) {
          auto &FB = *R.getFirstBlock();
          if (FB.getAlignmentOffset() != 0) {
            auto Padding = G.allocateBuffer(FB.getAlignmentOffset());
            memset(Padding.data(), 0, Padding.size());
            G.createContentBlock(Sec, Padding,
                                 FB.getAddress() - FB.getAlignmentOffset(),
                                 FB.getAlignment(), 0);
          }
        }
      }
    }

    // Create container block.
    size_t SectionsCmdSize =
        sizeof(typename MachOTraits::Section) * NumSections;
    size_t SegmentLCSize =
        sizeof(typename MachOTraits::SegmentLC) + SectionsCmdSize;
    size_t ContainerBlockSize =
        sizeof(typename MachOTraits::Header) + SegmentLCSize;
    auto ContainerBlockContent = G.allocateBuffer(ContainerBlockSize);
    MachOContainerBlock = &G.createMutableContentBlock(
        SDOSec, ContainerBlockContent, orc::ExecutorAddr(), 8, 0);

    // Copy debug section blocks and symbols.
    orc::ExecutorAddr NextBlockAddr(MachOContainerBlock->getSize());
    for (auto &SI : DebugSecInfos) {
      assert(!SI.Sec->blocks().empty() && "Empty debug info section?");

      // Update addresses in debug section.
      LLVM_DEBUG({
        dbgs() << "  Appending " << SI.Sec->getName() << " ("
               << SI.Sec->blocks_size() << " block(s)) at "
               << formatv("{0:x8}", NextBlockAddr) << "\n";
      });
      for (auto *B : SI.Sec->blocks()) {
        NextBlockAddr = alignToBlock(NextBlockAddr, *B);
        B->setAddress(NextBlockAddr);
        NextBlockAddr += B->getSize();
      }

      auto &FirstBlock = **SI.Sec->blocks().begin();
      if (FirstBlock.getAlignmentOffset() != 0)
        return make_error<StringError>(
            "First block in " + SI.Sec->getName() +
                " section has non-zero alignment offset",
            inconvertibleErrorCode());
      if (FirstBlock.getAlignment() > std::numeric_limits<uint32_t>::max())
        return make_error<StringError>("First block in " + SI.Sec->getName() +
                                           " has alignment >4Gb",
                                       inconvertibleErrorCode());

      SI.Alignment = FirstBlock.getAlignment();
      SI.StartAddr = FirstBlock.getAddress();
      SI.Size = NextBlockAddr - SI.StartAddr;
      G.mergeSections(SDOSec, *SI.Sec);
      SI.Sec = nullptr;
    }
    size_t DebugSectionsSize =
        NextBlockAddr - orc::ExecutorAddr(MachOContainerBlock->getSize());

    // Write MachO header and debug section load commands.
    MachOStructWriter Writer(MachOContainerBlock->getAlreadyMutableContent());
    typename MachOTraits::Header Hdr;
    memset(&Hdr, 0, sizeof(Hdr));
    Hdr.magic = MachOTraits::Magic;
    switch (G.getTargetTriple().getArch()) {
    case Triple::x86_64:
      Hdr.cputype = MachO::CPU_TYPE_X86_64;
      Hdr.cpusubtype = MachO::CPU_SUBTYPE_X86_64_ALL;
      break;
    case Triple::aarch64:
      Hdr.cputype = MachO::CPU_TYPE_ARM64;
      Hdr.cpusubtype = MachO::CPU_SUBTYPE_ARM64_ALL;
      break;
    default:
      llvm_unreachable("Unsupported architecture");
    }
    Hdr.filetype = MachO::MH_OBJECT;
    Hdr.ncmds = 1;
    Hdr.sizeofcmds = SegmentLCSize;
    Hdr.flags = 0;
    Writer.write(Hdr);

    typename MachOTraits::SegmentLC SegLC;
    memset(&SegLC, 0, sizeof(SegLC));
    SegLC.cmd = MachOTraits::SegmentCmd;
    SegLC.cmdsize = SegmentLCSize;
    SegLC.vmaddr = ContainerBlockSize;
    SegLC.vmsize = DebugSectionsSize;
    SegLC.fileoff = ContainerBlockSize;
    SegLC.filesize = DebugSectionsSize;
    SegLC.maxprot =
        MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE;
    SegLC.initprot =
        MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE;
    SegLC.nsects = NumSections;
    SegLC.flags = 0;
    Writer.write(SegLC);

    StringSet<> ExistingLongNames;
    for (auto &SI : DebugSecInfos) {
      typename MachOTraits::Section Sec;
      memset(&Sec, 0, sizeof(Sec));
      memcpy(Sec.sectname, SI.SecName.data(), SI.SecName.size());
      memcpy(Sec.segname, SI.SegName.data(), SI.SegName.size());
      Sec.addr = SI.StartAddr.getValue();
      Sec.size = SI.Size;
      Sec.offset = SI.StartAddr.getValue();
      Sec.align = SI.Alignment;
      Sec.reloff = 0;
      Sec.nreloc = 0;
      Sec.flags = MachO::S_ATTR_DEBUG;
      Writer.write(Sec);
    }

    // Set MachOContainerBlock to indicate success to
    // completeSynthesisAndRegister.
    NonDebugSectionsStart = Writer.getOffset();
    return Error::success();
  }

  Error completeSynthesisAndRegister() override {
    if (!MachOContainerBlock) {
      LLVM_DEBUG({
        dbgs() << "Not writing MachO debug object header for " << G.getName()
               << " since createDebugSection failed\n";
      });
      return Error::success();
    }

    LLVM_DEBUG({
      dbgs() << "Writing MachO debug object header for " << G.getName() << "\n";
    });

    MachOStructWriter Writer(
        MachOContainerBlock->getAlreadyMutableContent().drop_front(
            NonDebugSectionsStart));

    unsigned LongSectionNameIdx = 0;
    for (auto *Sec : NonDebugSections) {
      size_t SepPos = Sec->getName().find(',');
      StringRef SegName, SecName;
      std::string CustomSecName;

      if ((SepPos == StringRef::npos && Sec->getName().size() <= 16)) {
        // No embedded segment name, short section name.
        SegName = "__JITLINK_CUSTOM";
        SecName = Sec->getName();
      } else if (SepPos < 16 && (Sec->getName().size() - (SepPos + 1) <= 16)) {
        // Canonical embedded segment and section name.
        SegName = Sec->getName().substr(0, SepPos);
        SecName = Sec->getName().substr(SepPos + 1);
      } else {
        // Long section name that needs to be truncated.
        assert(Sec->getName().size() > 16 &&
               "Short section name should have been handled above");
        SegName = "__JITLINK_CUSTOM";
        auto IdxStr = std::to_string(++LongSectionNameIdx);
        CustomSecName = Sec->getName().substr(0, 15 - IdxStr.size()).str();
        CustomSecName += ".";
        CustomSecName += IdxStr;
        SecName = StringRef(CustomSecName.data(), 16);
      }

      SectionRange R(*Sec);
      if (R.getFirstBlock()->getAlignmentOffset() != 0)
        return make_error<StringError>(
            "While building MachO debug object for " + G.getName() +
                " first block has non-zero alignment offset",
            inconvertibleErrorCode());

      typename MachOTraits::Section SecCmd;
      memset(&SecCmd, 0, sizeof(SecCmd));
      memcpy(SecCmd.sectname, SecName.data(), SecName.size());
      memcpy(SecCmd.segname, SegName.data(), SegName.size());
      SecCmd.addr = R.getStart().getValue();
      SecCmd.size = R.getSize();
      SecCmd.offset = 0;
      SecCmd.align = R.getFirstBlock()->getAlignment();
      SecCmd.reloff = 0;
      SecCmd.nreloc = 0;
      SecCmd.flags = 0;
      Writer.write(SecCmd);
    }

    SectionRange R(MachOContainerBlock->getSection());
    G.allocActions().push_back(
        {cantFail(shared::WrapperFunctionCall::Create<
                  shared::SPSArgList<shared::SPSExecutorAddrRange>>(
             RegisterActionAddr, R.getRange())),
         {}});
    return Error::success();
  }

private:
  Block *MachOContainerBlock = nullptr;
  SmallVector<Section *, 16> NonDebugSections;
  size_t NonDebugSectionsStart = 0;
};

} // end anonymous namespace

namespace llvm {
namespace orc {

Expected<std::unique_ptr<GDBJITDebugInfoRegistrationPlugin>>
GDBJITDebugInfoRegistrationPlugin::Create(ExecutionSession &ES,
                                          JITDylib &ProcessJD,
                                          const Triple &TT) {
  auto RegisterActionAddr =
      TT.isOSBinFormatMachO()
          ? ES.intern("_llvm_orc_registerJITLoaderGDBAllocAction")
          : ES.intern("llvm_orc_registerJITLoaderGDBAllocAction");

  if (auto Addr = ES.lookup({&ProcessJD}, RegisterActionAddr))
    return std::make_unique<GDBJITDebugInfoRegistrationPlugin>(
        ExecutorAddr(Addr->getAddress()));
  else
    return Addr.takeError();
}

Error GDBJITDebugInfoRegistrationPlugin::notifyFailed(
    MaterializationResponsibility &MR) {
  return Error::success();
}

Error GDBJITDebugInfoRegistrationPlugin::notifyRemovingResources(
    JITDylib &JD, ResourceKey K) {
  return Error::success();
}

void GDBJITDebugInfoRegistrationPlugin::notifyTransferringResources(
    JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) {}

void GDBJITDebugInfoRegistrationPlugin::modifyPassConfig(
    MaterializationResponsibility &MR, LinkGraph &LG,
    PassConfiguration &PassConfig) {

  if (LG.getTargetTriple().getObjectFormat() == Triple::MachO)
    modifyPassConfigForMachO(MR, LG, PassConfig);
  else {
    LLVM_DEBUG({
      dbgs() << "GDBJITDebugInfoRegistrationPlugin skipping unspported graph "
             << LG.getName() << "(triple = " << LG.getTargetTriple().str()
             << "\n";
    });
  }
}

void GDBJITDebugInfoRegistrationPlugin::modifyPassConfigForMachO(
    MaterializationResponsibility &MR, jitlink::LinkGraph &LG,
    jitlink::PassConfiguration &PassConfig) {

  switch (LG.getTargetTriple().getArch()) {
  case Triple::x86_64:
  case Triple::aarch64:
    // Supported, continue.
    assert(LG.getPointerSize() == 8 && "Graph has incorrect pointer size");
    assert(LG.getEndianness() == support::little &&
           "Graph has incorrect endianness");
    break;
  default:
    // Unsupported.
    LLVM_DEBUG({
      dbgs() << "GDBJITDebugInfoRegistrationPlugin skipping unsupported "
             << "MachO graph " << LG.getName()
             << "(triple = " << LG.getTargetTriple().str()
             << ", pointer size = " << LG.getPointerSize() << ", endianness = "
             << (LG.getEndianness() == support::big ? "big" : "little")
             << ")\n";
    });
    return;
  }

  // Scan for debug sections. If we find one then install passes.
  bool HasDebugSections = false;
  for (auto &Sec : LG.sections())
    if (MachODebugObjectSynthesizerBase::isDebugSection(Sec)) {
      HasDebugSections = true;
      break;
    }

  if (HasDebugSections) {
    LLVM_DEBUG({
      dbgs() << "GDBJITDebugInfoRegistrationPlugin: Graph " << LG.getName()
             << " contains debug info. Installing debugger support passes.\n";
    });

    auto MDOS = std::make_shared<MachODebugObjectSynthesizer<MachO64LE>>(
        LG, RegisterActionAddr);
    PassConfig.PrePrunePasses.push_back(
        [=](LinkGraph &G) { return MDOS->preserveDebugSections(); });
    PassConfig.PostPrunePasses.push_back(
        [=](LinkGraph &G) { return MDOS->startSynthesis(); });
    PassConfig.PreFixupPasses.push_back(
        [=](LinkGraph &G) { return MDOS->completeSynthesisAndRegister(); });
  } else {
    LLVM_DEBUG({
      dbgs() << "GDBJITDebugInfoRegistrationPlugin: Graph " << LG.getName()
             << " contains no debug info. Skipping.\n";
    });
  }
}

} // namespace orc
} // namespace llvm
