brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · c586ad1 Raw
76 lines · cpp
1//===--- generic-elf-64bit/dynamic_ffi/ffi.cpp -------------------- C++ -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8//9// Implement subset of the FFI api by calling into the FFI library via dlopen10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Support/DynamicLibrary.h"14 15#include "Shared/Debug.h"16#include <memory>17 18#include "DLWrap.h"19#include "ffi.h"20 21DLWRAP_INITIALIZE()22 23DLWRAP(ffi_call, 4);24DLWRAP(ffi_prep_cif, 5);25 26DLWRAP_FINALIZE()27 28ffi_type ffi_type_void;29ffi_type ffi_type_pointer;30 31// Name of the FFI shared library.32constexpr const char *FFI_PATH = "libffi.so";33 34#define DYNAMIC_FFI_SUCCESS 035#define DYNAMIC_FFI_FAIL 136 37// Initializes the dynamic FFI wrapper.38uint32_t ffi_init() {39  std::string ErrMsg;40  auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>(41      llvm::sys::DynamicLibrary::getPermanentLibrary(FFI_PATH, &ErrMsg));42 43  if (!DynlibHandle->isValid()) {44    DP("Unable to load library '%s': %s!\n", FFI_PATH, ErrMsg.c_str());45    return DYNAMIC_FFI_FAIL;46  }47 48  for (size_t I = 0; I < dlwrap::size(); I++) {49    const char *Sym = dlwrap::symbol(I);50 51    void *P = DynlibHandle->getAddressOfSymbol(Sym);52    if (P == nullptr) {53      DP("Unable to find '%s' in '%s'!\n", Sym, FFI_PATH);54      return DYNAMIC_FFI_FAIL;55    }56    DP("Implementing %s with dlsym(%s) -> %p\n", Sym, Sym, P);57 58    *dlwrap::pointer(I) = P;59  }60 61#define DYNAMIC_INIT(SYMBOL)                                                   \62  {                                                                            \63    void *SymbolPtr = DynlibHandle->getAddressOfSymbol(#SYMBOL);               \64    if (!SymbolPtr) {                                                          \65      DP("Unable to find '%s' in '%s'!\n", #SYMBOL, FFI_PATH);                 \66      return DYNAMIC_FFI_FAIL;                                                 \67    }                                                                          \68    SYMBOL = *reinterpret_cast<decltype(SYMBOL) *>(SymbolPtr);                 \69  }70  DYNAMIC_INIT(ffi_type_void);71  DYNAMIC_INIT(ffi_type_pointer);72#undef DYNAMIC_INIT73 74  return DYNAMIC_FFI_SUCCESS;75}76