From 48c93500365f719e255cc0155019f9f7a9fe06d7 Mon Sep 17 00:00:00 2001 From: Jesse Buhagiar Date: Sun, 2 Jan 2022 14:59:55 +1100 Subject: LibELF: Add `LD_LIBRARY_PATH` envvar support :^) The dynamic linker now supports having custom library paths as specified by the user. --- Userland/Libraries/LibELF/DynamicLinker.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'Userland/Libraries/LibELF') diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index 418bc14411..b66b6401b5 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -2,6 +2,7 @@ * Copyright (c) 2020, Itamar S. * Copyright (c) 2021, Andreas Kling * Copyright (c) 2021, the SerenityOS developers. + * Copyright (c) 2022, Jesse Buhagiar * * SPDX-License-Identifier: BSD-2-Clause */ @@ -52,6 +53,7 @@ static __pthread_mutex_t s_loader_lock = __PTHREAD_MUTEX_INITIALIZER; static bool s_allowed_to_check_environment_variables { false }; static bool s_do_breakpoint_trap_before_entry { false }; +static StringView s_ld_library_path; static Result __dlclose(void* handle); static Result __dlopen(const char* filename, int flags); @@ -108,6 +110,18 @@ static Result, DlErrorMessage> map_library(const St return map_library(name, fd); } + // Scan the LD_LIBRARY_PATH environment variable if applicable + if (s_ld_library_path != nullptr) { + for (const auto& search_path : s_ld_library_path.split_view(':')) { + LexicalPath library_path(search_path); + int fd = open(library_path.append(name).string().characters(), O_RDONLY); + if (fd < 0) + continue; + return map_library(name, fd); + } + } + + // Now check the default paths. // TODO: Do we want to also look for libs in other paths too? const char* search_paths[] = { "/usr/lib/{}", "/usr/local/lib/{}" }; for (auto& search_path : search_paths) { @@ -494,9 +508,15 @@ static Result __dladdr(void* addr, Dl_info* info) static void read_environment_variables() { for (char** env = s_envp; *env; ++env) { - if (StringView { *env } == "_LOADER_BREAKPOINT=1"sv) { + StringView env_string { *env }; + if (env_string == "_LOADER_BREAKPOINT=1"sv) { s_do_breakpoint_trap_before_entry = true; } + + constexpr auto library_path_string = "LD_LIBRARY_PATH="sv; + if (env_string.starts_with(library_path_string)) { + s_ld_library_path = env_string.substring_view(library_path_string.length()); + } } } -- cgit v1.2.3