Serenity Operating System

LibDl: Move the `dlfcn` implementation to LibC

authored by

Tim Schumacher and committed by
Linus Groh
226608a4 27bfb817

+77 -81
Toolchain/Stubs/i686clang/libc.so

This is a binary file and will not be displayed.

Toolchain/Stubs/i686clang/libdl.so

This is a binary file and will not be displayed.

Toolchain/Stubs/x86_64clang/libc.so

This is a binary file and will not be displayed.

Toolchain/Stubs/x86_64clang/libdl.so

This is a binary file and will not be displayed.

+73 -1
Userland/Libraries/LibC/dlfcn.cpp
··· 4 4 * SPDX-License-Identifier: BSD-2-Clause 5 5 */ 6 6 7 + #include <AK/String.h> 8 + #include <AK/Types.h> 9 + #include <dlfcn.h> 7 10 #include <dlfcn_integration.h> 11 + #include <string.h> 8 12 9 - // These are used by libdl and are filled in by the dynamic loader. 13 + // These are filled in by the dynamic loader. 10 14 DlCloseFunction __dlclose; 11 15 DlOpenFunction __dlopen; 12 16 DlSymFunction __dlsym; 13 17 DlAddrFunction __dladdr; 18 + 19 + // FIXME: use thread_local and a String once TLS works 20 + #ifdef NO_TLS 21 + char* s_dlerror_text = NULL; 22 + bool s_dlerror_retrieved = false; 23 + #else 24 + __thread char* s_dlerror_text = NULL; 25 + __thread bool s_dlerror_retrieved = false; 26 + #endif 27 + 28 + static void store_error(String const& error) 29 + { 30 + free(s_dlerror_text); 31 + s_dlerror_text = strdup(error.characters()); 32 + s_dlerror_retrieved = false; 33 + } 34 + 35 + int dlclose(void* handle) 36 + { 37 + auto result = __dlclose(handle); 38 + if (result.is_error()) { 39 + store_error(result.error().text); 40 + return -1; 41 + } 42 + return 0; 43 + } 44 + 45 + char* dlerror() 46 + { 47 + if (s_dlerror_retrieved) { 48 + free(s_dlerror_text); 49 + s_dlerror_text = nullptr; 50 + } 51 + s_dlerror_retrieved = true; 52 + return const_cast<char*>(s_dlerror_text); 53 + } 54 + 55 + void* dlopen(char const* filename, int flags) 56 + { 57 + auto result = __dlopen(filename, flags); 58 + if (result.is_error()) { 59 + store_error(result.error().text); 60 + return nullptr; 61 + } 62 + return result.value(); 63 + } 64 + 65 + void* dlsym(void* handle, char const* symbol_name) 66 + { 67 + auto result = __dlsym(handle, symbol_name); 68 + if (result.is_error()) { 69 + store_error(result.error().text); 70 + return nullptr; 71 + } 72 + return result.value(); 73 + } 74 + 75 + int dladdr(void* addr, Dl_info* info) 76 + { 77 + auto result = __dladdr(addr, info); 78 + if (result.is_error()) { 79 + // FIXME: According to the man page glibc does _not_ make the error 80 + // available via dlerror(), however we do. Does this break anything? 81 + store_error(result.error().text); 82 + return 0; 83 + } 84 + return 1; 85 + }
+4 -6
Userland/Libraries/LibDl/CMakeLists.txt
··· 1 - set(SOURCES 2 - dlfcn.cpp 3 - ) 4 - 5 - serenity_libc(LibDl dl) 6 - target_link_libraries(LibDl LibC) 1 + # Provide a dummy target and a linker script that tells everything to link against LibC instead. 2 + add_library(LibDl INTERFACE) 3 + target_link_libraries(LibDl INTERFACE LibC) 4 + file(WRITE "${CMAKE_STAGING_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libdl.so" "INPUT(libc.so)")
-74
Userland/Libraries/LibDl/dlfcn.cpp
··· 1 - /* 2 - * Copyright (c) 2021, Gunnar Beutner <gunnar@beutner.name> 3 - * 4 - * SPDX-License-Identifier: BSD-2-Clause 5 - */ 6 - 7 - #include <AK/String.h> 8 - #include <AK/Types.h> 9 - #include <dlfcn.h> 10 - #include <dlfcn_integration.h> 11 - #include <string.h> 12 - 13 - // FIXME: use thread_local and a String once TLS works 14 - __thread char* s_dlerror_text = NULL; 15 - __thread bool s_dlerror_retrieved = false; 16 - 17 - static void store_error(String const& error) 18 - { 19 - free(s_dlerror_text); 20 - s_dlerror_text = strdup(error.characters()); 21 - s_dlerror_retrieved = false; 22 - } 23 - 24 - int dlclose(void* handle) 25 - { 26 - auto result = __dlclose(handle); 27 - if (result.is_error()) { 28 - store_error(result.error().text); 29 - return -1; 30 - } 31 - return 0; 32 - } 33 - 34 - char* dlerror() 35 - { 36 - if (s_dlerror_retrieved) { 37 - free(s_dlerror_text); 38 - s_dlerror_text = nullptr; 39 - } 40 - s_dlerror_retrieved = true; 41 - return const_cast<char*>(s_dlerror_text); 42 - } 43 - 44 - void* dlopen(char const* filename, int flags) 45 - { 46 - auto result = __dlopen(filename, flags); 47 - if (result.is_error()) { 48 - store_error(result.error().text); 49 - return nullptr; 50 - } 51 - return result.value(); 52 - } 53 - 54 - void* dlsym(void* handle, char const* symbol_name) 55 - { 56 - auto result = __dlsym(handle, symbol_name); 57 - if (result.is_error()) { 58 - store_error(result.error().text); 59 - return nullptr; 60 - } 61 - return result.value(); 62 - } 63 - 64 - int dladdr(void* addr, Dl_info* info) 65 - { 66 - auto result = __dladdr(addr, info); 67 - if (result.is_error()) { 68 - // FIXME: According to the man page glibc does _not_ make the error 69 - // available via dlerror(), however we do. Does this break anything? 70 - store_error(result.error().text); 71 - return 0; 72 - } 73 - return 1; 74 - }
Userland/Libraries/LibDl/dlfcn.h Userland/Libraries/LibC/dlfcn.h
Userland/Libraries/LibDl/dlfcn_integration.h Userland/Libraries/LibC/dlfcn_integration.h