mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:37:46 +00:00
LibDl: Move the dlfcn
implementation to LibC
This commit is contained in:
parent
27bfb81702
commit
226608a48f
9 changed files with 77 additions and 81 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -4,10 +4,82 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <AK/Types.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#include <dlfcn_integration.h>
|
#include <dlfcn_integration.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// These are used by libdl and are filled in by the dynamic loader.
|
// These are filled in by the dynamic loader.
|
||||||
DlCloseFunction __dlclose;
|
DlCloseFunction __dlclose;
|
||||||
DlOpenFunction __dlopen;
|
DlOpenFunction __dlopen;
|
||||||
DlSymFunction __dlsym;
|
DlSymFunction __dlsym;
|
||||||
DlAddrFunction __dladdr;
|
DlAddrFunction __dladdr;
|
||||||
|
|
||||||
|
// FIXME: use thread_local and a String once TLS works
|
||||||
|
#ifdef NO_TLS
|
||||||
|
char* s_dlerror_text = NULL;
|
||||||
|
bool s_dlerror_retrieved = false;
|
||||||
|
#else
|
||||||
|
__thread char* s_dlerror_text = NULL;
|
||||||
|
__thread bool s_dlerror_retrieved = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void store_error(String const& error)
|
||||||
|
{
|
||||||
|
free(s_dlerror_text);
|
||||||
|
s_dlerror_text = strdup(error.characters());
|
||||||
|
s_dlerror_retrieved = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dlclose(void* handle)
|
||||||
|
{
|
||||||
|
auto result = __dlclose(handle);
|
||||||
|
if (result.is_error()) {
|
||||||
|
store_error(result.error().text);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* dlerror()
|
||||||
|
{
|
||||||
|
if (s_dlerror_retrieved) {
|
||||||
|
free(s_dlerror_text);
|
||||||
|
s_dlerror_text = nullptr;
|
||||||
|
}
|
||||||
|
s_dlerror_retrieved = true;
|
||||||
|
return const_cast<char*>(s_dlerror_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* dlopen(char const* filename, int flags)
|
||||||
|
{
|
||||||
|
auto result = __dlopen(filename, flags);
|
||||||
|
if (result.is_error()) {
|
||||||
|
store_error(result.error().text);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return result.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* dlsym(void* handle, char const* symbol_name)
|
||||||
|
{
|
||||||
|
auto result = __dlsym(handle, symbol_name);
|
||||||
|
if (result.is_error()) {
|
||||||
|
store_error(result.error().text);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return result.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
int dladdr(void* addr, Dl_info* info)
|
||||||
|
{
|
||||||
|
auto result = __dladdr(addr, info);
|
||||||
|
if (result.is_error()) {
|
||||||
|
// FIXME: According to the man page glibc does _not_ make the error
|
||||||
|
// available via dlerror(), however we do. Does this break anything?
|
||||||
|
store_error(result.error().text);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
set(SOURCES
|
# Provide a dummy target and a linker script that tells everything to link against LibC instead.
|
||||||
dlfcn.cpp
|
add_library(LibDl INTERFACE)
|
||||||
)
|
target_link_libraries(LibDl INTERFACE LibC)
|
||||||
|
file(WRITE "${CMAKE_STAGING_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libdl.so" "INPUT(libc.so)")
|
||||||
serenity_libc(LibDl dl)
|
|
||||||
target_link_libraries(LibDl LibC)
|
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2021, Gunnar Beutner <gunnar@beutner.name>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <AK/String.h>
|
|
||||||
#include <AK/Types.h>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <dlfcn_integration.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// FIXME: use thread_local and a String once TLS works
|
|
||||||
__thread char* s_dlerror_text = NULL;
|
|
||||||
__thread bool s_dlerror_retrieved = false;
|
|
||||||
|
|
||||||
static void store_error(String const& error)
|
|
||||||
{
|
|
||||||
free(s_dlerror_text);
|
|
||||||
s_dlerror_text = strdup(error.characters());
|
|
||||||
s_dlerror_retrieved = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dlclose(void* handle)
|
|
||||||
{
|
|
||||||
auto result = __dlclose(handle);
|
|
||||||
if (result.is_error()) {
|
|
||||||
store_error(result.error().text);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* dlerror()
|
|
||||||
{
|
|
||||||
if (s_dlerror_retrieved) {
|
|
||||||
free(s_dlerror_text);
|
|
||||||
s_dlerror_text = nullptr;
|
|
||||||
}
|
|
||||||
s_dlerror_retrieved = true;
|
|
||||||
return const_cast<char*>(s_dlerror_text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* dlopen(char const* filename, int flags)
|
|
||||||
{
|
|
||||||
auto result = __dlopen(filename, flags);
|
|
||||||
if (result.is_error()) {
|
|
||||||
store_error(result.error().text);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return result.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void* dlsym(void* handle, char const* symbol_name)
|
|
||||||
{
|
|
||||||
auto result = __dlsym(handle, symbol_name);
|
|
||||||
if (result.is_error()) {
|
|
||||||
store_error(result.error().text);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return result.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
int dladdr(void* addr, Dl_info* info)
|
|
||||||
{
|
|
||||||
auto result = __dladdr(addr, info);
|
|
||||||
if (result.is_error()) {
|
|
||||||
// FIXME: According to the man page glibc does _not_ make the error
|
|
||||||
// available via dlerror(), however we do. Does this break anything?
|
|
||||||
store_error(result.error().text);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue