//===----- PerfSupportPlugin.cpp --- Utils for perf support -----*- 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
//
//===----------------------------------------------------------------------===//
//
// Handles support for registering code with perf
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.h"

#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"
#include "llvm/ExecutionEngine/Orc/LookupAndApply.h"
#include "llvm/ExecutionEngine/Orc/SPSProxySpec.h"
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"

#define DEBUG_TYPE "orc"

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

// Controller-interface descriptors for the executor's perf-support wrapper
// calls.
namespace llvm::orc::perf_sps_ci {
struct RegisterPerfStart {
  static constexpr SymbolNameSpec Name =
      SymbolNameSpec::c("llvm_orc_registerJITLoaderPerfStart");
  using SPSSig = void();
};
struct RegisterPerfEnd {
  static constexpr SymbolNameSpec Name =
      SymbolNameSpec::c("llvm_orc_registerJITLoaderPerfEnd");
  using SPSSig = void();
};
} // namespace llvm::orc::perf_sps_ci

namespace {

// Creates an EH frame header prepared for a 32-bit relative relocation
// to the start of the .eh_frame section. Absolute injects a 64-bit absolute
// address space offset 4 bytes from the start instead of 4 bytes
Expected<std::string> createX64EHFrameHeader(Section &EHFrame,
                                             llvm::endianness endianness,
                                             bool absolute) {
  uint8_t Version = 1;
  uint8_t EhFramePtrEnc = 0;
  if (absolute) {
    EhFramePtrEnc |= dwarf::DW_EH_PE_sdata8 | dwarf::DW_EH_PE_absptr;
  } else {
    EhFramePtrEnc |= dwarf::DW_EH_PE_sdata4 | dwarf::DW_EH_PE_datarel;
  }
  uint8_t FDECountEnc = dwarf::DW_EH_PE_omit;
  uint8_t TableEnc = dwarf::DW_EH_PE_omit;
  // X86_64_64 relocation to the start of the .eh_frame section
  uint32_t EHFrameRelocation = 0;
  // uint32_t FDECount = 0;
  // Skip the FDE binary search table
  // We'd have to reprocess the CIEs to get this information,
  // which seems like more trouble than it's worth
  // TODO consider implementing this.
  // binary search table goes here

  size_t HeaderSize =
      (sizeof(Version) + sizeof(EhFramePtrEnc) + sizeof(FDECountEnc) +
       sizeof(TableEnc) +
       (absolute ? sizeof(uint64_t) : sizeof(EHFrameRelocation)));
  std::string HeaderContent(HeaderSize, '\0');
  BinaryStreamWriter Writer(
      MutableArrayRef<uint8_t>(
          reinterpret_cast<uint8_t *>(HeaderContent.data()), HeaderSize),
      endianness);
  if (auto Err = Writer.writeInteger(Version))
    return std::move(Err);
  if (auto Err = Writer.writeInteger(EhFramePtrEnc))
    return std::move(Err);
  if (auto Err = Writer.writeInteger(FDECountEnc))
    return std::move(Err);
  if (auto Err = Writer.writeInteger(TableEnc))
    return std::move(Err);
  if (absolute) {
    uint64_t EHFrameAddr = SectionRange(EHFrame).getStart().getValue();
    if (auto Err = Writer.writeInteger(EHFrameAddr))
      return std::move(Err);
  } else {
    if (auto Err = Writer.writeInteger(EHFrameRelocation))
      return std::move(Err);
  }
  return HeaderContent;
}

constexpr SymbolNameSpec RegisterPerfImplSymbolName =
    SymbolNameSpec::c("llvm_orc_registerJITLoaderPerfImpl");

static PerfJITCodeLoadRecord
getCodeLoadRecord(const Symbol &Sym, std::atomic<uint64_t> &CodeIndex) {
  PerfJITCodeLoadRecord Record;
  auto Name = *Sym.getName();
  auto Addr = Sym.getAddress();
  auto Size = Sym.getSize();
  Record.Prefix.Id = PerfJITRecordType::JIT_CODE_LOAD;
  // Runtime sets PID
  Record.Pid = 0;
  // Runtime sets TID
  Record.Tid = 0;
  Record.Vma = Addr.getValue();
  Record.CodeAddr = Addr.getValue();
  Record.CodeSize = Size;
  Record.CodeIndex = CodeIndex++;
  Record.Name = Name.str();
  // Initialize last, once all the other fields are filled
  Record.Prefix.TotalSize =
      (2 * sizeof(uint32_t)   // id, total_size
       + sizeof(uint64_t)     // timestamp
       + 2 * sizeof(uint32_t) // pid, tid
       + 4 * sizeof(uint64_t) // vma, code_addr, code_size, code_index
       + Name.size() + 1      // symbol name
       + Record.CodeSize      // code
      );
  return Record;
}

static std::optional<PerfJITDebugInfoRecord>
getDebugInfoRecord(const Symbol &Sym, DWARFContext &DC) {
  auto &Section = Sym.getSection();
  auto Addr = Sym.getAddress();
  auto Size = Sym.getSize();
  auto SAddr = object::SectionedAddress{Addr.getValue(), Section.getOrdinal()};
  LLVM_DEBUG(dbgs() << "Getting debug info for symbol " << Sym.getName()
                    << " at address " << Addr.getValue() << " with size "
                    << Size << "\n"
                    << "Section ordinal: " << Section.getOrdinal() << "\n");
  auto LInfo = DC.getLineInfoForAddressRange(
      SAddr, Size, DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);
  if (LInfo.empty()) {
    // No line info available
    LLVM_DEBUG(dbgs() << "No line info available\n");
    return std::nullopt;
  }
  PerfJITDebugInfoRecord Record;
  Record.Prefix.Id = PerfJITRecordType::JIT_CODE_DEBUG_INFO;
  Record.CodeAddr = Addr.getValue();
  for (const auto &Entry : LInfo) {
    auto Addr = Entry.first;
    // The function re-created by perf is preceded by a elf
    // header. Need to adjust for that, otherwise the results are
    // wrong.
    Addr += 0x40;
    Record.Entries.push_back({Addr, Entry.second.Line,
                              Entry.second.Discriminator,
                              Entry.second.FileName});
  }
  size_t EntriesBytes = (2   // record header
                         + 2 // record fields
                         ) *
                        sizeof(uint64_t);
  for (const auto &Entry : Record.Entries) {
    EntriesBytes +=
        sizeof(uint64_t) + 2 * sizeof(uint32_t); // Addr, Line/Discrim
    EntriesBytes += Entry.Name.size() + 1;       // Name
  }
  Record.Prefix.TotalSize = EntriesBytes;
  LLVM_DEBUG(dbgs() << "Created debug info record\n"
                    << "Total size: " << Record.Prefix.TotalSize << "\n"
                    << "Nr entries: " << Record.Entries.size() << "\n");
  return Record;
}

static Expected<PerfJITCodeUnwindingInfoRecord>
getUnwindingRecord(LinkGraph &G) {
  PerfJITCodeUnwindingInfoRecord Record;
  Record.Prefix.Id = PerfJITRecordType::JIT_CODE_UNWINDING_INFO;
  Record.Prefix.TotalSize = 0;
  auto Eh_frame = G.findSectionByName(".eh_frame");
  if (!Eh_frame) {
    LLVM_DEBUG(dbgs() << "No .eh_frame section found\n");
    return Record;
  }
  if (!G.getTargetTriple().isOSBinFormatELF()) {
    LLVM_DEBUG(dbgs() << "Not an ELF file, will not emit unwinding info\n");
    return Record;
  }
  auto SR = SectionRange(*Eh_frame);
  auto EHFrameSize = SR.getSize();
  auto Eh_frame_hdr = G.findSectionByName(".eh_frame_hdr");
  if (!Eh_frame_hdr) {
    if (G.getTargetTriple().getArch() == Triple::x86_64) {
      auto Hdr = createX64EHFrameHeader(*Eh_frame, G.getEndianness(), true);
      if (!Hdr)
        return Hdr.takeError();
      Record.EHFrameHdr = std::move(*Hdr);
    } else {
      LLVM_DEBUG(dbgs() << "No .eh_frame_hdr section found\n");
      return Record;
    }
    Record.EHFrameHdrAddr = 0;
    Record.EHFrameHdrSize = Record.EHFrameHdr.size();
    Record.UnwindDataSize = EHFrameSize + Record.EHFrameHdrSize;
    Record.MappedSize = 0; // Because the EHFrame header was not mapped
  } else {
    auto SR = SectionRange(*Eh_frame_hdr);
    Record.EHFrameHdrAddr = SR.getStart().getValue();
    Record.EHFrameHdrSize = SR.getSize();
    Record.UnwindDataSize = EHFrameSize + Record.EHFrameHdrSize;
    Record.MappedSize = Record.UnwindDataSize;
  }
  Record.EHFrameAddr = SR.getStart().getValue();
  Record.Prefix.TotalSize =
      (2 * sizeof(uint32_t) // id, total_size
       + sizeof(uint64_t)   // timestamp
       +
       3 * sizeof(uint64_t) // unwind_data_size, eh_frame_hdr_size, mapped_size
       + Record.UnwindDataSize // eh_frame_hdr, eh_frame
      );
  LLVM_DEBUG(dbgs() << "Created unwind record\n"
                    << "Total size: " << Record.Prefix.TotalSize << "\n"
                    << "Unwind size: " << Record.UnwindDataSize << "\n"
                    << "EHFrame size: " << EHFrameSize << "\n"
                    << "EHFrameHdr size: " << Record.EHFrameHdrSize << "\n");
  return Record;
}

static PerfJITRecordBatch getRecords(ExecutionSession &ES, LinkGraph &G,
                                     std::atomic<uint64_t> &CodeIndex,
                                     bool EmitDebugInfo, bool EmitUnwindInfo) {
  std::unique_ptr<DWARFContext> DC;
  StringMap<std::unique_ptr<MemoryBuffer>> DCBacking;
  if (EmitDebugInfo) {
    auto EDC = createDWARFContext(G);
    if (!EDC) {
      ES.reportError(EDC.takeError());
      EmitDebugInfo = false;
    } else {
      DC = std::move(EDC->first);
      DCBacking = std::move(EDC->second);
    }
  }
  PerfJITRecordBatch Batch;
  for (auto Sym : G.defined_symbols()) {
    if (!Sym->hasName() || !Sym->isCallable())
      continue;
    if (EmitDebugInfo) {
      auto DebugInfo = getDebugInfoRecord(*Sym, *DC);
      if (DebugInfo)
        Batch.DebugInfoRecords.push_back(std::move(*DebugInfo));
    }
    Batch.CodeLoadRecords.push_back(getCodeLoadRecord(*Sym, CodeIndex));
  }
  if (EmitUnwindInfo) {
    auto UWR = getUnwindingRecord(G);
    if (!UWR) {
      ES.reportError(UWR.takeError());
    } else {
      Batch.UnwindingRecord = std::move(*UWR);
    }
  } else {
    Batch.UnwindingRecord.Prefix.TotalSize = 0;
  }
  return Batch;
}
} // namespace

PerfSupportPlugin::PerfSupportPlugin(ExecutorProcessControl &EPC,
                                     ExecutorAddr RegisterPerfStartAddr,
                                     ExecutorAddr RegisterPerfEndAddr,
                                     ExecutorAddr RegisterPerfImplAddr,
                                     bool EmitDebugInfo, bool EmitUnwindInfo)
    : EPC(EPC), RegisterPerfStart(
                    sps::ProxySpec<Proxy<void()>,
                                   perf_sps_ci::RegisterPerfStart>::dispatch,
                    RegisterPerfStartAddr),
      RegisterPerfEnd(
          sps::ProxySpec<Proxy<void()>, perf_sps_ci::RegisterPerfEnd>::dispatch,
          RegisterPerfEndAddr),
      RegisterPerfImplAddr(RegisterPerfImplAddr), CodeIndex(0),
      EmitDebugInfo(EmitDebugInfo), EmitUnwindInfo(EmitUnwindInfo) {
  cantFail(RegisterPerfStart(EPC.getExecutionSession()));
}
PerfSupportPlugin::~PerfSupportPlugin() {
  // FIXME: End message from destructor is unreliable. Executor-side perf
  //        support (currently JITLoaderPerf.cpp in OrcTargetProcess) should be
  //        reimplemented as a service in the new ORC runtime, where cleanup
  //        can be run as an on-shutdown event.
  //
  // For now, switch to async dispatch here so that a message failure doesn't
  // load to a crash when we try to read from a std::future whose std::promise
  // has been destoryed.
  RegisterPerfEnd([](Error Err) { consumeError(std::move(Err)); },
                  EPC.getExecutionSession());
}

void PerfSupportPlugin::modifyPassConfig(MaterializationResponsibility &MR,
                                         LinkGraph &G,
                                         PassConfiguration &Config) {
  Config.PostFixupPasses.push_back([this](LinkGraph &G) {
    auto Batch = getRecords(EPC.getExecutionSession(), G, CodeIndex,
                            EmitDebugInfo, EmitUnwindInfo);
    G.allocActions().push_back(
        {cantFail(shared::WrapperFunctionCall::Create<
                  shared::SPSArgList<shared::SPSPerfJITRecordBatch>>(
             RegisterPerfImplAddr, Batch)),
         {}});
    return Error::success();
  });
}

Expected<std::unique_ptr<PerfSupportPlugin>>
PerfSupportPlugin::Create(ExecutorProcessControl &EPC, JITDylib &JD,
                          bool EmitDebugInfo, bool EmitUnwindInfo) {
  if (!EPC.getTargetTriple().isOSBinFormatELF()) {
    return make_error<StringError>(
        "Perf support only available for ELF LinkGraphs!",
        inconvertibleErrorCode());
  }
  ExecutorAddr StartAddr, EndAddr, ImplAddr;
  if (auto Err = lookupAndApply(
          JD, {recordAddr(perf_sps_ci::RegisterPerfStart::Name, &StartAddr),
               recordAddr(perf_sps_ci::RegisterPerfEnd::Name, &EndAddr),
               recordAddr(RegisterPerfImplSymbolName, &ImplAddr)}))
    return std::move(Err);
  return std::make_unique<PerfSupportPlugin>(EPC, StartAddr, EndAddr, ImplAddr,
                                             EmitDebugInfo, EmitUnwindInfo);
}
