On Sun, 30 Nov 2025 at 20:28, Bruno Haible <[email protected]> wrote: > Hi Reuben, > > > My patch is incomplete: it unconditionally uses libdl.m4, meaning libdl > > will always be linked on systems that have it. I appreciate this is what > > we're trying to avoid! I'm unclear what the best way to fix this is. > Should > > I move the test for which code to use (i.e. Windows, libdl or /proc) to > > configure.ac, and introduce an automake conditional to guard the > addition > > of libdl to the LIBS variable? > > I think you are on the right track. What I would do: > - Keep the invocation of gl_LIBDL, but don't use the value of $(LIBDL) > in lib_LDFLAGS. > - Define _GL_USE_DLADDR only if $(LIBDL) is empty. > - Use the value $(LIBDL) to decide this, in the configure.ac section of > the > module. I don't know whether that will require an Automake conditional.
Updated patch attached. It seemed too simple: all I do is, as you say, define _GL_USE_DLADDR only if $(LIBDL) is empty, and then use dladdr only if _GL_USE_DLADDR is set, and we haven't defined either _GL_USE_PROCFS or _GL_USE_WIN32. -- Web: rrt.sc3d.org
From 8fc778805199b40777ab267bce0bfab9fdaccafe Mon Sep 17 00:00:00 2001 From: Reuben Thomas <[email protected]> Date: Mon, 8 Dec 2025 18:59:01 +0000 Subject: [PATCH] relocatable-lib{,-lgpl}: allow using dladdr to get path to shared library This is portable (in POSIX:2024 [1]), so use it on all systems where dladdr is in libc. [1] https://pubs.opengroup.org/onlinepubs/9799919799/functions/dladdr.html --- lib/relocatable.c | 38 ++++++++++++++++++++++++++---------- m4/libdl.m4 | 2 +- modules/relocatable-lib | 7 +++++-- modules/relocatable-lib-lgpl | 4 ++++ 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/lib/relocatable.c b/lib/relocatable.c index 15b3bc442d..b060df91d4 100644 --- a/lib/relocatable.c +++ b/lib/relocatable.c @@ -71,6 +71,21 @@ # define GetModuleFileName GetModuleFileNameA #endif +/* We have special code for two types of system: non-Cygwin Windows, and + Linux where dladdr is in a separate library (uClibc and glibc < 2.34). + Need glibc >= 2, for getline(). + + Otherwise, use dladdr. +*/ +#if defined __linux__ && (defined __UCLIBC__ || ((__GLIBC__ >= 2) && (__GLIBC_MINOR__ < 34))) +#define _GL_USE_PROCFS 1 +#elif (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ +#define _GL_USE_WIN32 1 +#elif _GL_DLADDR_IN_LIBC +#define _GL_USE_DLADDR 1 +#include <dlfcn.h> +#endif + /* Faked cheap 'bool'. */ #undef bool #undef false @@ -318,10 +333,9 @@ static char *shared_library_fullname; #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows only. - On Cygwin, it is better to use the Cygwin provided /proc interface, than - to use native Windows API and cygwin_conv_to_posix_path, because it - supports longer file names - (see <https://cygwin.com/ml/cygwin/2011-01/msg00410.html>). */ + On Cygwin, it is better to use dladdr, than to use native Windows + API and cygwin_conv_to_posix_path, because it supports longer file + names (see <https://cygwin.com/ml/cygwin/2011-01/msg00410.html>). */ /* Determine the full pathname of the shared library when it is loaded. @@ -402,12 +416,10 @@ _DLL_InitTerm (unsigned long hModule, unsigned long ulFlag) static void find_shared_library_fullname () { -#if (defined __linux__ && (__GLIBC__ >= 2 || defined __UCLIBC__)) || defined __CYGWIN__ +#if _GL_USE_PROCFS /* Linux has /proc/self/maps. glibc 2 and uClibc have the getline() function. - Cygwin >= 1.5 has /proc/self/maps and the getline() function too. - But it is costly: ca. 0.3 ms on Linux, 3 ms on Cygwin 1.5, and 5 ms on - Cygwin 1.7. */ + But it is costly: ca. 0.3 ms. */ FILE *fp; /* Open the current process' maps file. It describes one VMA per line. */ @@ -449,6 +461,11 @@ find_shared_library_fullname () } fclose (fp); } +#elif _GL_USE_DLADDR + Dl_info info; + dladdr (find_shared_library_fullname, &info); + if (info.dli_fname != NULL) + shared_library_fullname = strdup (info.dli_fname); #endif } @@ -456,11 +473,12 @@ find_shared_library_fullname () /* Return the full pathname of the current shared library. Return NULL if unknown. - Guaranteed to work only on Linux, EMX, Cygwin, and native Windows. */ + Guaranteed to work only on Linux, EMX, Cygwin, native Windows, and + systems with dladdr in libc. */ static char * get_shared_library_fullname () { -#if !(defined _WIN32 && !defined __CYGWIN__) && !defined __EMX__ +#if !_GL_USE_WIN32 static bool tried_find_shared_library_fullname; if (!tried_find_shared_library_fullname) { diff --git a/m4/libdl.m4 b/m4/libdl.m4 index 4b4357b7f8..839b053af5 100644 --- a/m4/libdl.m4 +++ b/m4/libdl.m4 @@ -15,7 +15,7 @@ AC_DEFUN([gl_LIBDL], dnl dlopen, dlsym are dnl - in libc on glibc >= 2.34, musl libc, macOS, FreeBSD, NetBSD, OpenBSD, dnl AIX, Solaris, Cygwin, Haiku, - dnl - in a separate libdl on glibc < 2.34, Android. + dnl - in a separate libdl on glibc < 2.34, Android, uClibc. AC_CACHE_CHECK([for library needed for dlopen and dlsym], [gl_cv_lib_dl], [AC_LINK_IFELSE( diff --git a/modules/relocatable-lib b/modules/relocatable-lib index 0d59464fe6..583df4bccc 100644 --- a/modules/relocatable-lib +++ b/modules/relocatable-lib @@ -7,6 +7,7 @@ doc/relocatable.texi lib/relocatable.h lib/relocatable.c lib/relocatable.valgrind +m4/libdl.m4 m4/relocatable-lib.m4 m4/build-to-host.m4 @@ -19,8 +20,10 @@ gl_RELOCATABLE_LIBRARY if test $RELOCATABLE = yes; then AC_LIBOBJ([relocatable]) fi - -Makefile.am: +gl_LIBDL +if test "$LIBDL" = ""; then + AC_DEFINE([_GL_DLADDR_IN_LIBC], 1, [Define to 1 if dladdr is in libc.]) +fi Include: "relocatable.h" diff --git a/modules/relocatable-lib-lgpl b/modules/relocatable-lib-lgpl index b8ecb51ef8..99dac18f50 100644 --- a/modules/relocatable-lib-lgpl +++ b/modules/relocatable-lib-lgpl @@ -18,6 +18,10 @@ gl_RELOCATABLE_LIBRARY if test $RELOCATABLE = yes; then AC_LIBOBJ([relocatable]) fi +gl_LIBDL +if test "$LIBDL" = ""; then + AC_DEFINE([_GL_DLADDR_IN_LIBC], 1, [Define to 1 if dladdr is in libc.]) +fi Makefile.am: DEFS += -DNO_XMALLOC -- 2.43.0
