summaryrefslogtreecommitdiffstats
path: root/man3/dlinfo.3
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--man3/dlinfo.3318
1 files changed, 318 insertions, 0 deletions
diff --git a/man3/dlinfo.3 b/man3/dlinfo.3
new file mode 100644
index 0000000..586663d
--- /dev/null
+++ b/man3/dlinfo.3
@@ -0,0 +1,318 @@
+'\" t
+.\" Copyright (C) 2015 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH dlinfo 3 2023-07-20 "Linux man-pages 6.05.01"
+.SH NAME
+dlinfo \- obtain information about a dynamically loaded object
+.SH LIBRARY
+Dynamic linking library
+.RI ( libdl ", " \-ldl )
+.SH SYNOPSIS
+.nf
+.B #define _GNU_SOURCE
+.B #include <link.h>
+.B #include <dlfcn.h>
+.PP
+.BR "int dlinfo(void *restrict " handle ", int " request \
+", void *restrict " info );
+.fi
+.SH DESCRIPTION
+The
+.BR dlinfo ()
+function obtains information about the dynamically loaded object
+referred to by
+.I handle
+(typically obtained by an earlier call to
+.BR dlopen (3)
+or
+.BR dlmopen (3)).
+The
+.I request
+argument specifies which information is to be returned.
+The
+.I info
+argument is a pointer to a buffer used to store information
+returned by the call; the type of this argument depends on
+.IR request .
+.PP
+The following values are supported for
+.I request
+(with the corresponding type for
+.I info
+shown in parentheses):
+.TP
+.BR RTLD_DI_LMID " (\fILmid_t *\fP)"
+Obtain the ID of the link-map list (namespace) in which
+.I handle
+is loaded.
+.TP
+.BR RTLD_DI_LINKMAP " (\fIstruct link_map **\fP)"
+Obtain a pointer to the
+.I link_map
+structure corresponding to
+.IR handle .
+The
+.I info
+argument points to a pointer to a
+.I link_map
+structure, defined in
+.I <link.h>
+as:
+.IP
+.in +4n
+.EX
+struct link_map {
+ ElfW(Addr) l_addr; /* Difference between the
+ address in the ELF file and
+ the address in memory */
+ char *l_name; /* Absolute pathname where
+ object was found */
+ ElfW(Dyn) *l_ld; /* Dynamic section of the
+ shared object */
+ struct link_map *l_next, *l_prev;
+ /* Chain of loaded objects */
+\&
+ /* Plus additional fields private to the
+ implementation */
+};
+.EE
+.in
+.TP
+.BR RTLD_DI_ORIGIN " (\fIchar *\fP)"
+Copy the pathname of the origin of the shared object corresponding to
+.I handle
+to the location pointed to by
+.IR info .
+.TP
+.BR RTLD_DI_SERINFO " (\fIDl_serinfo *\fP)"
+Obtain the library search paths for the shared object referred to by
+.IR handle .
+The
+.I info
+argument is a pointer to a
+.I Dl_serinfo
+that contains the search paths.
+Because the number of search paths may vary,
+the size of the structure pointed to by
+.I info
+can vary.
+The
+.B RTLD_DI_SERINFOSIZE
+request described below allows applications to size the buffer suitably.
+The caller must perform the following steps:
+.RS
+.IP (1) 5
+Use a
+.B RTLD_DI_SERINFOSIZE
+request to populate a
+.I Dl_serinfo
+structure with the size
+.RI ( dls_size )
+of the structure needed for the subsequent
+.B RTLD_DI_SERINFO
+request.
+.IP (2)
+Allocate a
+.I Dl_serinfo
+buffer of the correct size
+.RI ( dls_size ).
+.IP (3)
+Use a further
+.B RTLD_DI_SERINFOSIZE
+request to populate the
+.I dls_size
+and
+.I dls_cnt
+fields of the buffer allocated in the previous step.
+.IP (4)
+Use a
+.B RTLD_DI_SERINFO
+to obtain the library search paths.
+.RE
+.IP
+The
+.I Dl_serinfo
+structure is defined as follows:
+.IP
+.in +4n
+.EX
+typedef struct {
+ size_t dls_size; /* Size in bytes of
+ the whole buffer */
+ unsigned int dls_cnt; /* Number of elements
+ in \[aq]dls_serpath\[aq] */
+ Dl_serpath dls_serpath[1]; /* Actually longer,
+ \[aq]dls_cnt\[aq] elements */
+} Dl_serinfo;
+.EE
+.in
+.IP
+Each of the
+.I dls_serpath
+elements in the above structure is a structure of the following form:
+.IP
+.in +4n
+.EX
+typedef struct {
+ char *dls_name; /* Name of library search
+ path directory */
+ unsigned int dls_flags; /* Indicates where this
+ directory came from */
+} Dl_serpath;
+.EE
+.in
+.IP
+The
+.I dls_flags
+field is currently unused, and always contains zero.
+.TP
+.BR RTLD_DI_SERINFOSIZE " (\fIDl_serinfo *\fP)"
+Populate the
+.I dls_size
+and
+.I dls_cnt
+fields of the
+.I Dl_serinfo
+structure pointed to by
+.I info
+with values suitable for allocating a buffer for use in a subsequent
+.B RTLD_DI_SERINFO
+request.
+.TP
+.BR RTLD_DI_TLS_MODID " (\fIsize_t *\fP, since glibc 2.4)"
+Obtain the module ID of this shared object's TLS (thread-local storage)
+segment, as used in TLS relocations.
+If this object does not define a TLS segment, zero is placed in
+.IR *info .
+.TP
+.BR RTLD_DI_TLS_DATA " (\fIvoid **\fP, since glibc 2.4)"
+Obtain a pointer to the calling
+thread's TLS block corresponding to this shared object's TLS segment.
+If this object does not define a PT_TLS segment,
+or if the calling thread has not allocated a block for it,
+NULL is placed in
+.IR *info .
+.SH RETURN VALUE
+On success,
+.BR dlinfo ()
+returns 0.
+On failure, it returns \-1; the cause of the error can be diagnosed using
+.BR dlerror (3).
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR dlinfo ()
+T} Thread safety MT-Safe
+.TE
+.sp 1
+.SH VERSIONS
+The sets of requests supported by the various implementations
+overlaps only partially.
+.SH STANDARDS
+GNU.
+.SH HISTORY
+glibc 2.3.3.
+Solaris.
+.SH EXAMPLES
+The program below opens a shared objects using
+.BR dlopen (3)
+and then uses the
+.B RTLD_DI_SERINFOSIZE
+and
+.B RTLD_DI_SERINFO
+requests to obtain the library search path list for the library.
+Here is an example of what we might see when running the program:
+.PP
+.in +4n
+.EX
+$ \fB./a.out /lib64/libm.so.6\fP
+dls_serpath[0].dls_name = /lib64
+dls_serpath[1].dls_name = /usr/lib64
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (dlinfo.c)
+.EX
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <link.h>
+#include <stdio.h>
+#include <stdlib.h>
+\&
+int
+main(int argc, char *argv[])
+{
+ void *handle;
+ Dl_serinfo serinfo;
+ Dl_serinfo *sip;
+\&
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <libpath>\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Obtain a handle for shared object specified on command line. */
+\&
+ handle = dlopen(argv[1], RTLD_NOW);
+ if (handle == NULL) {
+ fprintf(stderr, "dlopen() failed: %s\en", dlerror());
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Discover the size of the buffer that we must pass to
+ RTLD_DI_SERINFO. */
+\&
+ if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == \-1) {
+ fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror());
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Allocate the buffer for use with RTLD_DI_SERINFO. */
+\&
+ sip = malloc(serinfo.dls_size);
+ if (sip == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Initialize the \[aq]dls_size\[aq] and \[aq]dls_cnt\[aq] fields in the newly
+ allocated buffer. */
+\&
+ if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == \-1) {
+ fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror());
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Fetch and print library search list. */
+\&
+ if (dlinfo(handle, RTLD_DI_SERINFO, sip) == \-1) {
+ fprintf(stderr, "RTLD_DI_SERINFO failed: %s\en", dlerror());
+ exit(EXIT_FAILURE);
+ }
+\&
+ for (size_t j = 0; j < serinfo.dls_cnt; j++)
+ printf("dls_serpath[%zu].dls_name = %s\en",
+ j, sip\->dls_serpath[j].dls_name);
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR dl_iterate_phdr (3),
+.BR dladdr (3),
+.BR dlerror (3),
+.BR dlopen (3),
+.BR dlsym (3),
+.BR ld.so (8)