1 //===--- generic-elf-64bit/dynamic_ffi/ffi.cpp -------------------- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Implement subset of the FFI api by calling into the FFI library via dlopen
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Support/DynamicLibrary.h"
15 #include "Shared/Debug.h"
24 DLWRAP(ffi_prep_cif
, 5);
28 ffi_type ffi_type_void
;
29 ffi_type ffi_type_pointer
;
31 // Name of the FFI shared library.
32 constexpr const char *FFI_PATH
= "libffi.so";
34 #define DYNAMIC_FFI_SUCCESS 0
35 #define DYNAMIC_FFI_FAIL 1
37 // Initializes the dynamic FFI wrapper.
40 auto DynlibHandle
= std::make_unique
<llvm::sys::DynamicLibrary
>(
41 llvm::sys::DynamicLibrary::getPermanentLibrary(FFI_PATH
, &ErrMsg
));
43 if (!DynlibHandle
->isValid()) {
44 DP("Unable to load library '%s': %s!\n", FFI_PATH
, ErrMsg
.c_str());
45 return DYNAMIC_FFI_FAIL
;
48 for (size_t I
= 0; I
< dlwrap::size(); I
++) {
49 const char *Sym
= dlwrap::symbol(I
);
51 void *P
= DynlibHandle
->getAddressOfSymbol(Sym
);
53 DP("Unable to find '%s' in '%s'!\n", Sym
, FFI_PATH
);
54 return DYNAMIC_FFI_FAIL
;
56 DP("Implementing %s with dlsym(%s) -> %p\n", Sym
, Sym
, P
);
58 *dlwrap::pointer(I
) = P
;
61 #define DYNAMIC_INIT(SYMBOL) \
63 void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL); \
65 DP("Unable to find '%s' in '%s'!\n", #SYMBOL, FFI_PATH); \
66 return DYNAMIC_FFI_FAIL; \
68 SYMBOL = *reinterpret_cast<decltype(SYMBOL) *>(SymbolPtr); \
70 DYNAMIC_INIT(ffi_type_void
);
71 DYNAMIC_INIT(ffi_type_pointer
);
74 return DYNAMIC_FFI_SUCCESS
;