//===----- 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/LookupAndRecordAddrs.h"
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"

#define DEBUG_TYPE "orc"

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

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 StringRef RegisterPerfStartSymbolName =
    "llvm_orc_registerJITLoaderPerfStart";
constexpr StringRef RegisterPerfEndSymbolName =
    "llvm_orc_registerJITLoaderPerfEnd";
constexpr StringRef RegisterPerfImplSymbolName =
    "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), RegisterPerfStartAddr(RegisterPerfStartAddr),
      RegisterPerfEndAddr(RegisterPerfEndAddr),
      RegisterPerfImplAddr(RegisterPerfImplAddr), CodeIndex(0),
      EmitDebugInfo(EmitDebugInfo), EmitUnwindInfo(EmitUnwindInfo) {
  cantFail(EPC.callSPSWrapper<void()>(RegisterPerfStartAddr));
}
PerfSupportPlugin::~PerfSupportPlugin() {
  cantFail(EPC.callSPSWrapper<void()>(RegisterPerfEndAddr));
}

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());
  }
  auto &ES = EPC.getExecutionSession();
  ExecutorAddr StartAddr, EndAddr, ImplAddr;
  if (auto Err = lookupAndRecordAddrs(
          ES, LookupKind::Static, makeJITDylibSearchOrder({&JD}),
          {{ES.intern(RegisterPerfStartSymbolName), &StartAddr},
           {ES.intern(RegisterPerfEndSymbolName), &EndAddr},
           {ES.intern(RegisterPerfImplSymbolName), &ImplAddr}}))
    return std::move(Err);
  return std::make_unique<PerfSupportPlugin>(EPC, StartAddr, EndAddr, ImplAddr,
                                             EmitDebugInfo, EmitUnwindInfo);
}
