//===----- ELF_i386.cpp - JIT linker implementation for ELF/i386 ----===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// ELF/i386 jit-link implementation.
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/JITLink/ELF_i386.h"
#include "DefineExternalSectionStartAndEndSymbols.h"
#include "ELFLinkGraphBuilder.h"
#include "JITLinkGeneric.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/ExecutionEngine/JITLink/i386.h"
#include "llvm/Object/ELFObjectFile.h"

#define DEBUG_TYPE "jitlink"

using namespace llvm;
using namespace llvm::jitlink;

namespace {
constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";

Error buildTables_ELF_i386(LinkGraph &G) {
  LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");

  i386::GOTTableManager GOT;
  i386::PLTTableManager PLT(GOT);
  visitExistingEdges(G, GOT, PLT);
  return Error::success();
}
} // namespace

namespace llvm::jitlink {

class ELFJITLinker_i386 : public JITLinker<ELFJITLinker_i386> {
  friend class JITLinker<ELFJITLinker_i386>;

public:
  ELFJITLinker_i386(std::unique_ptr<JITLinkContext> Ctx,
                    std::unique_ptr<LinkGraph> G, PassConfiguration PassConfig)
      : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {
    getPassConfig().PostAllocationPasses.push_back(
        [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); });
  }

private:
  Symbol *GOTSymbol = nullptr;

  Error getOrCreateGOTSymbol(LinkGraph &G) {
    auto DefineExternalGOTSymbolIfPresent =
        createDefineExternalSectionStartAndEndSymbolsPass(
            [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
              if (Sym.getName() != nullptr &&
                  *Sym.getName() == ELFGOTSymbolName)
                if (auto *GOTSection = G.findSectionByName(
                        i386::GOTTableManager::getSectionName())) {
                  GOTSymbol = &Sym;
                  return {*GOTSection, true};
                }
              return {};
            });

    // Try to attach _GLOBAL_OFFSET_TABLE_ to the GOT if it's defined as an
    // external.
    if (auto Err = DefineExternalGOTSymbolIfPresent(G))
      return Err;

    // If we succeeded then we're done.
    if (GOTSymbol)
      return Error::success();

    // Otherwise look for a GOT section: If it already has a start symbol we'll
    // record it, otherwise we'll create our own.
    // If there's a GOT section but we didn't find an external GOT symbol...
    if (auto *GOTSection =
            G.findSectionByName(i386::GOTTableManager::getSectionName())) {

      // Check for an existing defined symbol.
      for (auto *Sym : GOTSection->symbols())
        if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {
          GOTSymbol = Sym;
          return Error::success();
        }

      // If there's no defined symbol then create one.
      SectionRange SR(*GOTSection);

      if (SR.empty()) {
        GOTSymbol =
            &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,
                                 Linkage::Strong, Scope::Local, true);
      } else {
        GOTSymbol =
            &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
                                Linkage::Strong, Scope::Local, false, true);
      }
    }

    return Error::success();
  }

  Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
    return i386::applyFixup(G, B, E, GOTSymbol);
  }
};

class ELFLinkGraphBuilder_i386 : public ELFLinkGraphBuilder<object::ELF32LE> {
private:
  using ELFT = object::ELF32LE;

  Expected<i386::EdgeKind_i386> getRelocationKind(const uint32_t Type) {
    using namespace i386;
    switch (Type) {
    case ELF::R_386_NONE:
      return EdgeKind_i386::None;
    case ELF::R_386_32:
      return EdgeKind_i386::Pointer32;
    case ELF::R_386_PC32:
      return EdgeKind_i386::PCRel32;
    case ELF::R_386_16:
      return EdgeKind_i386::Pointer16;
    case ELF::R_386_PC16:
      return EdgeKind_i386::PCRel16;
    case ELF::R_386_GOT32:
      return EdgeKind_i386::RequestGOTAndTransformToDelta32FromGOT;
    case ELF::R_386_GOTPC:
      return EdgeKind_i386::Delta32;
    case ELF::R_386_GOTOFF:
      return EdgeKind_i386::Delta32FromGOT;
    case ELF::R_386_PLT32:
      return EdgeKind_i386::BranchPCRel32;
    }

    return make_error<JITLinkError>(
        "In " + G->getName() + ": Unsupported i386 relocation type " +
        object::getELFRelocationTypeName(ELF::EM_386, Type));
  }

  Error addRelocations() override {
    LLVM_DEBUG(dbgs() << "Adding relocations\n");
    using Base = ELFLinkGraphBuilder<ELFT>;
    using Self = ELFLinkGraphBuilder_i386;

    for (const auto &RelSect : Base::Sections) {
      // Validate the section to read relocation entries from.
      if (RelSect.sh_type == ELF::SHT_RELA)
        return make_error<StringError>(
            "No SHT_RELA in valid i386 ELF object files",
            inconvertibleErrorCode());

      if (Error Err = Base::forEachRelRelocation(RelSect, this,
                                                 &Self::addSingleRelocation))
        return Err;
    }

    return Error::success();
  }

  Error addSingleRelocation(const typename ELFT::Rel &Rel,
                            const typename ELFT::Shdr &FixupSection,
                            Block &BlockToFix) {
    using Base = ELFLinkGraphBuilder<ELFT>;

    uint32_t SymbolIndex = Rel.getSymbol(false);
    auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
    if (!ObjSymbol)
      return ObjSymbol.takeError();

    Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
    if (!GraphSymbol)
      return make_error<StringError>(
          formatv("Could not find symbol at given index, did you add it to "
                  "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
                  SymbolIndex, (*ObjSymbol)->st_shndx,
                  Base::GraphSymbols.size()),
          inconvertibleErrorCode());

    Expected<i386::EdgeKind_i386> Kind = getRelocationKind(Rel.getType(false));
    if (!Kind)
      return Kind.takeError();

    auto FixupAddress = orc::ExecutorAddr(FixupSection.sh_addr) + Rel.r_offset;
    int64_t Addend = 0;

    switch (*Kind) {
    case i386::EdgeKind_i386::None:
      break;
    case i386::EdgeKind_i386::Pointer32:
    case i386::EdgeKind_i386::PCRel32:
    case i386::EdgeKind_i386::RequestGOTAndTransformToDelta32FromGOT:
    case i386::EdgeKind_i386::Delta32:
    case i386::EdgeKind_i386::Delta32FromGOT:
    case i386::EdgeKind_i386::BranchPCRel32:
    case i386::EdgeKind_i386::BranchPCRel32ToPtrJumpStub:
    case i386::EdgeKind_i386::BranchPCRel32ToPtrJumpStubBypassable: {
      const char *FixupContent = BlockToFix.getContent().data() +
                                 (FixupAddress - BlockToFix.getAddress());
      Addend = *(const support::little32_t *)FixupContent;
      break;
    }
    case i386::EdgeKind_i386::Pointer16:
    case i386::EdgeKind_i386::PCRel16: {
      const char *FixupContent = BlockToFix.getContent().data() +
                                 (FixupAddress - BlockToFix.getAddress());
      Addend = *(const support::little16_t *)FixupContent;
      break;
    }
    }

    Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
    Edge GE(*Kind, Offset, *GraphSymbol, Addend);
    LLVM_DEBUG({
      dbgs() << "    ";
      printEdge(dbgs(), BlockToFix, GE, i386::getEdgeKindName(*Kind));
      dbgs() << "\n";
    });

    BlockToFix.addEdge(std::move(GE));
    return Error::success();
  }

public:
  ELFLinkGraphBuilder_i386(StringRef FileName, const object::ELFFile<ELFT> &Obj,
                           std::shared_ptr<orc::SymbolStringPool> SSP,
                           Triple TT, SubtargetFeatures Features)
      : ELFLinkGraphBuilder<ELFT>(Obj, std::move(SSP), std::move(TT),
                                  std::move(Features), FileName,
                                  i386::getEdgeKindName) {}
};

Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromELFObject_i386(MemoryBufferRef ObjectBuffer,
                                  std::shared_ptr<orc::SymbolStringPool> SSP) {
  LLVM_DEBUG({
    dbgs() << "Building jitlink graph for new input "
           << ObjectBuffer.getBufferIdentifier() << "...\n";
  });

  auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer);
  if (!ELFObj)
    return ELFObj.takeError();

  auto Features = (*ELFObj)->getFeatures();
  if (!Features)
    return Features.takeError();

  assert((*ELFObj)->getArch() == Triple::x86 &&
         "Only i386 (little endian) is supported for now");

  auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);

  return ELFLinkGraphBuilder_i386((*ELFObj)->getFileName(),
                                  ELFObjFile.getELFFile(), std::move(SSP),
                                  (*ELFObj)->makeTriple(), std::move(*Features))
      .buildGraph();
}

void link_ELF_i386(std::unique_ptr<LinkGraph> G,
                   std::unique_ptr<JITLinkContext> Ctx) {
  PassConfiguration Config;
  const Triple &TT = G->getTargetTriple();
  if (Ctx->shouldAddDefaultTargetPasses(TT)) {
    if (auto MarkLive = Ctx->getMarkLivePass(TT))
      Config.PrePrunePasses.push_back(std::move(MarkLive));
    else
      Config.PrePrunePasses.push_back(markAllSymbolsLive);

    // Add an in-place GOT and PLT build pass.
    Config.PostPrunePasses.push_back(buildTables_ELF_i386);

    // Add GOT/Stubs optimizer pass.
    Config.PreFixupPasses.push_back(i386::optimizeGOTAndStubAccesses);
  }
  if (auto Err = Ctx->modifyPassConfig(*G, Config))
    return Ctx->notifyFailed(std::move(Err));

  ELFJITLinker_i386::link(std::move(Ctx), std::move(G), std::move(Config));
}

} // namespace llvm::jitlink
