The GNU C Library provides various facilities for querying information from the dynamic linker.
A link map is associated with the main executable and each shared
object. Some fields of the link map are accessible to applications and
exposed through the struct link_map
. Applications must not modify
the link map directly.
Pointers to link maps can be obtained from the _r_debug
variable,
from the RTLD_DI_LINKMAP
request for dlinfo
, and from the
_dl_find_object
function. See below for details.
l_addr
¶This field contains the load address of the object. This is the
offset that needs to be applied to unrelocated addresses in the object
image (as stored on disk) to form an address that can be used at run
time for accessing data or running code. For position-dependent
executables, the load address is typically zero, and no adjustment is
required. For position-independent objects, the l_addr
field
usually contains the address of the object’s ELF header in the process
image. However, this correspondence is not guaranteed because the ELF
header might not be mapped at all, and the ELF file as stored on disk
might use zero as the lowest virtual address. Due to the second
variable, values of the l_addr
field do not necessarily uniquely
identify a shared object.
On Linux, to obtain the lowest loaded address of the main program, use
getauxval
to obtain the AT_PHDR
and AT_PHNUM
values
for the current process. Alternatively, call
‘dlinfo (_r_debug.r_map, &phdr)’
to obtain the number of program headers, and the address of the program
header array will be stored in phdr
(of type const ElfW(Phdr) *
, as explained below).
These values allow processing the array of program headers and the
address information in the PT_LOAD
entries among them.
This works even when the program was started with an explicit loader
invocation.
l_name
For a shared object, this field contains the file name that the
the GNU C Library dynamic loader used when opening the object. This can be
a relative path (relative to the current directory at process start,
or if the object was loaded later, via dlopen
or
dlmopen
). Symbolic links are not necessarily resolved.
For the main executable, l_name
is ‘""’ (the empty string).
(The main executable is not loaded by the GNU C Library, so its file name is
not available.) On Linux, the main executable is available as
/proc/self/exe (unless an explicit loader invocation was used to
start the program). The file name /proc/self/exe continues to
resolve to the same file even if it is moved within or deleted from the
file system. Its current location can be read using readlink
.
See Symbolic Links. (Although /proc/self/exe is not actually
a symbol link, it is only presented as one.) Note that /proc may
not be mounted, in which case /proc/self/exe is not available.
If an explicit loader invocation is used (such as ‘ld.so
/usr/bin/emacs’), the /proc/self/exe approach does not work
because the file name refers to the dynamic linker ld.so
, and not
the /usr/bin/emacs
program. An approximation to the executable
path is still available in the info.dli_fname
member after
calling ‘dladdr (_r_debug.r_map->l_ld, &info)’. Note that
this could be a relative path, and it is supplied by the process that
created the current process, not the kernel, so it could be inaccurate.
l_ld
This is a pointer to the ELF dynamic segment, an array of tag/value
pairs that provide various pieces of information that the dynamic
linking process uses. On most architectures, addresses in the dynamic
segment are relocated at run time, but on some architectures and in some
run-time configurations, it is necessary to add the l_addr
field
value to obtain a proper address.
l_prev
l_next
These fields are used to maintain a double-linked linked list of all
link maps within one dlmopen
namespace. Note that there is
currently no thread-safe way to iterate over this list. The
callback-based dl_iterate_phdr
interface can be used instead.
Portability note: It is not possible to create a struct
link_map
object and pass a pointer to a function that expects a
struct link_map *
argument. Only link map pointers initially
supplied by the GNU C Library are permitted as arguments. In current versions
of the GNU C Library, handles returned by dlopen
and dlmopen
are
pointers to link maps. However, this is not a portable assumption, and
may even change in future versions of the GNU C Library. To obtain the link
map associated with a handle, see dlinfo
and
RTLD_DI_LINKMAP
below. If a function accepts both
dlopen
/dlmopen
handles and struct link_map
pointers
in its void *
argument, that is documented explicitly.
The dlinfo
function provides access to internal information
associated with dlopen
/dlmopen
handles and link maps.
int
dlinfo (void *handle, int request, void *arg)
¶| MT-Safe | AS-Unsafe corrupt | AC-Unsafe corrupt | See POSIX Safety Concepts.
This function returns information about handle in the memory
location arg, based on request. The handle argument
must be a pointer returned by dlopen
or dlmopen
; it must
not have been closed by dlclose
. Alternatively, handle
can be a struct link_map *
value for a link map of an object
that has not been closed.
On success, dlinfo
returns 0 for most request types; exceptions
are noted below. If there is an error, the function returns -1,
and dlerror
can be used to obtain a corresponding error message.
The following operations are defined for use with request:
RTLD_DI_LINKMAP
¶The corresponding struct link_map
pointer for handle is
written to *arg
. The arg argument must be the
address of an object of type struct link_map *
.
RTLD_DI_LMID
¶The namespace identifier of handle is written to
*arg
. The arg argument must be the address of an
object of type Lmid_t
.
RTLD_DI_ORIGIN
¶The value of the $ORIGIN
dynamic string token for handle is
written to the character array starting at arg as a
null-terminated string.
This request type should not be used because it is prone to buffer overflows.
RTLD_DI_SERINFO
¶RTLD_DI_SERINFOSIZE
¶These requests can be used to obtain search path information for
handle. For both requests, arg must point to a
Dl_serinfo
object. The RTLD_DI_SERINFOSIZE
request must
be made first; it updates the dls_size
and dls_cnt
members
of the Dl_serinfo
object. The caller should then allocate memory
to store at least dls_size
bytes and pass that buffer to a
RTLD_DI_SERINFO
request. This second request fills the
dls_serpath
array. The number of array elements was returned in
the dls_cnt
member in the initial RTLD_DI_SERINFOSIZE
request. The caller is responsible for freeing the allocated buffer.
This interface is prone to buffer overflows in multi-threaded processes
because the required size can change between the
RTLD_DI_SERINFOSIZE
and RTLD_DI_SERINFO
requests.
RTLD_DI_TLS_DATA
¶This request writes the address of the TLS block (in the current thread)
for the shared object identified by handle to *arg
.
The argument arg must be the address of an object of type
void *
. A null pointer is written if the object does not have
any associated TLS block.
RTLD_DI_TLS_MODID
¶This request writes the TLS module ID for the shared object handle
to *arg
. The argument arg must be the address of an
object of type size_t
. The module ID is zero if the object
does not have an associated TLS block.
RTLD_DI_PHDR
¶This request writes the address of the program header array to
*arg
. The argument arg must be the address of an
object of type const ElfW(Phdr) *
(that is,
const Elf32_Phdr *
or const Elf64_Phdr *
, as appropriate
for the current architecture). For this request, the value returned by
dlinfo
is the number of program headers in the program header
array.
The dlinfo
function is a GNU extension.
The remainder of this section documents the _dl_find_object
function and supporting types and constants.
This structure contains information about a main program or loaded
object. The _dl_find_object
function uses it to return
result data to the caller.
unsigned long long int dlfo_flags
Currently unused and always 0.
void *dlfo_map_start
The start address of the inspected mapping. This information comes from the program header, so it follows its convention, and the address is not necessarily page-aligned.
void *dlfo_map_end
The end address of the mapping.
struct link_map *dlfo_link_map
This member contains a pointer to the link map of the object.
void *dlfo_eh_frame
This member contains a pointer to the exception handling data of the
object. See DLFO_EH_SEGMENT_TYPE
below.
This structure is a GNU extension.
int
DLFO_STRUCT_HAS_EH_DBASE ¶On most targets, this macro is defined as 0
. If it is defined to
1
, struct dl_find_object
contains an additional member
dlfo_eh_dbase
of type void *
. It is the base address for
DW_EH_PE_datarel
DWARF encodings to this location.
This macro is a GNU extension.
int
DLFO_STRUCT_HAS_EH_COUNT ¶On most targets, this macro is defined as 0
. If it is defined to
1
, struct dl_find_object
contains an additional member
dlfo_eh_count
of type int
. It is the number of exception
handling entries in the EH frame segment identified by the
dlfo_eh_frame
member.
This macro is a GNU extension.
int
DLFO_EH_SEGMENT_TYPE ¶On targets using DWARF-based exception unwinding, this macro expands to
PT_GNU_EH_FRAME
. This indicates that dlfo_eh_frame
in
struct dl_find_object
points to the PT_GNU_EH_FRAME
segment of the object. On targets that use other unwinding formats, the
macro expands to the program header type for the unwinding data.
This macro is a GNU extension.
int
_dl_find_object (void *address, struct dl_find_object *result)
¶| MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.
On success, this function returns 0 and writes about the object
surrounding the address to *result
. On failure, -1 is
returned.
The address can be a code address or data address. On
architectures using function descriptors, no attempt is made to decode
the function descriptor. Depending on how these descriptors are
implemented, _dl_find_object
may return the object that defines
the function descriptor (and not the object that contains the code
implementing the function), or fail to find any object at all.
On success address is greater than or equal to
result->dlfo_map_start
and less than
result->dlfo_map_end
, that is, the supplied code address is
located within the reported mapping.
This function returns a pointer to the unwinding information for the
object that contains the program code address in
result->dlfo_eh_frame
. If the platform uses DWARF
unwinding information, this is the in-memory address of the
PT_GNU_EH_FRAME
segment. See DLFO_EH_SEGMENT_TYPE
above.
In case address resides in an object that lacks unwinding information,
the function still returns 0, but sets result->dlfo_eh_frame
to a null pointer.
_dl_find_object
itself is thread-safe. However, if the
application invokes dlclose
for the object that contains
address concurrently with _dl_find_object
or after the call
returns, accessing the unwinding data for that object or the link map
(through result->dlfo_link_map
) is not safe. Therefore, the
application needs to ensure by other means (e.g., by convention) that
address remains a valid code address while the unwinding
information is processed.
This function is a GNU extension.