diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-06-06 17:40:11 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-06 22:16:11 +0200 |
commit | 89a38b72b7181b103aa524e8abd3fe98c8c75864 (patch) | |
tree | 3b71cde96160281d7d3c26468d53f88377d4760a /Userland/Libraries/LibDl | |
parent | f82aa87d141a27271a3494fb734b5a9fc3ee4930 (diff) | |
download | serenity-89a38b72b7181b103aa524e8abd3fe98c8c75864.zip |
LibC+LibELF: Implement dladdr()
This implements the dladdr() function which lets the caller look up
the symbol name, symbol address as well as library name and library
base address for an arbitrary address.
Diffstat (limited to 'Userland/Libraries/LibDl')
-rw-r--r-- | Userland/Libraries/LibDl/dlfcn.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibDl/dlfcn.h | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibDl/dlfcn_integration.h | 5 |
3 files changed, 25 insertions, 0 deletions
diff --git a/Userland/Libraries/LibDl/dlfcn.cpp b/Userland/Libraries/LibDl/dlfcn.cpp index ef730e845d..077f62a101 100644 --- a/Userland/Libraries/LibDl/dlfcn.cpp +++ b/Userland/Libraries/LibDl/dlfcn.cpp @@ -60,3 +60,15 @@ void* dlsym(void* handle, const char* symbol_name) } 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; +} diff --git a/Userland/Libraries/LibDl/dlfcn.h b/Userland/Libraries/LibDl/dlfcn.h index fd0b427f82..880dce74ac 100644 --- a/Userland/Libraries/LibDl/dlfcn.h +++ b/Userland/Libraries/LibDl/dlfcn.h @@ -16,9 +16,17 @@ __BEGIN_DECLS #define RTLD_GLOBAL 8 #define RTLD_LOCAL 16 +typedef struct __Dl_info { + const char* dli_fname; + void* dli_fbase; + const char* dli_sname; + void* dli_saddr; +} Dl_info; + int dlclose(void*); char* dlerror(); void* dlopen(const char*, int); void* dlsym(void*, const char*); +int dladdr(void*, Dl_info*); __END_DECLS diff --git a/Userland/Libraries/LibDl/dlfcn_integration.h b/Userland/Libraries/LibDl/dlfcn_integration.h index c336e7bee9..19a8251ae2 100644 --- a/Userland/Libraries/LibDl/dlfcn_integration.h +++ b/Userland/Libraries/LibDl/dlfcn_integration.h @@ -23,12 +23,17 @@ struct DlErrorMessage { String text; }; +struct __Dl_info; +typedef struct __Dl_info Dl_info; + typedef Result<void, DlErrorMessage> (*DlCloseFunction)(void*); typedef Result<void*, DlErrorMessage> (*DlOpenFunction)(const char*, int); typedef Result<void*, DlErrorMessage> (*DlSymFunction)(void*, const char*); +typedef Result<void, DlErrorMessage> (*DlAddrFunction)(void*, Dl_info*); extern "C" { extern DlCloseFunction __dlclose; extern DlOpenFunction __dlopen; extern DlSymFunction __dlsym; +extern DlAddrFunction __dladdr; } |