@@ -24,6 +24,8 @@ Major new features:
* The dladdr1 function accepts a new flag, RTLD_DL_HANDLE, to obtain a
handle (as used with dlsym and other functions) based on an address.
+* The dlinfo_soname function has been added to the <dlfcn.h> header file.
+
Deprecated and removed features, and other changes affecting compatibility:
* The totalorder and totalordermag functions, and the corresponding
@@ -23,8 +23,11 @@ headers := bits/dlfcn.h dlfcn.h
extra-libs := libdl
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo \
dlmopen dlfcn dlfreeres
-routines := $(patsubst %,s%,$(filter-out dlfcn,$(libdl-routines)))
-elide-routines.os := $(routines)
+
+# Most routines currently end up in libdl only (for shared builds).
+routines-for-libdl := $(patsubst %,s%,$(filter-out dlfcn,$(libdl-routines)))
+routines := $(routines-for-libdl) dlinfo_soname
+elide-routines.os := $(routines-for-libdl)
extra-libs-others := libdl
@@ -36,7 +39,9 @@ endif
ifeq (yes,$(build-shared))
tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
- bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen tst-dladdr1-handle
+ bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen tst-dladdr1-handle \
+ tst-dlinfo_soname
+tests-static = tst-dlinfo_soname-static
endif
modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
defaultmod2 errmsg1mod modatexit modcxaatexit \
@@ -49,14 +54,17 @@ glreflib2.so-no-z-defs = yes
errmsg1mod.so-no-z-defs = yes
ifeq (yes,$(build-shared))
-tests += tststatic tststatic2 tststatic3 tststatic4 tststatic5
-tests-static += tststatic tststatic2 tststatic3 tststatic4 tststatic5
+tests += tststatic tststatic2 tststatic3 tststatic4 tststatic5 \
+ tst-dlinfo_soname-static
+tests-static += tststatic tststatic2 tststatic3 tststatic4 tststatic5 \
+ tst-dlinfo_soname-static
modules-names += modstatic modstatic2 modstatic3 modstatic5
tststatic-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
tststatic2-ENV = $(tststatic-ENV)
tststatic3-ENV = $(tststatic-ENV)
tststatic4-ENV = $(tststatic-ENV)
tststatic5-ENV = $(tststatic-ENV)
+tst-dlinfo_soname-static-ENV = $(tststatic-ENV)
ifneq (,$(CXX))
modules-names += bug-atexit3-lib
@@ -154,3 +162,9 @@ $(objpfx)tst-rec-dlopen.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so
$(objpfx)tst-dladdr1-handle: $(libdl)
$(objpfx)tst-dladdr1-handle.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so
+
+$(objpfx)tst-dlinfo_soname: $(libdl)
+$(objpfx)tst-dlinfo_soname.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so
+$(objpfx)tst-dlinfo_soname-static: $(objpfx)libdl.a
+$(objpfx)tst-dlinfo_soname-static.out: \
+ $(objpfx)moddummy1.so $(objpfx)moddummy2.so
@@ -1,3 +1,9 @@
+libc {
+ GLIBC_2.31 {
+ dlinfo_soname;
+ }
+}
+
libdl {
GLIBC_2.0 {
dladdr; dlclose; dlerror; dlopen; dlsym;
@@ -199,6 +199,13 @@ typedef struct
Dl_serpath dls_serpath[1]; /* Actually longer, dls_cnt elements. */
# endif
} Dl_serinfo;
+
+/* Return a string with the soname for the object identified by HANDLE
+ (which must have been obtained from dlopen or dlmopen). The result
+ is NULL if the object does not have a soname (either an explicit or
+ an implied one). */
+extern const char *dlinfo_soname (void *handle) __THROW __nonnull ((1));
+
#endif /* __USE_GNU */
new file mode 100644
@@ -0,0 +1,35 @@
+/* Obtain the soname of an object identified by its handle.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <ldsodefs.h>
+#include <link.h>
+#include <string.h>
+
+const char *
+dlinfo_soname (void *handle)
+{
+ struct link_map *l = handle;
+ if (l->l_info[DT_SONAME] != NULL)
+ return ((const char *) D_PTR (l, l_info[DT_STRTAB])
+ + l->l_info[DT_SONAME]->d_un.d_val);
+ else if (l->l_name != NULL && l->l_name[0] != '\0')
+ return __basename (l->l_name);
+ else
+ return NULL;
+}
new file mode 100644
@@ -0,0 +1,57 @@
+/* Test for the dlinfo_soname function. Static version.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <gnu/lib-names.h>
+#include <link.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xdlfcn.h>
+
+static int
+do_test (void)
+{
+ Dl_info info;
+ void *handle;
+
+ /* Check the soname of a library loaded by soname. */
+ void *moddummy1_handle = xdlopen ("moddummy1.so", RTLD_NOW);
+ TEST_COMPARE_STRING (dlinfo_soname (moddummy1_handle), "moddummy1.so");
+
+ /* This is an arbitrary symbol in libc.so. It is used to locate a
+ handle for libc.so only. */
+ void *ptr = xdlsym (moddummy1_handle, "grantpt");
+ if (dladdr1 (ptr, &info, &handle, RTLD_DL_HANDLE) == 0)
+ FAIL_EXIT1 ("dladdr1 for grantpt in namespace failed");
+ TEST_COMPARE_STRING (dlinfo_soname (handle), LIBC_SO);
+
+ /* Check the soname of a library loaded by full path. */
+ char *full_path = xasprintf ("%s/dlfcn/moddummy2.so", support_objdir_root);
+ void *moddummy2_handle = xdlopen (full_path, RTLD_NOW);
+ TEST_COMPARE_STRING (dlinfo_soname (moddummy2_handle), "moddummy2.so");
+
+ xdlclose (moddummy2_handle);
+ free (full_path);
+ xdlclose (moddummy1_handle);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
new file mode 100644
@@ -0,0 +1,72 @@
+/* Test for the dlinfo_soname function. Shared version.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <gnu/lib-names.h>
+#include <link.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xdlfcn.h>
+
+static void
+local_function (void)
+{
+}
+
+static int
+do_test (void)
+{
+ Dl_info info;
+ void *handle;
+
+ if (dladdr1 (&local_function, &info, &handle, RTLD_DL_HANDLE) == 0)
+ FAIL_EXIT1 ("dladdr1 for local_function failed");
+ /* The main program does not have a soname. */
+ TEST_VERIFY (dlinfo_soname (handle) == NULL);
+
+ /* Check the soname of libc. Use an obscure libc function as
+ reference, to avoid PLT stubs and similar constructs moving the
+ active definition to another object. */
+ void *ptr = xdlsym (NULL, "grantpt");
+ if (dladdr1 (ptr, &info, &handle, RTLD_DL_HANDLE) == 0)
+ FAIL_EXIT1 ("dladdr1 for grantpt failed");
+ TEST_COMPARE_STRING (dlinfo_soname (handle), LIBC_SO);
+
+ /* Check the soname of a library loaded by soname. */
+ void *moddummy1_handle = xdlopen ("moddummy1.so", RTLD_NOW);
+ TEST_COMPARE_STRING (dlinfo_soname (moddummy1_handle), "moddummy1.so");
+
+ /* Check the soname of a library loaded by full path. */
+ char *full_path = xasprintf ("%s/dlfcn/moddummy2.so", support_objdir_root);
+ void *moddummy2_handle = xdlopen (full_path, RTLD_NOW);
+ TEST_COMPARE_STRING (dlinfo_soname (moddummy2_handle), "moddummy2.so");
+ ptr = xdlsym (moddummy2_handle, "grantpt");
+ if (dladdr1 (ptr, &info, &handle, RTLD_DL_HANDLE) == 0)
+ FAIL_EXIT1 ("dladdr1 for grantpt in namespace failed");
+ TEST_COMPARE_STRING (dlinfo_soname (handle), LIBC_SO);
+
+ xdlclose (moddummy2_handle);
+ free (full_path);
+ xdlclose (moddummy1_handle);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -2181,6 +2181,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2145,3 +2145,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
@@ -2225,6 +2225,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -130,6 +130,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
@@ -130,6 +130,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
@@ -2089,3 +2089,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
@@ -2046,6 +2046,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2212,6 +2212,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2078,6 +2078,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -131,6 +131,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0x98
GLIBC_2.4 _IO_2_1_stdin_ D 0x98
@@ -2155,6 +2155,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2137,3 +2137,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
@@ -2137,3 +2137,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
@@ -2129,6 +2129,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2127,6 +2127,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2135,6 +2135,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2129,6 +2129,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2178,3 +2178,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
@@ -2185,6 +2185,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2218,6 +2218,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2048,6 +2048,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2247,3 +2247,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
@@ -2107,3 +2107,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
@@ -2180,6 +2180,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2084,6 +2084,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2050,6 +2050,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2050,6 +2050,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2174,6 +2174,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2101,6 +2101,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2059,6 +2059,7 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2158,3 +2158,4 @@ GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
+GLIBC_2.31 dlinfo_soname F