Serenity Operating System
at master 85 lines 2.0 kB view raw
1/* 2 * Copyright (c) 2021, Gunnar Beutner <gunnar@beutner.name> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/DeprecatedString.h> 8#include <AK/Types.h> 9#include <bits/dlfcn_integration.h> 10#include <dlfcn.h> 11#include <string.h> 12 13// These are filled in by the dynamic loader. 14DlCloseFunction __dlclose; 15DlOpenFunction __dlopen; 16DlSymFunction __dlsym; 17DlAddrFunction __dladdr; 18 19// FIXME: use thread_local and a String once TLS works 20#ifdef NO_TLS 21char* s_dlerror_text = NULL; 22bool s_dlerror_retrieved = false; 23#else 24__thread char* s_dlerror_text = NULL; 25__thread bool s_dlerror_retrieved = false; 26#endif 27 28static void store_error(DeprecatedString const& error) 29{ 30 free(s_dlerror_text); 31 s_dlerror_text = strdup(error.characters()); 32 s_dlerror_retrieved = false; 33} 34 35int 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 45char* 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 55void* 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 65void* 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 75int 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}