diff --git a/CI/FEXLinuxTestsThunks.json b/CI/FEXLinuxTestsThunks.json new file mode 100644 index 0000000000..bee8f675ff --- /dev/null +++ b/CI/FEXLinuxTestsThunks.json @@ -0,0 +1,5 @@ +{ + "ThunksDB": { + "fex_thunk_test": 1 + } +} diff --git a/Data/ThunksDB.json b/Data/ThunksDB.json index e53dbee8d0..4ae9b592a8 100644 --- a/Data/ThunksDB.json +++ b/Data/ThunksDB.json @@ -144,6 +144,12 @@ "@PREFIX_LIB@/libasound.so.2.0.0" ] }, + "fex_thunk_test": { + "Library": "libfex_thunk_test-guest.so", + "Overlay": [ + "@PREFIX_LIB@/libfex_thunk_test.so" + ] + }, "Xrender": { "Library": "libXrender-guest.so", "Overlay": [ diff --git a/ThunkLibs/GuestLibs/CMakeLists.txt b/ThunkLibs/GuestLibs/CMakeLists.txt index 431f998818..69223e8a4d 100644 --- a/ThunkLibs/GuestLibs/CMakeLists.txt +++ b/ThunkLibs/GuestLibs/CMakeLists.txt @@ -291,3 +291,6 @@ if (BITNESS EQUAL 32) # 338: 0f 0b ud2 target_compile_options(VDSO-guest PRIVATE "-fno-pic") endif() + +generate(libfex_thunk_test ${CMAKE_CURRENT_SOURCE_DIR}/../libfex_thunk_test/libfex_thunk_test_interface.cpp) +add_guest_lib(fex_thunk_test "libfex_thunk_test.so") diff --git a/ThunkLibs/HostLibs/CMakeLists.txt b/ThunkLibs/HostLibs/CMakeLists.txt index 33471a9a6f..cc2a5dceef 100644 --- a/ThunkLibs/HostLibs/CMakeLists.txt +++ b/ThunkLibs/HostLibs/CMakeLists.txt @@ -186,4 +186,10 @@ foreach(GUEST_BITNESS IN LISTS BITNESS_LIST) target_include_directories(libdrm-${GUEST_BITNESS}-deps INTERFACE /usr/include/drm/) target_include_directories(libdrm-${GUEST_BITNESS}-deps INTERFACE /usr/include/libdrm/) add_host_lib(drm ${GUEST_BITNESS}) + + generate(libfex_thunk_test ${CMAKE_CURRENT_SOURCE_DIR}/../libfex_thunk_test/libfex_thunk_test_interface.cpp ${GUEST_BITNESS}) + add_host_lib(fex_thunk_test ${GUEST_BITNESS}) endforeach() + +add_library(fex_thunk_test SHARED ../libfex_thunk_test/lib.cpp) +install(TARGETS fex_thunk_test LIBRARY DESTINATION lib COMPONENT TestLibraries) diff --git a/ThunkLibs/libfex_thunk_test/Guest.cpp b/ThunkLibs/libfex_thunk_test/Guest.cpp new file mode 100644 index 0000000000..d9a0ed6f93 --- /dev/null +++ b/ThunkLibs/libfex_thunk_test/Guest.cpp @@ -0,0 +1,12 @@ +/* +$info$ +tags: thunklibs|fex_thunk_test +$end_info$ +*/ + +#include "common/Guest.h" +#include "api.h" + +#include "thunkgen_guest_libfex_thunk_test.inl" + +LOAD_LIB(libfex_thunk_test) diff --git a/ThunkLibs/libfex_thunk_test/Host.cpp b/ThunkLibs/libfex_thunk_test/Host.cpp new file mode 100644 index 0000000000..ab90519145 --- /dev/null +++ b/ThunkLibs/libfex_thunk_test/Host.cpp @@ -0,0 +1,16 @@ +/* +$info$ +tags: thunklibs|fex_thunk_test +$end_info$ +*/ + +#include +#include + +#include "common/Host.h" + +#include "api.h" + +#include "thunkgen_host_libfex_thunk_test.inl" + +EXPORTS(libfex_thunk_test) diff --git a/ThunkLibs/libfex_thunk_test/api.h b/ThunkLibs/libfex_thunk_test/api.h new file mode 100644 index 0000000000..293ba29451 --- /dev/null +++ b/ThunkLibs/libfex_thunk_test/api.h @@ -0,0 +1,13 @@ +/** + * This file defines interfaces of a dummy library used to test various + * features of the thunk generator. + */ +#pragma once + +#include + +extern "C" { + +uint32_t GetDoubledValue(uint32_t); + +} diff --git a/ThunkLibs/libfex_thunk_test/lib.cpp b/ThunkLibs/libfex_thunk_test/lib.cpp new file mode 100644 index 0000000000..2e6354b8e1 --- /dev/null +++ b/ThunkLibs/libfex_thunk_test/lib.cpp @@ -0,0 +1,9 @@ +#include "api.h" + +extern "C" { + +uint32_t GetDoubledValue(uint32_t input) { + return 2 * input; +} + +} // extern "C" diff --git a/ThunkLibs/libfex_thunk_test/libfex_thunk_test_interface.cpp b/ThunkLibs/libfex_thunk_test/libfex_thunk_test_interface.cpp new file mode 100644 index 0000000000..7fedaa415d --- /dev/null +++ b/ThunkLibs/libfex_thunk_test/libfex_thunk_test_interface.cpp @@ -0,0 +1,14 @@ +#include + +#include "api.h" + +template +struct fex_gen_config {}; + +template +struct fex_gen_type {}; + +template +struct fex_gen_param {}; + +template<> struct fex_gen_config {}; diff --git a/unittests/FEXLinuxTests/CMakeLists.txt b/unittests/FEXLinuxTests/CMakeLists.txt index 4fbb0d5725..602c46057e 100644 --- a/unittests/FEXLinuxTests/CMakeLists.txt +++ b/unittests/FEXLinuxTests/CMakeLists.txt @@ -44,6 +44,16 @@ function(AddTests Tests BinDirectory Bitness) set(BIN_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BinDirectory}/${TEST_NAME}.${Bitness}") set(TEST_CASE "${TEST_NAME}.${Bitness}") + set(THUNK_ARGS "") + if(TEST_NAME STREQUAL "thunk_testlib") + # Test thunking only if thunks are enabled and supported + if(NOT BUILD_THUNKS OR ENABLE_GLIBC_ALLOCATOR_HOOK_FAULT) + continue() + endif() + + set(THUNK_ARGS "-k" "${CMAKE_SOURCE_DIR}/CI/FEXLinuxTestsThunks.json") + endif() + # Add jit test case add_test(NAME "${TEST_CASE}.jit.flt" COMMAND "python3" "${CMAKE_SOURCE_DIR}/Scripts/guest_test_runner.py" @@ -54,9 +64,11 @@ function(AddTests Tests BinDirectory Bitness) "${TEST_CASE}" "guest" "$" + ${THUNK_ARGS} "--no-silent" "-c" "irjit" "-n" "500" "--" "${BIN_PATH}") - if (_M_X86_64) + + if (_M_X86_64 AND NOT TEST_NAME STREQUAL "thunk_testlib") # Add host test case add_test(NAME "${TEST_CASE}.host.flt" COMMAND "python3" "${CMAKE_SOURCE_DIR}/Scripts/guest_test_runner.py" @@ -79,6 +91,12 @@ AddTests("${TESTS_64_ONLY}" "FEXLinuxTests_64" 64) # Execute tests that are only 32-bit. AddTests("${TESTS_32_ONLY}" "FEXLinuxTests_32" 32) +if(TEST thunk_testlib.64.jit.flt) + # Ensure libfex_thunk_test is found even when using an uncommon install prefix + set_property(TEST "thunk_testlib.32.jit.flt" PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX}/lib") + set_property(TEST "thunk_testlib.64.jit.flt" PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX}/lib") +endif() + execute_process(COMMAND "nproc" OUTPUT_VARIABLE CORES) string(STRIP ${CORES} CORES) diff --git a/unittests/FEXLinuxTests/tests/CMakeLists.txt b/unittests/FEXLinuxTests/tests/CMakeLists.txt index 21c29c69f1..2669855b96 100644 --- a/unittests/FEXLinuxTests/tests/CMakeLists.txt +++ b/unittests/FEXLinuxTests/tests/CMakeLists.txt @@ -3,8 +3,8 @@ project(FEXLinuxTests) set(CMAKE_CXX_STANDARD 17) -unset (CMAKE_C_FLAGS) -unset (CMAKE_CXX_FLAGS) +unset(CMAKE_C_FLAGS) +unset(CMAKE_CXX_FLAGS) set(GENERATE_GUEST_INSTALL_TARGETS TRUE) @@ -40,4 +40,6 @@ target_link_libraries(smc-shared-1.${BITNESS} PRIVATE rt pthread) target_link_libraries(smc-shared-2.${BITNESS} PRIVATE rt pthread) +target_link_libraries(thunk_testlib.${BITNESS} PRIVATE ${CMAKE_DL_LIBS}) + target_link_libraries(timer-sigev-thread.${BITNESS} PRIVATE rt pthread) diff --git a/unittests/FEXLinuxTests/tests/thunks/thunk_testlib.cpp b/unittests/FEXLinuxTests/tests/thunks/thunk_testlib.cpp new file mode 100644 index 0000000000..4fc742db2f --- /dev/null +++ b/unittests/FEXLinuxTests/tests/thunks/thunk_testlib.cpp @@ -0,0 +1,24 @@ +#include + +#include + +#include + +#include "../../../../ThunkLibs/libfex_thunk_test/api.h" + +struct Fixture { + void* lib = []() { + auto ret = dlopen("libfex_thunk_test.so", RTLD_LAZY); + if (!ret) { + throw std::runtime_error("Failed to open lib\n"); + } + return ret; + }(); + +#define GET_SYMBOL(name) decltype(&::name) name = (decltype(name))dlsym(lib, #name) + GET_SYMBOL(GetDoubledValue); +}; + +TEST_CASE_METHOD(Fixture, "Trivial") { + CHECK(GetDoubledValue(10) == 20); +}