65 lines
2 KiB
C++
65 lines
2 KiB
C++
//===--- 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 <memory>
|
|
|
|
#include "DLWrap.h"
|
|
#include "ffi.h"
|
|
|
|
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())
|
|
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)
|
|
return DYNAMIC_FFI_FAIL;
|
|
|
|
*dlwrap::pointer(I) = P;
|
|
}
|
|
|
|
#define DYNAMIC_INIT(SYMBOL) \
|
|
{ \
|
|
void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL); \
|
|
if (!SymbolPtr) \
|
|
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;
|
|
}
|