//===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===//
//
// 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/LazyObjectLinkingLayer.h"

#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/RedirectionManager.h"

using namespace llvm;
using namespace llvm::jitlink;

namespace {

constexpr StringRef FnBodySuffix = "$orc_fnbody";

} // anonymous namespace

namespace llvm::orc {

class LazyObjectLinkingLayer::RenamerPlugin
    : public ObjectLinkingLayer::Plugin {
public:
  void modifyPassConfig(MaterializationResponsibility &MR,
                        jitlink::LinkGraph &LG,
                        jitlink::PassConfiguration &Config) override {
    // We need to insert this before the mark-live pass to ensure that we don't
    // delete the bodies (their names won't match the responsibility set until
    // after this pass completes.
    Config.PrePrunePasses.insert(
        Config.PrePrunePasses.begin(),
        [&MR](LinkGraph &G) { return renameFunctionBodies(G, MR); });
  }

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

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

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

private:
  static Error renameFunctionBodies(LinkGraph &G,
                                    MaterializationResponsibility &MR) {
    DenseMap<StringRef, NonOwningSymbolStringPtr> SymsToRename;
    for (auto &[Name, Flags] : MR.getSymbols())
      if ((*Name).ends_with(FnBodySuffix))
        SymsToRename[(*Name).drop_back(FnBodySuffix.size())] =
            NonOwningSymbolStringPtr(Name);

    for (auto *Sym : G.defined_symbols()) {
      if (!Sym->hasName())
        continue;
      auto I = SymsToRename.find(Sym->getName());
      if (I == SymsToRename.end())
        continue;
      Sym->setName(G.allocateName(*I->second));
    }

    return Error::success();
  }
};

LazyObjectLinkingLayer::LazyObjectLinkingLayer(ObjectLinkingLayer &BaseLayer,
                                               LazyCallThroughManager &LCTMgr,
                                               RedirectableSymbolManager &RSMgr)
    : ObjectLayer(BaseLayer.getExecutionSession()), BaseLayer(BaseLayer),
      LCTMgr(LCTMgr), RSMgr(RSMgr) {
  BaseLayer.addPlugin(std::make_unique<RenamerPlugin>());
}

Error LazyObjectLinkingLayer::add(ResourceTrackerSP RT,
                                  std::unique_ptr<MemoryBuffer> O,
                                  MaterializationUnit::Interface I) {

  // Object files with initializer symbols can't be lazy.
  if (I.InitSymbol)
    return BaseLayer.add(std::move(RT), std::move(O), std::move(I));

  auto &ES = getExecutionSession();
  SymbolAliasMap LazySymbols;
  for (auto &[Name, Flags] : I.SymbolFlags)
    if (Flags.isCallable())
      LazySymbols[Name] = {ES.intern((*Name + FnBodySuffix).str()), Flags};

  for (auto &[Name, AI] : LazySymbols) {
    I.SymbolFlags.erase(Name);
    I.SymbolFlags[AI.Aliasee] = AI.AliasFlags;
  }

  if (auto Err = BaseLayer.add(RT, std::move(O), std::move(I)))
    return Err;

  auto &JD = RT->getJITDylib();
  return JD.define(lazyReexports(LCTMgr, RSMgr, JD, std::move(LazySymbols)),
                   std::move(RT));
}

void LazyObjectLinkingLayer::emit(
    std::unique_ptr<MaterializationResponsibility> MR,
    std::unique_ptr<MemoryBuffer> Obj) {
  return BaseLayer.emit(std::move(MR), std::move(Obj));
}

} // namespace llvm::orc
