mirror of https://github.com/status-im/evmc.git
loader: Add Windows support
This commit is contained in:
parent
02b52e2926
commit
49e26b1ede
|
@ -25,5 +25,6 @@ build_script: |
|
|||
cmake --build . --config %CONFIGURATION% --target install
|
||||
|
||||
after_build: |
|
||||
C:\projects\evmc\build\test\Release\evmc-test.exe
|
||||
cd C:\projects\evmc\build\test
|
||||
Release\evmc-test.exe
|
||||
C:\install\bin\evmc-vmtester.exe C:\install\bin\evmc-examplevm.dll
|
||||
|
|
|
@ -11,8 +11,6 @@ add_library(
|
|||
add_library(evmc::loader ALIAS loader)
|
||||
set_target_properties(loader PROPERTIES OUTPUT_NAME evmc-loader)
|
||||
target_include_directories(loader PUBLIC $<BUILD_INTERFACE:${include_dir}>$<INSTALL_INTERFACE:include>)
|
||||
if(CMAKE_DL_LIBS)
|
||||
target_link_libraries(loader INTERFACE ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
target_link_libraries(loader INTERFACE ${CMAKE_DL_LIBS})
|
||||
|
||||
install(TARGETS loader EXPORT evmcTargets DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
|
|
@ -8,11 +8,34 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <Windows.h>
|
||||
#define DLL_HANDLE HMODULE
|
||||
#define DLL_OPEN(filename) LoadLibrary(filename)
|
||||
#define DLL_CLOSE(handle) FreeLibrary(handle)
|
||||
#define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn) GetProcAddress(handle, name)
|
||||
#define HAVE_STRCPY_S 1
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#define DLL_HANDLE void*
|
||||
#define DLL_OPEN(filename) dlopen(filename, RTLD_LAZY)
|
||||
#define DLL_CLOSE(handle) dlclose(handle)
|
||||
#define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn)(uintptr_t) dlsym(handle, name)
|
||||
#define HAVE_STRCPY_S 0
|
||||
#endif
|
||||
|
||||
#define PATH_MAX_LENGTH 4096
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
|
||||
#if !HAVE_STRCPY_S
|
||||
static void strcpy_s(char* dest, size_t destsz, const char* src)
|
||||
{
|
||||
size_t len = strlen(src);
|
||||
if (len > destsz - 1)
|
||||
len = destsz - 1;
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct evmc_instance* (*evmc_create_fn)();
|
||||
|
||||
|
@ -34,7 +57,7 @@ struct evmc_instance* evmc_load(const char* filename, enum evmc_loader_error_cod
|
|||
goto exit;
|
||||
}
|
||||
|
||||
void* handle = dlopen(filename, RTLD_LAZY);
|
||||
DLL_HANDLE handle = DLL_OPEN(filename);
|
||||
if (!handle)
|
||||
{
|
||||
ec = EVMC_LOADER_CANNOT_OPEN;
|
||||
|
@ -44,7 +67,7 @@ struct evmc_instance* evmc_load(const char* filename, enum evmc_loader_error_cod
|
|||
const char prefix[] = "evmc_create_";
|
||||
const size_t prefix_length = strlen(prefix);
|
||||
char name[sizeof(prefix) + PATH_MAX_LENGTH];
|
||||
strcpy(name, prefix);
|
||||
strcpy_s(name, sizeof(name), prefix);
|
||||
|
||||
const char* sep_pos = strrchr(filename, '/');
|
||||
const char* name_pos = sep_pos ? sep_pos + 1 : filename;
|
||||
|
@ -54,7 +77,7 @@ struct evmc_instance* evmc_load(const char* filename, enum evmc_loader_error_cod
|
|||
if (strncmp(name_pos, lib_prefix, lib_prefix_length) == 0)
|
||||
name_pos += lib_prefix_length;
|
||||
|
||||
strncpy(name + prefix_length, name_pos, PATH_MAX_LENGTH);
|
||||
strcpy_s(name + prefix_length, PATH_MAX_LENGTH, name_pos);
|
||||
|
||||
char* ext_pos = strrchr(name, '.');
|
||||
if (ext_pos)
|
||||
|
@ -64,26 +87,25 @@ struct evmc_instance* evmc_load(const char* filename, enum evmc_loader_error_cod
|
|||
while ((dash_pos = strchr(dash_pos, '-')) != NULL)
|
||||
*dash_pos++ = '_';
|
||||
|
||||
const void* symbol = dlsym(handle, name);
|
||||
if (!symbol)
|
||||
evmc_create_fn create_fn = DLL_GET_CREATE_FN(handle, name);
|
||||
if (!create_fn)
|
||||
{
|
||||
const char* short_name_pos = strrchr(name, '_');
|
||||
if (short_name_pos)
|
||||
{
|
||||
short_name_pos += 1;
|
||||
memmove(name + prefix_length, short_name_pos, strlen(short_name_pos) + 1);
|
||||
symbol = dlsym(handle, name);
|
||||
create_fn = DLL_GET_CREATE_FN(handle, name);
|
||||
}
|
||||
}
|
||||
|
||||
if (symbol)
|
||||
if (create_fn)
|
||||
{
|
||||
evmc_create_fn create_fn = (evmc_create_fn)(uintptr_t)symbol;
|
||||
instance = create_fn();
|
||||
}
|
||||
else
|
||||
{
|
||||
dlclose(handle);
|
||||
DLL_CLOSE(handle);
|
||||
ec = EVMC_LOADER_SYMBOL_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# Licensed under the MIT License. See the LICENSE file.
|
||||
|
||||
add_library(vm-mock SHARED vm_mock.c)
|
||||
target_link_libraries(vm-mock PRIVATE evmc)
|
||||
|
||||
if(UNIX)
|
||||
set(cmd create_symlink)
|
||||
|
@ -12,14 +13,14 @@ endif()
|
|||
|
||||
add_custom_command(
|
||||
TARGET vm-mock POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> ${CMAKE_SHARED_LIBRARY_PREFIX}aaa${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> double_prefix_aaa.evm
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> double-prefix-aaa.evm
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> eee-bbb.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> ${CMAKE_SHARED_LIBRARY_PREFIX}eee1${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> eee2${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> ${CMAKE_SHARED_LIBRARY_PREFIX}eee3
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE_NAME:vm-mock> eee4
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> libaaa.so
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> double_prefix_aaa.evm
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> double-prefix-aaa.evm
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> eee-bbb.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> libeee1.so
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> eee2.so
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> libeee3.x
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> eee4
|
||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> ../aaa.evm
|
||||
COMMAND ${CMAKE_COMMAND} -E touch empty.file
|
||||
)
|
||||
|
|
|
@ -108,9 +108,10 @@ TEST(loader, eee_bbb)
|
|||
EXPECT_EQ(x, 0xeeebbb);
|
||||
}
|
||||
|
||||
TEST(loader, DISABLED_nextto)
|
||||
#if _WIN32
|
||||
TEST(loader, nextto)
|
||||
{
|
||||
// FIXME: Does not work because dlopen searches only system paths.
|
||||
// On Unix dlopen searches for system libs when the path does not contain "/".
|
||||
|
||||
auto path = "aaa.evm";
|
||||
|
||||
|
@ -122,6 +123,7 @@ TEST(loader, DISABLED_nextto)
|
|||
x = (uintptr_t)evmc_load(path, nullptr);
|
||||
EXPECT_EQ(x, 0xaaa);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(loader, eee1)
|
||||
{
|
||||
|
@ -151,7 +153,7 @@ TEST(loader, eee2)
|
|||
|
||||
TEST(loader, eee3)
|
||||
{
|
||||
auto path = "unittests/libeee3";
|
||||
auto path = "unittests/libeee3.x";
|
||||
|
||||
evmc_loader_error_code ec;
|
||||
auto x = evmc_load(path, &ec);
|
||||
|
@ -162,8 +164,10 @@ TEST(loader, eee3)
|
|||
EXPECT_EQ(x, nullptr);
|
||||
}
|
||||
|
||||
#if !_WIN32
|
||||
TEST(loader, eee4)
|
||||
{
|
||||
// Windows is not loading DLLs without extensions.
|
||||
auto path = "unittests/eee4";
|
||||
|
||||
evmc_loader_error_code ec;
|
||||
|
@ -173,4 +177,5 @@ TEST(loader, eee4)
|
|||
|
||||
x = evmc_load(path, nullptr);
|
||||
EXPECT_EQ(x, nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
* Licensed under the MIT License. See the LICENSE file.
|
||||
*/
|
||||
|
||||
void* evmc_create_aaa()
|
||||
#include <evmc/utils.h>
|
||||
|
||||
EVMC_EXPORT void* evmc_create_aaa()
|
||||
{
|
||||
return (void*)0xaaa;
|
||||
}
|
||||
|
||||
void* evmc_create_eee_bbb()
|
||||
EVMC_EXPORT void* evmc_create_eee_bbb()
|
||||
{
|
||||
return (void*)0xeeebbb;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue