//===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- 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
//
//===----------------------------------------------------------------------===//
//
// Contains the definition for an JITLink-based, in-process object linking
// layer.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cassert>
#include <functional>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>

namespace llvm {

namespace jitlink {
class EHFrameRegistrar;
} // namespace jitlink

namespace object {
class ObjectFile;
} // namespace object

namespace orc {

class ObjectLinkingLayerJITLinkContext;

/// An ObjectLayer implementation built on JITLink.
///
/// Clients can use this class to add relocatable object files to an
/// ExecutionSession, and it typically serves as the base layer (underneath
/// a compiling layer like IRCompileLayer) for the rest of the JIT.
class ObjectLinkingLayer : public ObjectLayer {
  friend class ObjectLinkingLayerJITLinkContext;

public:
  /// Plugin instances can be added to the ObjectLinkingLayer to receive
  /// callbacks when code is loaded or emitted, and when JITLink is being
  /// configured.
  class Plugin {
  public:
    virtual ~Plugin();
    virtual void modifyPassConfig(MaterializationResponsibility &MR,
                                  const Triple &TT,
                                  jitlink::PassConfiguration &Config) {}
    virtual void notifyLoaded(MaterializationResponsibility &MR) {}
    virtual Error notifyEmitted(MaterializationResponsibility &MR) {
      return Error::success();
    }
    virtual Error notifyRemovingModule(VModuleKey K) {
      return Error::success();
    }
    virtual Error notifyRemovingAllModules() { return Error::success(); }
  };

  using ReturnObjectBufferFunction =
      std::function<void(std::unique_ptr<MemoryBuffer>)>;

  /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
  /// and NotifyEmitted functors.
  ObjectLinkingLayer(ExecutionSession &ES,
                     std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);

  /// Destruct an ObjectLinkingLayer.
  ~ObjectLinkingLayer();

  /// Set an object buffer return function. By default object buffers are
  /// deleted once the JIT has linked them. If a return function is set then
  /// it will be called to transfer ownership of the buffer instead.
  void setReturnObjectBuffer(ReturnObjectBufferFunction ReturnObjectBuffer) {
    this->ReturnObjectBuffer = std::move(ReturnObjectBuffer);
  }

  /// Add a pass-config modifier.
  ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
    std::lock_guard<std::mutex> Lock(LayerMutex);
    Plugins.push_back(std::move(P));
    return *this;
  }

  /// Emit the object.
  void emit(MaterializationResponsibility R,
            std::unique_ptr<MemoryBuffer> O) override;

  /// Instructs this ObjectLinkingLayer instance to override the symbol flags
  /// found in the AtomGraph with the flags supplied by the
  /// MaterializationResponsibility instance. This is a workaround to support
  /// symbol visibility in COFF, which does not use the libObject's
  /// SF_Exported flag. Use only when generating / adding COFF object files.
  ///
  /// FIXME: We should be able to remove this if/when COFF properly tracks
  /// exported symbols.
  ObjectLinkingLayer &
  setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
    this->OverrideObjectFlags = OverrideObjectFlags;
    return *this;
  }

  /// If set, this ObjectLinkingLayer instance will claim responsibility
  /// for any symbols provided by a given object file that were not already in
  /// the MaterializationResponsibility instance. Setting this flag allows
  /// higher-level program representations (e.g. LLVM IR) to be added based on
  /// only a subset of the symbols they provide, without having to write
  /// intervening layers to scan and add the additional symbols. This trades
  /// diagnostic quality for convenience however: If all symbols are enumerated
  /// up-front then clashes can be detected and reported early (and usually
  /// deterministically). If this option is set, clashes for the additional
  /// symbols may not be detected until late, and detection may depend on
  /// the flow of control through JIT'd code. Use with care.
  ObjectLinkingLayer &
  setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
    this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
    return *this;
  }

private:
  using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;

  void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
                        jitlink::PassConfiguration &PassConfig);
  void notifyLoaded(MaterializationResponsibility &MR);
  Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);

  Error removeModule(VModuleKey K);
  Error removeAllModules();

  mutable std::mutex LayerMutex;
  std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr;
  bool OverrideObjectFlags = false;
  bool AutoClaimObjectSymbols = false;
  ReturnObjectBufferFunction ReturnObjectBuffer;
  DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
  std::vector<AllocPtr> UntrackedAllocs;
  std::vector<std::unique_ptr<Plugin>> Plugins;
};

class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
public:
  EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
  Error notifyEmitted(MaterializationResponsibility &MR) override;
  void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
                        jitlink::PassConfiguration &PassConfig) override;
  Error notifyRemovingModule(VModuleKey K) override;
  Error notifyRemovingAllModules() override;

private:

  struct EHFrameRange {
    JITTargetAddress Addr = 0;
    size_t Size;
  };

  jitlink::EHFrameRegistrar &Registrar;
  DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
  DenseMap<VModuleKey, EHFrameRange> TrackedEHFrameRanges;
  std::vector<EHFrameRange> UntrackedEHFrameRanges;
};

} // end namespace orc
} // end namespace llvm

#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
