Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Date: Thu, 25 Jan 2024 13:10:04 +0100
From: Jules Maselbas <jmaselbas@...v.net>
To: musl@...ts.openwall.com
Cc: Jules Maselbas <jmaselbas@...v.net>
Subject: [PATCH] modify dladdr to add dladdr1 support

The dladdr1() function is very much like dladdr(), but also returns
additional information depending on the value of the flags argument,
which can be one of the following values:

 - RTLD_DL_LINKMAP, returns a pointer to the link map for the matched
   file, same as dlinfo() with the RTLD_DI_LINKMAP request.

 - RTLD_DL_SYMENT, returns a pointer to the ELF symbole structure that
   matched for the given addr argument.

---
Implemented this because it is used by plthook (a dependency of renderdoc),
I have not tested this.

 include/dlfcn.h    |  3 +++
 ldso/dynlink.c     | 12 +++++++++++-
 src/ldso/dladdr1.c |  9 +++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 src/ldso/dladdr1.c

diff --git a/include/dlfcn.h b/include/dlfcn.h
index 13ab71dd..8d09767a 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -32,6 +32,9 @@ typedef struct {
 	void *dli_saddr;
 } Dl_info;
 int dladdr(const void *, Dl_info *);
+int dladdr1(const void *, Dl_info *, void **, int);
+#define RTLD_DL_SYMENT  1
+#define RTLD_DL_LINKMAP 2
 int dlinfo(void *, int, void *);
 #endif
 
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 324aa859..5cc550d6 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -2291,7 +2291,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
 	return laddr(def.dso, def.sym->st_value);
 }
 
-int dladdr(const void *addr_arg, Dl_info *info)
+int dladdr1(const void *addr_arg, Dl_info *info, void **extra_info, int flags)
 {
 	size_t addr = (size_t)addr_arg;
 	struct dso *p;
@@ -2355,9 +2355,19 @@ int dladdr(const void *addr_arg, Dl_info *info)
 	info->dli_sname = strings + bestsym->st_name;
 	info->dli_saddr = (void *)best;
 
+	if (flags == RTLD_DL_LINKMAP)
+		*(struct link_map **)extra_info = (void *)p;
+	if (flags == RTLD_DL_SYMENT)
+		*(const Sym **)extra_info = bestsym;
+
 	return 1;
 }
 
+int dladdr(const void *addr_arg, Dl_info *info)
+{
+	return dladdr1(addr_arg, info, NULL, 0);
+}
+
 hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
 {
 	void *res;
diff --git a/src/ldso/dladdr1.c b/src/ldso/dladdr1.c
new file mode 100644
index 00000000..b1e51379
--- /dev/null
+++ b/src/ldso/dladdr1.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+
+static int stub_dladdr1(const void *addr, Dl_info *info, void **extra_info, int flags)
+{
+	return 0;
+}
+
+weak_alias(stub_dladdr1, dladdr1);
-- 
2.43.0

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.