From 9c707c42050b81b394a6241866872698d8fd94a0 Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Sun, 21 Apr 2024 23:26:15 -0400 Subject: [PATCH] Tests/LibELF: Run LibELF tests on Lagom using Linux runtime linker So that we can be sure Serenity's runtime linker performs the same. --- Meta/Lagom/CMakeLists.txt | 3 ++ Tests/LibELF/CMakeLists.txt | 85 +++++++++++++++++++++++++------------ Tests/LibELF/TestDlOpen.cpp | 6 +-- Tests/LibELF/TestTLS.cpp | 2 +- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 98cbe73627c..dc89743d2a8 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -655,6 +655,9 @@ if (BUILD_LAGOM) list(APPEND TEST_DIRECTORIES LibWeb) list(APPEND TEST_DIRECTORIES LibWebView) endif() + if (LINUX) + list(APPEND TEST_DIRECTORIES LibELF) + endif() foreach (dir IN LISTS TEST_DIRECTORIES) add_serenity_subdirectory("Tests/${dir}") diff --git a/Tests/LibELF/CMakeLists.txt b/Tests/LibELF/CMakeLists.txt index 9579678315c..4b7e434f7c8 100644 --- a/Tests/LibELF/CMakeLists.txt +++ b/Tests/LibELF/CMakeLists.txt @@ -1,14 +1,29 @@ set(CMAKE_SKIP_RPATH FALSE) +if (NOT BUILD_LAGOM) + set(CMAKE_INSTALL_RPATH "$ORIGIN:$ORIGIN/../lib") + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +else() + set(CMAKE_BUILD_RPATH "$ORIGIN:$ORIGIN/../lib") + set(CMAKE_INSTALL_RPATH "$ORIGIN:$ORIGIN/../lib") +endif() macro(add_test_lib NAME FILE) add_library(${NAME} SHARED ${FILE}) - serenity_set_implicit_links(${NAME}) + if (NOT BUILD_LAGOM) + serenity_set_implicit_links(${NAME}) + else() + target_link_libraries(${NAME} PRIVATE AK LibCore) + endif() install(TARGETS ${NAME} DESTINATION usr/Tests/LibELF) endmacro() macro(add_test_exe NAME FILE) add_executable(${NAME} ${FILE}) - serenity_set_implicit_links(${NAME}) + if (NOT BUILD_LAGOM) + serenity_set_implicit_links(${NAME}) + else() + target_link_libraries(${NAME} PRIVATE AK LibCore) + endif() install(TARGETS ${NAME} DESTINATION usr/Tests/LibELF) endmacro() @@ -19,17 +34,12 @@ macro(add_dlopen_lib NAME FUNCTION) target_link_libraries(${NAME} PRIVATE LibLine) endmacro() -add_dlopen_lib(DynlibA dynliba_function) -add_dlopen_lib(DynlibB dynlibb_function) - -add_dlopen_lib(DynlibC dynlibc_function) -set(CMAKE_INSTALL_RPATH $ORIGIN) -add_dlopen_lib(DynlibD dynlibd_function) -target_link_libraries(DynlibD PRIVATE DynlibC) -unset(CMAKE_INSTALL_RPATH) +macro(target_link_manual TARGET LIB) + target_link_libraries(${TARGET} PRIVATE -Wl,--push-state,--no-as-needed $ -Wl,--pop-state) + add_dependencies(${TARGET} ${LIB}) +endmacro() set(TEST_SOURCES - test-elf.cpp TestDlOpen.cpp TestOrder.cpp TestTLS.cpp @@ -37,35 +47,58 @@ set(TEST_SOURCES ) foreach(source IN LISTS TEST_SOURCES) - serenity_test("${source}" LibELF) + if (NOT BUILD_LAGOM) + serenity_test("${source}" LibELF) + else() + get_filename_component(test_name ${source} NAME_WE) + lagom_test("${source}" WORKING_DIRECTORY "$") + # FIXME: Figure out why on Ubuntu 22.04 dlopen ignores RUNPATH in executable. + set_tests_properties(${test_name} PROPERTIES ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() endforeach() +# test-elf.cpp +if (NOT BUILD_LAGOM) + serenity_test(test-elf.cpp LibELF) +endif() + +# TestDlOpen.cpp +add_dlopen_lib(DynlibA dynliba_function) +add_dlopen_lib(DynlibB dynlibb_function) + +add_dlopen_lib(DynlibC dynlibc_function) +add_dlopen_lib(DynlibD dynlibd_function) +target_link_manual(DynlibD DynlibC) + +# TestTLS.cpp add_test_lib(TLSDef TLSDef.cpp) add_test_lib(TLSUse TLSUse.cpp) target_compile_options(TLSUse PRIVATE -ftls-model=global-dynamic) target_link_libraries(TLSUse PRIVATE LibCore LibTest LibThreading TLSDef) -set_target_properties(TLSUse PROPERTIES INSTALL_RPATH "$ORIGIN") target_link_libraries(TestTLS PRIVATE TLSUse) -set_target_properties(TestTLS PROPERTIES INSTALL_RPATH "$ORIGIN") +# TestWeakSymbolResolution.cpp add_test_lib(TestWeakSymbolResolution1 TestWeakSymbolResolution1.cpp) add_test_lib(TestWeakSymbolResolution2 TestWeakSymbolResolution2.cpp) -target_link_libraries(TestWeakSymbolResolution PRIVATE TestWeakSymbolResolution1 TestWeakSymbolResolution2) -set_target_properties(TestWeakSymbolResolution PROPERTIES INSTALL_RPATH "$ORIGIN") +target_link_manual(TestWeakSymbolResolution TestWeakSymbolResolution1) +target_link_manual(TestWeakSymbolResolution TestWeakSymbolResolution2) +# TestOrder.cpp add_test_lib(TestOrderLib1 TestOrderLib1.cpp) add_test_lib(TestOrderLib2 TestOrderLib2.cpp) -target_link_libraries(TestOrderLib2 PRIVATE TestOrderLib1) -set_target_properties(TestOrderLib2 PROPERTIES INSTALL_RPATH "$ORIGIN") +target_link_manual(TestOrderLib2 TestOrderLib1) -# NOTE: This is so ugly because CMake sorts targets supplied to target_link_libraries. -# .elf extension here avoids direct invocations by SerenityOS's test runner. add_test_exe(TestOrderExe1.elf TestOrderExe.cpp) -target_link_libraries(TestOrderExe1.elf PRIVATE $ $) -add_dependencies(TestOrderExe1.elf TestOrderLib1 TestOrderLib2) -set_target_properties(TestOrderExe1.elf PROPERTIES INSTALL_RPATH "$ORIGIN") +target_link_manual(TestOrderExe1.elf TestOrderLib1) +target_link_manual(TestOrderExe1.elf TestOrderLib2) add_test_exe(TestOrderExe2.elf TestOrderExe.cpp) -target_link_libraries(TestOrderExe2.elf PRIVATE $ $) -add_dependencies(TestOrderExe2.elf TestOrderLib1 TestOrderLib2) -set_target_properties(TestOrderExe2.elf PROPERTIES INSTALL_RPATH "$ORIGIN") +target_link_manual(TestOrderExe2.elf TestOrderLib2) +target_link_manual(TestOrderExe2.elf TestOrderLib1) + +add_dependencies(TestOrder + TestOrderLib1 + TestOrderLib2 + TestOrderExe1.elf + TestOrderExe2.elf +) diff --git a/Tests/LibELF/TestDlOpen.cpp b/Tests/LibELF/TestDlOpen.cpp index cb4692fe222..3d9771784f9 100644 --- a/Tests/LibELF/TestDlOpen.cpp +++ b/Tests/LibELF/TestDlOpen.cpp @@ -9,9 +9,9 @@ TEST_CASE(test_dlopen) { - auto liba = dlopen("/usr/Tests/LibELF/libDynlibA.so", 0); + auto liba = dlopen("libDynlibA.so", RTLD_LAZY | RTLD_GLOBAL); EXPECT_NE(liba, nullptr); - auto libb = dlopen("/usr/Tests/LibELF/libDynlibB.so", 0); + auto libb = dlopen("libDynlibB.so", RTLD_LAZY | RTLD_GLOBAL); EXPECT_NE(libb, nullptr); typedef int (*dynlib_func_t)(); @@ -26,7 +26,7 @@ TEST_CASE(test_dlopen) TEST_CASE(test_dlsym_rtld_default) { - auto libd = dlopen("/usr/Tests/LibELF/libDynlibD.so", 0); + auto libd = dlopen("libDynlibD.so", RTLD_LAZY | RTLD_GLOBAL); EXPECT_NE(libd, nullptr); if (libd == nullptr) { warnln("can't open libDynlibD.so, {}", dlerror()); diff --git a/Tests/LibELF/TestTLS.cpp b/Tests/LibELF/TestTLS.cpp index fe7e5507547..5391d4374db 100644 --- a/Tests/LibELF/TestTLS.cpp +++ b/Tests/LibELF/TestTLS.cpp @@ -17,7 +17,7 @@ TEST_CASE(basic) TEST_CASE(local_exec) { - [[gnu::tls_model("local-exec")]] static volatile __thread char test1[PAGE_SIZE * 4 + 10]; + [[gnu::tls_model("local-exec")]] static volatile __thread char test1[4096 * 4 + 10]; for (size_t i = 0; i < sizeof(test1); i++) { test1[i] = static_cast(i);