headers := bits/dlfcn.h dlfcn.h
extra-libs := libdl
-libdl-routines := dlopen dlsym dlvsym dladdr1 dlinfo \
+libdl-routines := dlopen dlvsym dladdr1 dlinfo \
dlmopen dlfcn
routines := $(patsubst %,s%,$(filter-out dlfcn,$(libdl-routines)))
elide-routines.os := $(routines)
dladdr \
dlclose \
dlerror \
+ dlsym \
libc_dlerror_result \
extra-libs-others := libdl
<https://www.gnu.org/licenses/>. */
#include <dlfcn.h>
-#include <stddef.h>
-
#include <ldsodefs.h>
-
-#if !defined SHARED && IS_IN (libdl)
-
-void *
-dlsym (void *handle, const char *name)
-{
- return __dlsym (handle, name, RETURN_ADDRESS (0));
-}
-
-#else
+#include <shlib-compat.h>
+#include <stddef.h>
struct dlsym_args
{
args->sym = _dl_sym (args->handle, args->name, args->who);
}
-
-void *
-__dlsym (void *handle, const char *name DL_CALLER_DECL)
+static void *
+dlsym_implementation (void *handle, const char *name, void *dl_caller)
{
-# ifdef SHARED
- if (!rtld_active ())
- return _dlfcn_hook->dlsym (handle, name, DL_CALLER);
-# endif
-
struct dlsym_args args;
- args.who = DL_CALLER;
+ args.who = dl_caller;
args.handle = handle;
args.name = name;
return result;
}
-# ifdef SHARED
-strong_alias (__dlsym, dlsym)
+
+#ifdef SHARED
+void *
+___dlsym (void *handle, const char *name)
+{
+ if (!rtld_active ())
+ return _dlfcn_hook->dlsym (handle, name, RETURN_ADDRESS (0));
+ else
+ return dlsym_implementation (handle, name, RETURN_ADDRESS (0));
+}
+versioned_symbol (libc, ___dlsym, dlsym, GLIBC_2_34);
+
+# if OTHER_SHLIB_COMPAT (libdl, GLIBC_2_0, GLIBC_2_34)
+compat_symbol (libdl, ___dlsym, dlsym, GLIBC_2_0);
# endif
-#endif
+
+#else /* !SHARED */
+/* Also used with _dlfcn_hook. */
+void *
+__dlsym (void *handle, const char *name, void *dl_caller)
+{
+ return dlsym_implementation (handle, name, dl_caller);
+}
+
+void *
+___dlsym (void *handle, const char *name)
+{
+ return __dlsym (handle, name, RETURN_ADDRESS (0));
+}
+weak_alias (___dlsym, dlsym)
+#endif /* !SHARED */
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(strip $(modules-names))))
generated += $(addsuffix .so,$(strip $(modules-names)))
-$(objpfx)testobj1.so: $(libdl)
$(objpfx)testobj1_1.so: $(objpfx)testobj1.so $(libdl)
$(objpfx)testobj2.so: $(objpfx)testobj1.so $(libdl)
$(objpfx)testobj3.so: $(libdl)
RTLD_NEXT). WHO is the calling function, for RTLD_NEXT. Returns
the symbol value, which may be NULL. */
extern void *_dl_sym (void *handle, const char *name, void *who);
+libc_hidden_proto (_dl_sym)
/* Look up version VERSION of symbol NAME in shared object HANDLE
(which may be RTLD_DEFAULT or RTLD_NEXT). WHO is the calling
extern void *__dlmopen (Lmid_t nsid, const char *file, int mode DL_CALLER_DECL)
attribute_hidden;
extern int __dlclose (void *handle);
-extern void *__dlsym (void *handle, const char *name DL_CALLER_DECL)
- attribute_hidden;
+extern void *__dlsym (void *handle, const char *name, void *dl_caller);
extern void *__dlvsym (void *handle, const char *name, const char *version
DL_CALLER_DECL)
attribute_hidden;