blob: 8e3d963f2e7dcb2535a01cb6d551ac603a0c99c1 [file] [log] [blame] [edit]
//===--- generic-elf-64bit/dynamic_ffi/ffi.cpp -------------------- 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
//
//===----------------------------------------------------------------------===//
//
// Implement subset of the FFI api by calling into the FFI library via dlopen
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/DynamicLibrary.h"
#include "Shared/Debug.h"
#include <memory>
#include "DLWrap.h"
#include "ffi.h"
using namespace llvm::omp::target::debug;
DLWRAP_INITIALIZE()
DLWRAP(ffi_call, 4);
DLWRAP(ffi_prep_cif, 5);
DLWRAP_FINALIZE()
ffi_type ffi_type_void;
ffi_type ffi_type_pointer;
// Name of the FFI shared library.
constexpr const char *FFI_PATH = "libffi.so";
#define DYNAMIC_FFI_SUCCESS 0
#define DYNAMIC_FFI_FAIL 1
// Initializes the dynamic FFI wrapper.
uint32_t ffi_init() {
std::string ErrMsg;
auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>(
llvm::sys::DynamicLibrary::getPermanentLibrary(FFI_PATH, &ErrMsg));
if (!DynlibHandle->isValid()) {
ODBG(ODT_Init) << "Unable to load library '" << FFI_PATH << "': " << ErrMsg
<< "!";
return DYNAMIC_FFI_FAIL;
}
for (size_t I = 0; I < dlwrap::size(); I++) {
const char *Sym = dlwrap::symbol(I);
void *P = DynlibHandle->getAddressOfSymbol(Sym);
if (P == nullptr) {
ODBG(ODT_Init) << "Unable to find '" << Sym << "' in '" << FFI_PATH
<< "'!";
return DYNAMIC_FFI_FAIL;
}
ODBG(ODT_Init) << "Implementing " << Sym << " with dlsym(" << Sym << ") -> "
<< P;
*dlwrap::pointer(I) = P;
}
#define DYNAMIC_INIT(SYMBOL) \
{ \
void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL); \
if (!SymbolPtr) { \
ODBG(ODT_Init) << "Unable to find '" << #SYMBOL << "' in '" << FFI_PATH \
<< "'!"; \
return DYNAMIC_FFI_FAIL; \
} \
SYMBOL = *reinterpret_cast<decltype(SYMBOL) *>(SymbolPtr); \
}
DYNAMIC_INIT(ffi_type_void);
DYNAMIC_INIT(ffi_type_pointer);
#undef DYNAMIC_INIT
return DYNAMIC_FFI_SUCCESS;
}