diff --git a/Tests/LibELF/CMakeLists.txt b/Tests/LibELF/CMakeLists.txt index 6baeb7c375a..64140637e96 100644 --- a/Tests/LibELF/CMakeLists.txt +++ b/Tests/LibELF/CMakeLists.txt @@ -29,6 +29,7 @@ set(TEST_SOURCES test-elf.cpp TestDlOpen.cpp TestTLS.cpp + TestWeakSymbolResolution.cpp ) foreach(source IN LISTS TEST_SOURCES) @@ -42,3 +43,8 @@ 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") + +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") diff --git a/Tests/LibELF/TestWeakSymbolResolution.cpp b/Tests/LibELF/TestWeakSymbolResolution.cpp new file mode 100644 index 00000000000..6e19ff397da --- /dev/null +++ b/Tests/LibELF/TestWeakSymbolResolution.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024, Dan Klishch + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +int f(); +[[gnu::weak]] int f() { return 1; } +int g(); + +TEST_CASE(weak_symbol_resolution) +{ + EXPECT_EQ(g(), 1); +} diff --git a/Tests/LibELF/TestWeakSymbolResolution1.cpp b/Tests/LibELF/TestWeakSymbolResolution1.cpp new file mode 100644 index 00000000000..2a120900799 --- /dev/null +++ b/Tests/LibELF/TestWeakSymbolResolution1.cpp @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024, Dan Klishch + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +[[gnu::weak]] int f(); + +int g(); +int g() { return f(); } diff --git a/Tests/LibELF/TestWeakSymbolResolution2.cpp b/Tests/LibELF/TestWeakSymbolResolution2.cpp new file mode 100644 index 00000000000..ee391bb9108 --- /dev/null +++ b/Tests/LibELF/TestWeakSymbolResolution2.cpp @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024, Dan Klishch + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +int f(); +int f() { return 2; } diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index 16540fda131..404a7dbf7ec 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -78,27 +78,20 @@ static HashMap s_magic_functions; Optional DynamicLinker::lookup_global_symbol(StringView name) { - Optional weak_result; - auto symbol = DynamicObject::HashSymbol { name }; for (auto& lib : s_global_objects) { auto res = lib.value->lookup_symbol(symbol); if (!res.has_value()) continue; - if (res.value().bind == STB_GLOBAL) + if (res.value().bind == STB_GLOBAL || res.value().bind == STB_WEAK) return res; - if (res.value().bind == STB_WEAK && !weak_result.has_value()) - weak_result = res; // We don't want to allow local symbols to be pulled in to other modules } - if (!weak_result.has_value()) { - if (auto magic_lookup = s_magic_functions.get(name); magic_lookup.has_value()) - weak_result = *magic_lookup; - } - - return weak_result; + if (auto magic_lookup = s_magic_functions.get(name); magic_lookup.has_value()) + return *magic_lookup; + return {}; } static Result, DlErrorMessage> map_library(ByteString const& filepath, int fd)