//===------- UnwindInfoManager.cpp - Register unwind info sections --------===//
//
// 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/TargetProcess/UnwindInfoManager.h"
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"

#ifdef __APPLE__
#include <dlfcn.h>
#endif // __APPLE__

#define DEBUG_TYPE "orc"

using namespace llvm;
using namespace llvm::orc;
using namespace llvm::orc::shared;

static orc::shared::CWrapperFunctionResult
llvm_orc_rt_alt_UnwindInfoManager_register(const char *ArgData,
                                           size_t ArgSize) {
  using SPSSig = SPSError(SPSSequence<SPSExecutorAddrRange>, SPSExecutorAddr,
                          SPSExecutorAddrRange, SPSExecutorAddrRange);

  return WrapperFunction<SPSSig>::handle(
             ArgData, ArgSize,
             [](std::vector<ExecutorAddrRange> CodeRanges, ExecutorAddr DSOBase,
                ExecutorAddrRange DWARFRange,
                ExecutorAddrRange CompactUnwindRange) {
               return UnwindInfoManager::registerSections(
                   CodeRanges, DSOBase, DWARFRange, CompactUnwindRange);
             })
      .release();
}

static orc::shared::CWrapperFunctionResult
llvm_orc_rt_alt_UnwindInfoManager_deregister(const char *ArgData,
                                             size_t ArgSize) {
  using SPSSig = SPSError(SPSSequence<SPSExecutorAddrRange>);

  return WrapperFunction<SPSSig>::handle(
             ArgData, ArgSize,
             [](std::vector<ExecutorAddrRange> CodeRanges) {
               return UnwindInfoManager::deregisterSections(CodeRanges);
             })
      .release();
}

namespace llvm::orc {

[[maybe_unused]] static const char *AddFnName =
    "__unw_add_find_dynamic_unwind_sections";
[[maybe_unused]] static const char *RemoveFnName =
    "__unw_remove_find_dynamic_unwind_sections";
static std::unique_ptr<UnwindInfoManager> Instance;
static int (*RemoveFindDynamicUnwindSections)(void *) = nullptr;

UnwindInfoManager::~UnwindInfoManager() {
  if (int Err = RemoveFindDynamicUnwindSections((void *)&findSections)) {
    (void)Err; // Silence unused variable warning in release builds.
    LLVM_DEBUG({
      dbgs() << "Failed call to " << RemoveFnName << ": error = " << Err
             << "\n";
    });
    (void)Err;
  }
}

bool UnwindInfoManager::TryEnable() {
#ifdef __APPLE__
  static std::mutex M;
  std::lock_guard<std::mutex> Lock(M);

  if (Instance)
    return true;

  auto AddFn = (int (*)(void *))dlsym(RTLD_DEFAULT, AddFnName);
  if (!AddFn)
    return false;

  auto RemoveFn = (int (*)(void *))dlsym(RTLD_DEFAULT, RemoveFnName);
  if (!RemoveFn)
    return false;

  Instance.reset(new UnwindInfoManager());

  if (auto Err = AddFn((void *)&findSections)) {
    (void)Err; // Silence unused variable warning in release builds.
    LLVM_DEBUG({
      dbgs() << "Failed call to " << AddFnName << ": error = " << Err << "\n";
    });
    Instance = nullptr;
    return false;
  }

  RemoveFindDynamicUnwindSections = RemoveFn;
  return true;

#else
  return false;
#endif // __APPLE__
}

void UnwindInfoManager::addBootstrapSymbols(StringMap<ExecutorAddr> &M) {
  M[rt_alt::UnwindInfoManagerRegisterActionName] =
      ExecutorAddr::fromPtr(llvm_orc_rt_alt_UnwindInfoManager_register);
  M[rt_alt::UnwindInfoManagerDeregisterActionName] =
      ExecutorAddr::fromPtr(llvm_orc_rt_alt_UnwindInfoManager_deregister);
}

Error UnwindInfoManager::registerSections(
    ArrayRef<orc::ExecutorAddrRange> CodeRanges, orc::ExecutorAddr DSOBase,
    orc::ExecutorAddrRange DWARFEHFrame, orc::ExecutorAddrRange CompactUnwind) {
  return Instance->registerSectionsImpl(CodeRanges, DSOBase, DWARFEHFrame,
                                        CompactUnwind);
}

Error UnwindInfoManager::deregisterSections(
    ArrayRef<orc::ExecutorAddrRange> CodeRanges) {
  return Instance->deregisterSectionsImpl(CodeRanges);
}

int UnwindInfoManager::findSectionsImpl(uintptr_t Addr, UnwindSections *Info) {
  std::lock_guard<std::mutex> Lock(M);
  auto I = UWSecs.upper_bound(Addr);
  if (I == UWSecs.begin())
    return 0;
  --I;
  *Info = I->second;
  return 1;
}

int UnwindInfoManager::findSections(uintptr_t Addr, UnwindSections *Info) {
  return Instance->findSectionsImpl(Addr, Info);
}

Error UnwindInfoManager::registerSectionsImpl(
    ArrayRef<ExecutorAddrRange> CodeRanges, ExecutorAddr DSOBase,
    ExecutorAddrRange DWARFEHFrame, ExecutorAddrRange CompactUnwind) {
  std::lock_guard<std::mutex> Lock(M);
  for (auto &R : CodeRanges)
    UWSecs[R.Start.getValue()] =
        UnwindSections{static_cast<uintptr_t>(DSOBase.getValue()),
                       static_cast<uintptr_t>(DWARFEHFrame.Start.getValue()),
                       static_cast<size_t>(DWARFEHFrame.size()),
                       static_cast<uintptr_t>(CompactUnwind.Start.getValue()),
                       static_cast<size_t>(CompactUnwind.size())};
  return Error::success();
}

Error UnwindInfoManager::deregisterSectionsImpl(
    ArrayRef<ExecutorAddrRange> CodeRanges) {
  std::lock_guard<std::mutex> Lock(M);
  for (auto &R : CodeRanges) {
    auto I = UWSecs.find(R.Start.getValue());
    if (I == UWSecs.end())
      return make_error<StringError>(
          "No unwind-info sections registered for range " +
              formatv("{0:x} - {1:x}", R.Start, R.End),
          inconvertibleErrorCode());
    UWSecs.erase(I);
  }
  return Error::success();
}

} // namespace llvm::orc
