//===--- 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 #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::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(SymbolPtr); \ } DYNAMIC_INIT(ffi_type_void); DYNAMIC_INIT(ffi_type_pointer); #undef DYNAMIC_INIT return DYNAMIC_FFI_SUCCESS; }