aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kerrisk <mtk.manpages@gmail.com>2015-07-07 14:37:36 +0200
committerMichael Kerrisk <mtk.manpages@gmail.com>2015-08-08 17:35:43 +0200
commit2b8adcef3dca327e4e97878c7979a97a4a72d097 (patch)
tree9264ebc09b797c3ada43ba4f15dea2089e31fe16
parenta7634f014170e53eb0d6dccb13a7f7264f866519 (diff)
downloadman-pages-2b8adcef3dca327e4e97878c7979a97a4a72d097.tar.gz
dlinfo.3: New page describing dlinfo(3)
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
-rw-r--r--man3/dlinfo.3320
1 files changed, 320 insertions, 0 deletions
diff --git a/man3/dlinfo.3 b/man3/dlinfo.3
new file mode 100644
index 0000000000..5dca26ba13
--- /dev/null
+++ b/man3/dlinfo.3
@@ -0,0 +1,320 @@
+'\" t
+.\" Copyright (C) 2015 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" %%%LICENSE_START(VERBATIM)
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date. The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein. The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" %%%LICENSE_END
+.\"
+.TH DLINFO 3 2015-07-06 "Linux" "Linux Programmer's Manual"
+.SH NAME
+dlinfo \- obtain information about a dynamically loaded object
+.SH SYNOPSIS
+.nf
+.B #define _GNU_SOURCE
+.B #include <link.h>
+.B #include <dlfcn.h>
+
+.BR "int dlinfo(void *" handle ", int " request ", void *" info );
+
+Link with \fI\-ldl\fP.
+.fi
+.SH DESCRIPTION
+The
+.BR dlinfo ()
+function obtains information about the dynamically loaded object
+referred to by
+.IR 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 .
+
+The following values are supported for
+.IR request
+(with the corresponding type for
+.IR 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
+.IR info
+argument points to a pointer to a
+.I link_map
+structure, defined in
+.I <link.h>
+as:
+
+.in +4n
+.nf
+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 */
+};
+.fi
+.in
+.TP
+.BR RTLD_DI_ORIGIN " (\fIchar *\fP)"
+Copy the pathname of the origin of the shared object corresponding to
+.IR 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
+.IR 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. 3
+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.
+.IP
+.RE
+.IP
+The
+.I Dl_serinfo
+structure is defined as follows:
+
+.in +4n
+.nf
+typedef struct {
+ size_t dls_size; /* Size in bytes of
+ the whole buffer */
+ unsigned int dls_cnt; /* Number of elements
+ in 'dls_serpath' */
+ Dl_serpath dls_serpath[1]; /* Actually longer,
+ 'dls_cnt' elements */
+} Dl_serinfo;
+
+.fi
+.in
+Each of the
+.I dls_serpath
+elements in the above structure is a structure of the following form:
+
+.in +4n
+.nf
+typedef struct {
+ char *dls_name; /* Name of library search
+ path directory */
+ unsigned int dls_flags; /* Indicates where this
+ directory came from */
+} Dl_serpath;
+.fi
+.in
+
+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
+.IR 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 VERSIONS
+.BR dlinfo ()
+first appeared in glibc 2.3.3.
+.SH CONFORMING TO
+This function is a nonstandard GNU extension.
+.SH NOTES
+This function derives from the Solaris function of the same name
+and also appears on some other systems.
+The sets of requests supported by the various implementations
+overlaps only partially.
+.SH EXAMPLE
+The program below opens a shared objects using
+.BR dlopen ()
+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:
+.in +4n
+.nf
+.fi
+$ \fB./a.out /lib64/libm.so.6\fP
+dls_serpath[0].dls_name = /lib64
+dls_serpath[1].dls_name = /usr/lib64
+.in
+.SS Program source
+\&
+.nf
+#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;
+ int j;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <libpath>\\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Obtain a handle for shared objects specified on command line */
+
+ handle = dlopen(argv[1], RTLD_NOW);
+ if (handle == NULL) {
+ fprintf(stderr, "dlopen() failed: %s\\n", 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\\n", 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 \(aqdls_size\(aq and \(aqdls_cnt\(aq fields in the newly
+ allocated buffer */
+
+ if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == \-1) {
+ fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\\n", 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\\n", dlerror());
+ exit(EXIT_FAILURE);
+ }
+
+ for (j = 0; j < serinfo.dls_cnt; j++)
+ printf("dls_serpath[%d].dls_name = %s\\n",
+ j, sip\->dls_serpath[j].dls_name);
+
+ exit(EXIT_SUCCESS);
+}
+.fi
+.SH SEE ALSO
+.BR dl_iterate_phdr (3),
+.BR dladdr (3),
+.BR dlopen (3),
+.BR ld.so (8)