diff options
Diffstat (limited to 'man3/dlinfo.3')
-rw-r--r-- | man3/dlinfo.3 | 318 |
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) |