summaryrefslogtreecommitdiffstats
path: root/man3/dl_iterate_phdr.3
diff options
context:
space:
mode:
Diffstat (limited to 'man3/dl_iterate_phdr.3')
-rw-r--r--man3/dl_iterate_phdr.3346
1 files changed, 346 insertions, 0 deletions
diff --git a/man3/dl_iterate_phdr.3 b/man3/dl_iterate_phdr.3
new file mode 100644
index 0000000..dc15758
--- /dev/null
+++ b/man3/dl_iterate_phdr.3
@@ -0,0 +1,346 @@
+'\" t
+.\" Copyright (c) 2003, 2017 by Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH dl_iterate_phdr 3 2023-07-20 "Linux man-pages 6.05.01"
+.SH NAME
+dl_iterate_phdr \- walk through list of shared objects
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
+.B #include <link.h>
+.PP
+.B int dl_iterate_phdr(
+.BI " int (*" callback ")(struct dl_phdr_info *" info ,
+.BI " size_t " size ", void *" data ),
+.BI " void *" data );
+.fi
+.SH DESCRIPTION
+The
+.BR dl_iterate_phdr ()
+function allows an application to inquire at run time to find
+out which shared objects it has loaded,
+and the order in which they were loaded.
+.PP
+The
+.BR dl_iterate_phdr ()
+function walks through the list of an
+application's shared objects and calls the function
+.I callback
+once for each object,
+until either all shared objects have been processed or
+.I callback
+returns a nonzero value.
+.PP
+Each call to
+.I callback
+receives three arguments:
+.IR info ,
+which is a pointer to a structure containing information
+about the shared object;
+.IR size ,
+which is the size of the structure pointed to by
+.IR info ;
+and
+.IR data ,
+which is a copy of whatever value was passed by the calling
+program as the second argument (also named
+.IR data )
+in the call to
+.BR dl_iterate_phdr ().
+.PP
+The
+.I info
+argument is a structure of the following type:
+.PP
+.in +4n
+.EX
+struct dl_phdr_info {
+ ElfW(Addr) dlpi_addr; /* Base address of object */
+ const char *dlpi_name; /* (Null\-terminated) name of
+ object */
+ const ElfW(Phdr) *dlpi_phdr; /* Pointer to array of
+ ELF program headers
+ for this object */
+ ElfW(Half) dlpi_phnum; /* # of items in \fIdlpi_phdr\fP */
+\&
+ /* The following fields were added in glibc 2.4, after the first
+ version of this structure was available. Check the \fIsize\fP
+ argument passed to the dl_iterate_phdr callback to determine
+ whether or not each later member is available. */
+\&
+ unsigned long long dlpi_adds;
+ /* Incremented when a new object may
+ have been added */
+ unsigned long long dlpi_subs;
+ /* Incremented when an object may
+ have been removed */
+ size_t dlpi_tls_modid;
+ /* If there is a PT_TLS segment, its module
+ ID as used in TLS relocations, else zero */
+ void *dlpi_tls_data;
+ /* The address of the calling thread\[aq]s instance
+ of this module\[aq]s PT_TLS segment, if it has
+ one and it has been allocated in the calling
+ thread, otherwise a null pointer */
+};
+.EE
+.in
+.PP
+(The
+.IR ElfW ()
+macro definition turns its argument into the name of an ELF data
+type suitable for the hardware architecture.
+For example, on a 32-bit platform,
+.I ElfW(Addr)
+yields the data type name
+.IR Elf32_Addr .
+Further information on these types can be found in the
+.IR <elf.h> " and " <link.h>
+header files.)
+.PP
+The
+.I dlpi_addr
+field indicates the base address of the shared object
+(i.e., the difference between the virtual memory address of
+the shared object and the offset of that object in the file
+from which it was loaded).
+The
+.I dlpi_name
+field is a null-terminated string giving the pathname
+from which the shared object was loaded.
+.PP
+To understand the meaning of the
+.I dlpi_phdr
+and
+.I dlpi_phnum
+fields, we need to be aware that an ELF shared object consists
+of a number of segments, each of which has a corresponding
+program header describing the segment.
+The
+.I dlpi_phdr
+field is a pointer to an array of the program headers for this
+shared object.
+The
+.I dlpi_phnum
+field indicates the size of this array.
+.PP
+These program headers are structures of the following form:
+.PP
+.in +4n
+.EX
+typedef struct {
+ Elf32_Word p_type; /* Segment type */
+ Elf32_Off p_offset; /* Segment file offset */
+ Elf32_Addr p_vaddr; /* Segment virtual address */
+ Elf32_Addr p_paddr; /* Segment physical address */
+ Elf32_Word p_filesz; /* Segment size in file */
+ Elf32_Word p_memsz; /* Segment size in memory */
+ Elf32_Word p_flags; /* Segment flags */
+ Elf32_Word p_align; /* Segment alignment */
+} Elf32_Phdr;
+.EE
+.in
+.PP
+Note that we can calculate the location of a particular program header,
+.IR x ,
+in virtual memory using the formula:
+.PP
+.in +4n
+.EX
+addr == info\->dlpi_addr + info\->dlpi_phdr[x].p_vaddr;
+.EE
+.in
+.PP
+Possible values for
+.I p_type
+include the following (see
+.I <elf.h>
+for further details):
+.PP
+.in +4n
+.EX
+#define PT_LOAD 1 /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define PT_INTERP 3 /* Program interpreter */
+#define PT_NOTE 4 /* Auxiliary information */
+#define PT_SHLIB 5 /* Reserved */
+#define PT_PHDR 6 /* Entry for header table itself */
+#define PT_TLS 7 /* Thread\-local storage segment */
+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
+.\" For PT_GNU_STACK, see http://www.airs.com/blog/archives/518
+#define PT_GNU_RELRO 0x6474e552 /* Read\-only after relocation */
+.EE
+.in
+.SH RETURN VALUE
+The
+.BR dl_iterate_phdr ()
+function returns whatever value was returned by the last call to
+.IR callback .
+.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 dl_iterate_phdr ()
+T} Thread safety MT-Safe
+.TE
+.sp 1
+.SH VERSIONS
+Various other systems provide a version of this function,
+although details of the returned
+.I dl_phdr_info
+structure differ.
+On the BSDs and Solaris, the structure includes the fields
+.IR dlpi_addr ,
+.IR dlpi_name ,
+.IR dlpi_phdr ,
+and
+.I dlpi_phnum
+in addition to other implementation-specific fields.
+.PP
+Future versions of the C library may add further fields to the
+.I dl_phdr_info
+structure; in that event, the
+.I size
+argument provides a mechanism for the callback function to discover
+whether it is running on a system with added fields.
+.SH STANDARDS
+None.
+.SH HISTORY
+glibc 2.2.4.
+.SH NOTES
+The first object visited by
+.I callback
+is the main program.
+For the main program, the
+.I dlpi_name
+field will be an empty string.
+.SH EXAMPLES
+The following program displays a list of pathnames of the
+shared objects it has loaded.
+For each shared object, the program lists some information
+(virtual address, size, flags, and type)
+for each of the objects ELF segments.
+.PP
+The following shell session demonstrates the output
+produced by the program on an x86-64 system.
+The first shared object for which output is displayed
+(where the name is an empty string)
+is the main program.
+.PP
+.in +4n
+.EX
+$ \fB./a.out\fP
+Name: "" (9 segments)
+ 0: [ 0x400040; memsz: 1f8] flags: 0x5; PT_PHDR
+ 1: [ 0x400238; memsz: 1c] flags: 0x4; PT_INTERP
+ 2: [ 0x400000; memsz: ac4] flags: 0x5; PT_LOAD
+ 3: [ 0x600e10; memsz: 240] flags: 0x6; PT_LOAD
+ 4: [ 0x600e28; memsz: 1d0] flags: 0x6; PT_DYNAMIC
+ 5: [ 0x400254; memsz: 44] flags: 0x4; PT_NOTE
+ 6: [ 0x400970; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
+ 7: [ (nil); memsz: 0] flags: 0x6; PT_GNU_STACK
+ 8: [ 0x600e10; memsz: 1f0] flags: 0x4; PT_GNU_RELRO
+Name: "linux\-vdso.so.1" (4 segments)
+ 0: [0x7ffc6edd1000; memsz: e89] flags: 0x5; PT_LOAD
+ 1: [0x7ffc6edd1360; memsz: 110] flags: 0x4; PT_DYNAMIC
+ 2: [0x7ffc6edd17b0; memsz: 3c] flags: 0x4; PT_NOTE
+ 3: [0x7ffc6edd17ec; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
+Name: "/lib64/libc.so.6" (10 segments)
+ 0: [0x7f55712ce040; memsz: 230] flags: 0x5; PT_PHDR
+ 1: [0x7f557145b980; memsz: 1c] flags: 0x4; PT_INTERP
+ 2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD
+ 3: [0x7f55716857a0; memsz: 9240] flags: 0x6; PT_LOAD
+ 4: [0x7f5571688b80; memsz: 1f0] flags: 0x6; PT_DYNAMIC
+ 5: [0x7f55712ce270; memsz: 44] flags: 0x4; PT_NOTE
+ 6: [0x7f55716857a0; memsz: 78] flags: 0x4; PT_TLS
+ 7: [0x7f557145b99c; memsz: 544c] flags: 0x4; PT_GNU_EH_FRAME
+ 8: [0x7f55712ce000; memsz: 0] flags: 0x6; PT_GNU_STACK
+ 9: [0x7f55716857a0; memsz: 3860] flags: 0x4; PT_GNU_RELRO
+Name: "/lib64/ld\-linux\-x86\-64.so.2" (7 segments)
+ 0: [0x7f557168f000; memsz: 20828] flags: 0x5; PT_LOAD
+ 1: [0x7f55718afba0; memsz: 15a8] flags: 0x6; PT_LOAD
+ 2: [0x7f55718afe10; memsz: 190] flags: 0x6; PT_DYNAMIC
+ 3: [0x7f557168f1c8; memsz: 24] flags: 0x4; PT_NOTE
+ 4: [0x7f55716acec4; memsz: 604] flags: 0x4; PT_GNU_EH_FRAME
+ 5: [0x7f557168f000; memsz: 0] flags: 0x6; PT_GNU_STACK
+ 6: [0x7f55718afba0; memsz: 460] flags: 0x4; PT_GNU_RELRO
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (dl_iterate_phdr.c)
+.EX
+#define _GNU_SOURCE
+#include <link.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+\&
+static int
+callback(struct dl_phdr_info *info, size_t size, void *data)
+{
+ char *type;
+ int p_type;
+\&
+ printf("Name: \e"%s\e" (%d segments)\en", info\->dlpi_name,
+ info\->dlpi_phnum);
+\&
+ for (size_t j = 0; j < info\->dlpi_phnum; j++) {
+ p_type = info\->dlpi_phdr[j].p_type;
+ type = (p_type == PT_LOAD) ? "PT_LOAD" :
+ (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :
+ (p_type == PT_INTERP) ? "PT_INTERP" :
+ (p_type == PT_NOTE) ? "PT_NOTE" :
+ (p_type == PT_INTERP) ? "PT_INTERP" :
+ (p_type == PT_PHDR) ? "PT_PHDR" :
+ (p_type == PT_TLS) ? "PT_TLS" :
+ (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :
+ (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :
+ (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;
+\&
+ printf(" %2zu: [%14p; memsz:%7jx] flags: %#jx; ", j,
+ (void *) (info\->dlpi_addr + info\->dlpi_phdr[j].p_vaddr),
+ (uintmax_t) info\->dlpi_phdr[j].p_memsz,
+ (uintmax_t) info\->dlpi_phdr[j].p_flags);
+ if (type != NULL)
+ printf("%s\en", type);
+ else
+ printf("[other (%#x)]\en", p_type);
+ }
+\&
+ return 0;
+}
+\&
+int
+main(void)
+{
+ dl_iterate_phdr(callback, NULL);
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR ldd (1),
+.BR objdump (1),
+.BR readelf (1),
+.BR dladdr (3),
+.BR dlopen (3),
+.BR elf (5),
+.BR ld.so (8)
+.PP
+.IR "Executable and Linking Format Specification" ,
+available at various locations online.