470 lines
21 KiB
HTML
470 lines
21 KiB
HTML
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML><HEAD><TITLE>Man page of DL_ITERATE_PHDR</TITLE>
|
|
</HEAD><BODY>
|
|
<H1>DL_ITERATE_PHDR</H1>
|
|
Section: Linux Programmer's Manual (3)<BR>Updated: 2019-03-06<BR><A HREF="#index">Index</A>
|
|
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
|
|
|
<A NAME="lbAB"> </A>
|
|
<H2>NAME</H2>
|
|
|
|
dl_iterate_phdr - walk through list of shared objects
|
|
<A NAME="lbAC"> </A>
|
|
<H2>SYNOPSIS</H2>
|
|
|
|
<PRE>
|
|
<B>#define _GNU_SOURCE</B> /* See <A HREF="/cgi-bin/man/man2html?7+feature_test_macros">feature_test_macros</A>(7) */
|
|
<B>#include <<A HREF="file:///usr/include/link.h">link.h</A>></B>
|
|
|
|
<B>int dl_iterate_phdr(</B>
|
|
<B> int (*</B><I>callback</I><B>) (struct dl_phdr_info *</B><I>info</I><B>,</B>
|
|
<B> size_t </B><I>size</I><B>, void *</B><I>data</I><B>),</B>
|
|
<B> void *</B><I>data</I><B>);</B>
|
|
</PRE>
|
|
|
|
<A NAME="lbAD"> </A>
|
|
<H2>DESCRIPTION</H2>
|
|
|
|
The
|
|
<B>dl_iterate_phdr</B>()
|
|
|
|
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.
|
|
<P>
|
|
|
|
The
|
|
<B>dl_iterate_phdr</B>()
|
|
|
|
function walks through the list of an
|
|
application's shared objects and calls the function
|
|
<I>callback</I>
|
|
|
|
once for each object,
|
|
until either all shared objects have been processed or
|
|
<I>callback</I>
|
|
|
|
returns a nonzero value.
|
|
<P>
|
|
|
|
Each call to
|
|
<I>callback</I>
|
|
|
|
receives three arguments:
|
|
<I>info</I>,
|
|
|
|
which is a pointer to a structure containing information
|
|
about the shared object;
|
|
<I>size</I>,
|
|
|
|
which is the size of the structure pointed to by
|
|
<I>info</I>;
|
|
|
|
and
|
|
<I>data</I>,
|
|
|
|
which is a copy of whatever value was passed by the calling
|
|
program as the second argument (also named
|
|
<I>data</I>)
|
|
|
|
in the call to
|
|
<B>dl_iterate_phdr</B>().
|
|
|
|
<P>
|
|
|
|
The
|
|
<I>info</I>
|
|
|
|
argument is a structure of the following type:
|
|
<P>
|
|
|
|
|
|
|
|
struct dl_phdr_info {
|
|
<BR> ElfW(Addr) dlpi_addr; /* Base address of object */
|
|
<BR> const char *dlpi_name; /* (Null-terminated) name of
|
|
<BR> object */
|
|
<BR> const ElfW(Phdr) *dlpi_phdr; /* Pointer to array of
|
|
<BR> ELF program headers
|
|
<BR> for this object */
|
|
<BR> ElfW(Half) dlpi_phnum; /* # of items in <I>dlpi_phdr</I> */
|
|
<P>
|
|
<BR> /* The following fields were added in glibc 2.4, after the first
|
|
<BR> version of this structure was available. Check the <I>size</I>
|
|
<BR> argument passed to the dl_iterate_phdr callback to determine
|
|
<BR> whether or not each later member is available. */
|
|
<P>
|
|
<BR> unsigned long long int dlpi_adds;
|
|
<BR> /* Incremented when a new object may
|
|
<BR> have been added */
|
|
<BR> unsigned long long int dlpi_subs;
|
|
<BR> /* Incremented when an object may
|
|
<BR> have been removed */
|
|
<BR> size_t dlpi_tls_modid;
|
|
<BR> /* If there is a PT_TLS segment, its module
|
|
<BR> ID as used in TLS relocations, else zero */
|
|
<BR> void *dlpi_tls_data;
|
|
<BR> /* The address of the calling thread's instance
|
|
<BR> of this module's PT_TLS segment, if it has
|
|
<BR> one and it has been allocated in the calling
|
|
<BR> thread, otherwise a null pointer */
|
|
};
|
|
|
|
|
|
<P>
|
|
|
|
(The
|
|
<I>ElfW</I>()
|
|
|
|
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)</I>
|
|
|
|
yields the data type name
|
|
<I>Elf32_Addr</I>.
|
|
|
|
Further information on these types can be found in the
|
|
<I><<A HREF="file:///usr/include/elf.h">elf.h</A>></I> and <I><<A HREF="file:///usr/include/link.h">link.h</A>></I>
|
|
|
|
header files.)
|
|
<P>
|
|
|
|
The
|
|
<I>dlpi_addr</I>
|
|
|
|
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</I>
|
|
|
|
field is a null-terminated string giving the pathname
|
|
from which the shared object was loaded.
|
|
<P>
|
|
|
|
To understand the meaning of the
|
|
<I>dlpi_phdr</I>
|
|
|
|
and
|
|
<I>dlpi_phnum</I>
|
|
|
|
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</I>
|
|
|
|
field is a pointer to an array of the program headers for this
|
|
shared object.
|
|
The
|
|
<I>dlpi_phnum</I>
|
|
|
|
field indicates the size of this array.
|
|
<P>
|
|
|
|
These program headers are structures of the following form:
|
|
<P>
|
|
|
|
|
|
|
|
typedef struct {
|
|
<BR> Elf32_Word p_type; /* Segment type */
|
|
<BR> Elf32_Off p_offset; /* Segment file offset */
|
|
<BR> Elf32_Addr p_vaddr; /* Segment virtual address */
|
|
<BR> Elf32_Addr p_paddr; /* Segment physical address */
|
|
<BR> Elf32_Word p_filesz; /* Segment size in file */
|
|
<BR> Elf32_Word p_memsz; /* Segment size in memory */
|
|
<BR> Elf32_Word p_flags; /* Segment flags */
|
|
<BR> Elf32_Word p_align; /* Segment alignment */
|
|
} Elf32_Phdr;
|
|
|
|
|
|
<P>
|
|
|
|
Note that we can calculate the location of a particular program header,
|
|
<I>x</I>,
|
|
|
|
in virtual memory using the formula:
|
|
<P>
|
|
|
|
|
|
|
|
addr == info->dlpi_addr + info->dlpi_phdr[x].p_vaddr;
|
|
|
|
|
|
<P>
|
|
|
|
Possible values for
|
|
<I>p_type</I>
|
|
|
|
include the following (see
|
|
<I><<A HREF="file:///usr/include/elf.h">elf.h</A>></I>
|
|
|
|
for further details):
|
|
<P>
|
|
|
|
|
|
|
|
#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 */
|
|
|
|
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
|
|
|
|
|
|
<A NAME="lbAE"> </A>
|
|
<H2>RETURN VALUE</H2>
|
|
|
|
The
|
|
<B>dl_iterate_phdr</B>()
|
|
|
|
function returns whatever value was returned by the last call to
|
|
<I>callback</I>.
|
|
|
|
<A NAME="lbAF"> </A>
|
|
<H2>VERSIONS</H2>
|
|
|
|
<B>dl_iterate_phdr</B>()
|
|
|
|
has been supported in glibc since version 2.2.4.
|
|
<A NAME="lbAG"> </A>
|
|
<H2>ATTRIBUTES</H2>
|
|
|
|
For an explanation of the terms used in this section, see
|
|
<B><A HREF="/cgi-bin/man/man2html?7+attributes">attributes</A></B>(7).
|
|
|
|
<TABLE BORDER>
|
|
<TR VALIGN=top><TD><B>Interface</B></TD><TD><B>Attribute</B></TD><TD><B>Value</B><BR></TD></TR>
|
|
<TR VALIGN=top><TD>
|
|
<B>dl_iterate_phdr</B>()
|
|
|
|
</TD><TD>Thread safety</TD><TD>MT-Safe<BR></TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<A NAME="lbAH"> </A>
|
|
<H2>CONFORMING TO</H2>
|
|
|
|
The
|
|
<B>dl_iterate_phdr</B>()
|
|
|
|
function is not specified in any standard.
|
|
Various other systems provide a version of this function,
|
|
although details of the returned
|
|
<I>dl_phdr_info</I>
|
|
|
|
structure differ.
|
|
On the BSDs and Solaris, the structure includes the fields
|
|
<I>dlpi_addr</I>,
|
|
|
|
<I>dlpi_name</I>,
|
|
|
|
<I>dlpi_phdr</I>,
|
|
|
|
and
|
|
<I>dlpi_phnum</I>
|
|
|
|
in addition to other implementation-specific fields.
|
|
<A NAME="lbAI"> </A>
|
|
<H2>NOTES</H2>
|
|
|
|
Future versions of the C library may add further fields to the
|
|
<I>dl_phdr_info</I>
|
|
|
|
structure; in that event, the
|
|
<I>size</I>
|
|
|
|
argument provides a mechanism for the callback function to discover
|
|
whether it is running on a system with added fields.
|
|
<P>
|
|
|
|
The first object visited by
|
|
<I>callback</I>
|
|
|
|
is the main program.
|
|
For the main program, the
|
|
<I>dlpi_name</I>
|
|
|
|
field will be an empty string.
|
|
<A NAME="lbAJ"> </A>
|
|
<H2>EXAMPLE</H2>
|
|
|
|
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.
|
|
<P>
|
|
|
|
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.
|
|
<P>
|
|
|
|
|
|
|
|
$ <B>./a.out</B>
|
|
Name: "" (9 segments)
|
|
<BR> 0: [ 0x400040; memsz: 1f8] flags: 0x5; PT_PHDR
|
|
<BR> 1: [ 0x400238; memsz: 1c] flags: 0x4; PT_INTERP
|
|
<BR> 2: [ 0x400000; memsz: ac4] flags: 0x5; PT_LOAD
|
|
<BR> 3: [ 0x600e10; memsz: 240] flags: 0x6; PT_LOAD
|
|
<BR> 4: [ 0x600e28; memsz: 1d0] flags: 0x6; PT_DYNAMIC
|
|
<BR> 5: [ 0x400254; memsz: 44] flags: 0x4; PT_NOTE
|
|
<BR> 6: [ 0x400970; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
|
|
<BR> 7: [ (nil); memsz: 0] flags: 0x6; PT_GNU_STACK
|
|
<BR> 8: [ 0x600e10; memsz: 1f0] flags: 0x4; PT_GNU_RELRO
|
|
Name: "linux-vdso.so.1" (4 segments)
|
|
<BR> 0: [0x7ffc6edd1000; memsz: e89] flags: 0x5; PT_LOAD
|
|
<BR> 1: [0x7ffc6edd1360; memsz: 110] flags: 0x4; PT_DYNAMIC
|
|
<BR> 2: [0x7ffc6edd17b0; memsz: 3c] flags: 0x4; PT_NOTE
|
|
<BR> 3: [0x7ffc6edd17ec; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
|
|
Name: "/lib64/libc.so.6" (10 segments)
|
|
<BR> 0: [0x7f55712ce040; memsz: 230] flags: 0x5; PT_PHDR
|
|
<BR> 1: [0x7f557145b980; memsz: 1c] flags: 0x4; PT_INTERP
|
|
<BR> 2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD
|
|
<BR> 3: [0x7f55716857a0; memsz: 9240] flags: 0x6; PT_LOAD
|
|
<BR> 4: [0x7f5571688b80; memsz: 1f0] flags: 0x6; PT_DYNAMIC
|
|
<BR> 5: [0x7f55712ce270; memsz: 44] flags: 0x4; PT_NOTE
|
|
<BR> 6: [0x7f55716857a0; memsz: 78] flags: 0x4; PT_TLS
|
|
<BR> 7: [0x7f557145b99c; memsz: 544c] flags: 0x4; PT_GNU_EH_FRAME
|
|
<BR> 8: [0x7f55712ce000; memsz: 0] flags: 0x6; PT_GNU_STACK
|
|
<BR> 9: [0x7f55716857a0; memsz: 3860] flags: 0x4; PT_GNU_RELRO
|
|
Name: "/lib64/ld-linux-x86-64.so.2" (7 segments)
|
|
<BR> 0: [0x7f557168f000; memsz: 20828] flags: 0x5; PT_LOAD
|
|
<BR> 1: [0x7f55718afba0; memsz: 15a8] flags: 0x6; PT_LOAD
|
|
<BR> 2: [0x7f55718afe10; memsz: 190] flags: 0x6; PT_DYNAMIC
|
|
<BR> 3: [0x7f557168f1c8; memsz: 24] flags: 0x4; PT_NOTE
|
|
<BR> 4: [0x7f55716acec4; memsz: 604] flags: 0x4; PT_GNU_EH_FRAME
|
|
<BR> 5: [0x7f557168f000; memsz: 0] flags: 0x6; PT_GNU_STACK
|
|
<BR> 6: [0x7f55718afba0; memsz: 460] flags: 0x4; PT_GNU_RELRO
|
|
|
|
|
|
<P>
|
|
|
|
<A NAME="lbAK"> </A>
|
|
<H3>Program source</H3>
|
|
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
#include <<A HREF="file:///usr/include/link.h">link.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdlib.h">stdlib.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdio.h">stdio.h</A>>
|
|
<P>
|
|
static int
|
|
callback(struct dl_phdr_info *info, size_t size, void *data)
|
|
{
|
|
<BR> char *type;
|
|
<BR> int p_type, j;
|
|
<P>
|
|
<BR> printf("Name: \"%s\" (%d segments)\n", info->dlpi_name,
|
|
<BR> info->dlpi_phnum);
|
|
<P>
|
|
<BR> for (j = 0; j < info->dlpi_phnum; j++) {
|
|
<BR> p_type = info->dlpi_phdr[j].p_type;
|
|
<BR> type = (p_type == PT_LOAD) ? "PT_LOAD" :
|
|
<BR> (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :
|
|
<BR> (p_type == PT_INTERP) ? "PT_INTERP" :
|
|
<BR> (p_type == PT_NOTE) ? "PT_NOTE" :
|
|
<BR> (p_type == PT_INTERP) ? "PT_INTERP" :
|
|
<BR> (p_type == PT_PHDR) ? "PT_PHDR" :
|
|
<BR> (p_type == PT_TLS) ? "PT_TLS" :
|
|
<BR> (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :
|
|
<BR> (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :
|
|
<BR> (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;
|
|
<P>
|
|
<BR> printf(" %2d: [%14p; memsz:%7lx] flags: 0x%x; ", j,
|
|
<BR> (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr),
|
|
<BR> info->dlpi_phdr[j].p_memsz,
|
|
<BR> info->dlpi_phdr[j].p_flags);
|
|
<BR> if (type != NULL)
|
|
<BR> printf("%s\n", type);
|
|
<BR> else
|
|
<BR> printf("[other (0x%x)]\n", p_type);
|
|
<BR> }
|
|
<P>
|
|
<BR> return 0;
|
|
}
|
|
<P>
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
<BR> dl_iterate_phdr(callback, NULL);
|
|
<P>
|
|
<BR> exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
<A NAME="lbAL"> </A>
|
|
<H2>SEE ALSO</H2>
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?1+ldd">ldd</A></B>(1),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?1+objdump">objdump</A></B>(1),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?1+readelf">readelf</A></B>(1),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?3+dladdr">dladdr</A></B>(3),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?3+dlopen">dlopen</A></B>(3),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?5+elf">elf</A></B>(5),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?8+ld.so">ld.so</A></B>(8)
|
|
|
|
<P>
|
|
|
|
<I>Executable and Linking Format Specification</I>,
|
|
|
|
available at various locations online.
|
|
<A NAME="lbAM"> </A>
|
|
<H2>COLOPHON</H2>
|
|
|
|
This page is part of release 5.05 of the Linux
|
|
<I>man-pages</I>
|
|
|
|
project.
|
|
A description of the project,
|
|
information about reporting bugs,
|
|
and the latest version of this page,
|
|
can be found at
|
|
<A HREF="https://www.kernel.org/doc/man-pages/.">https://www.kernel.org/doc/man-pages/.</A>
|
|
<P>
|
|
|
|
<HR>
|
|
<A NAME="index"> </A><H2>Index</H2>
|
|
<DL>
|
|
<DT id="1"><A HREF="#lbAB">NAME</A><DD>
|
|
<DT id="2"><A HREF="#lbAC">SYNOPSIS</A><DD>
|
|
<DT id="3"><A HREF="#lbAD">DESCRIPTION</A><DD>
|
|
<DT id="4"><A HREF="#lbAE">RETURN VALUE</A><DD>
|
|
<DT id="5"><A HREF="#lbAF">VERSIONS</A><DD>
|
|
<DT id="6"><A HREF="#lbAG">ATTRIBUTES</A><DD>
|
|
<DT id="7"><A HREF="#lbAH">CONFORMING TO</A><DD>
|
|
<DT id="8"><A HREF="#lbAI">NOTES</A><DD>
|
|
<DT id="9"><A HREF="#lbAJ">EXAMPLE</A><DD>
|
|
<DL>
|
|
<DT id="10"><A HREF="#lbAK">Program source</A><DD>
|
|
</DL>
|
|
<DT id="11"><A HREF="#lbAL">SEE ALSO</A><DD>
|
|
<DT id="12"><A HREF="#lbAM">COLOPHON</A><DD>
|
|
</DL>
|
|
<HR>
|
|
This document was created by
|
|
<A HREF="/cgi-bin/man/man2html">man2html</A>,
|
|
using the manual pages.<BR>
|
|
Time: 00:05:38 GMT, March 31, 2021
|
|
</BODY>
|
|
</HTML>
|