]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man3/dl_iterate_phdr.3
proc.5: Note kernel version for /proc/PID/smaps VmFlags "wf" flag
[thirdparty/man-pages.git] / man3 / dl_iterate_phdr.3
CommitLineData
6736a802 1.\" Copyright (c) 2003, 2017 by Michael Kerrisk <mtk.manpages@gmail.com>
fea681da 2.\"
93015253 3.\" %%%LICENSE_START(VERBATIM)
fea681da
MK
4.\" Permission is granted to make and distribute verbatim copies of this
5.\" manual provided the copyright notice and this permission notice are
6.\" preserved on all copies.
7.\"
8.\" Permission is granted to copy and distribute modified versions of this
9.\" manual under the conditions for verbatim copying, provided that the
10.\" entire resulting derived work is distributed under the terms of a
11.\" permission notice identical to this one
12.\"
13.\" Since the Linux kernel and libraries are constantly changing, this
14.\" manual page may be incorrect or out-of-date. The author(s) assume no
15.\" responsibility for errors or omissions, or for damages resulting from
10d76543
MK
16.\" the use of the information contained herein. The author(s) may not
17.\" have taken the same level of care in the production of this manual,
18.\" which is licensed free of charge, as they might when working
19.\" professionally.
fea681da
MK
20.\"
21.\" Formatted or processed versions of this manual, if unaccompanied by
22.\" the source, must acknowledge the copyright and authors of this work.
4b72fb64 23.\" %%%LICENSE_END
fea681da 24.\"
9ba01802 25.TH DL_ITERATE_PHDR 3 2019-03-06 "GNU" "Linux Programmer's Manual"
fea681da
MK
26.SH NAME
27dl_iterate_phdr \- walk through list of shared objects
28.SH SYNOPSIS
29.nf
b80f966b 30.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
fea681da 31.B #include <link.h>
f90f031e 32.PP
c9942389
MK
33.BI "int dl_iterate_phdr("
34.BI " int (*" callback ") (struct dl_phdr_info *" info ,
fa92a07b
RV
35.BI " size_t " size ", void *" data "),"
36.BI " void *" data ");"
fea681da
MK
37.fi
38.SH DESCRIPTION
39The
d355f1ed 40.BR dl_iterate_phdr ()
cf50118f 41function allows an application to inquire at run time to find
797981eb
MK
42out which shared objects it has loaded,
43and the order in which they were loaded.
847e0d88 44.PP
fea681da 45The
d355f1ed 46.BR dl_iterate_phdr ()
fea681da
MK
47function walks through the list of an
48application's shared objects and calls the function
49.I callback
50once for each object,
51until either all shared objects have been processed or
52.I callback
c7094399 53returns a nonzero value.
847e0d88 54.PP
fea681da
MK
55Each call to
56.I callback
57receives three arguments:
58.IR info ,
59which is a pointer to a structure containing information
60about the shared object;
61.IR size ,
62which is the size of the structure pointed to by
63.IR info ;
64and
65.IR data ,
66which is a copy of whatever value was passed by the calling
67program as the second argument (also named
68.IR data )
69in the call to
d355f1ed 70.BR dl_iterate_phdr ().
847e0d88 71.PP
fea681da
MK
72The
73.I info
74argument is a structure of the following type:
847e0d88 75.PP
088a639b 76.in +4n
b8302363 77.EX
3c8e93ad 78struct dl_phdr_info {
fea681da
MK
79 ElfW(Addr) dlpi_addr; /* Base address of object */
80 const char *dlpi_name; /* (Null-terminated) name of
2968ea1a 81 object */
fea681da
MK
82 const ElfW(Phdr) *dlpi_phdr; /* Pointer to array of
83 ELF program headers
84 for this object */
f81fb444 85 ElfW(Half) dlpi_phnum; /* # of items in \fIdlpi_phdr\fP */
9b14ad2d
MK
86
87 /* The following fields were added in glibc 2.4, after the first
88 version of this structure was available. Check the \fIsize\fP
89 argument passed to the dl_iterate_phdr callback to determine
90 whether or not each later member is available. */
91
92 unsigned long long int dlpi_adds;
93 /* Incremented when a new object may
94 have been added */
95 unsigned long long int dlpi_subs;
96 /* Incremented when an object may
97 have been removed */
98 size_t dlpi_tls_modid;
99 /* If there is a PT_TLS segment, its module
100 ID as used in TLS relocations, else zero */
101 void *dlpi_tls_data;
102 /* The address of the calling thread's instance
103 of this module's PT_TLS segment, if it has
104 one and it has been allocated in the calling
91a2771d 105 thread, otherwise a null pointer */
3c8e93ad 106};
b8302363 107.EE
3c8e93ad 108.in
847e0d88 109.PP
fea681da 110(The
63aa9df0 111.IR ElfW ()
fea681da
MK
112macro definition turns its argument into the name of an ELF data
113type suitable for the hardware architecture.
114For example, on a 32-bit platform,
48a11e1d
MK
115.I ElfW(Addr)
116yields the data type name
117.IR Elf32_Addr .
fea681da
MK
118Further information on these types can be found in the
119.IR <elf.h> " and " <link.h>
120header files.)
847e0d88 121.PP
fea681da
MK
122The
123.I dlpi_addr
124field indicates the base address of the shared object
125(i.e., the difference between the virtual memory address of
126the shared object and the offset of that object in the file
127from which it was loaded).
128The
129.I dlpi_name
130field is a null-terminated string giving the pathname
131from which the shared object was loaded.
847e0d88 132.PP
fea681da
MK
133To understand the meaning of the
134.I dlpi_phdr
135and
136.I dlpi_phnum
137fields, we need to be aware that an ELF shared object consists
138of a number of segments, each of which has a corresponding
139program header describing the segment.
140The
141.I dlpi_phdr
142field is a pointer to an array of the program headers for this
143shared object.
144The
145.I dlpi_phnum
146field indicates the size of this array.
847e0d88 147.PP
fea681da 148These program headers are structures of the following form:
e646a1ba 149.PP
088a639b 150.in +4n
e646a1ba 151.EX
3c8e93ad 152typedef struct {
fea681da
MK
153 Elf32_Word p_type; /* Segment type */
154 Elf32_Off p_offset; /* Segment file offset */
155 Elf32_Addr p_vaddr; /* Segment virtual address */
156 Elf32_Addr p_paddr; /* Segment physical address */
157 Elf32_Word p_filesz; /* Segment size in file */
158 Elf32_Word p_memsz; /* Segment size in memory */
159 Elf32_Word p_flags; /* Segment flags */
160 Elf32_Word p_align; /* Segment alignment */
3c8e93ad 161} Elf32_Phdr;
b8302363 162.EE
3c8e93ad 163.in
847e0d88 164.PP
fea681da
MK
165Note that we can calculate the location of a particular program header,
166.IR x ,
fba59d25 167in virtual memory using the formula:
847e0d88 168.PP
207050fa
MK
169.in +4n
170.EX
171addr == info\->dlpi_addr + info\->dlpi_phdr[x].p_vaddr;
172.EE
173.in
847e0d88 174.PP
c4054f82
MK
175Possible values for
176.I p_type
177include the following (see
178.IR <elf.h>
179for further details):
847e0d88 180.PP
c4054f82 181.in +4n
b8302363 182.EX
c4054f82
MK
183#define PT_LOAD 1 /* Loadable program segment */
184#define PT_DYNAMIC 2 /* Dynamic linking information */
185#define PT_INTERP 3 /* Program interpreter */
186#define PT_NOTE 4 /* Auxiliary information */
187#define PT_SHLIB 5 /* Reserved */
188#define PT_PHDR 6 /* Entry for header table itself */
189#define PT_TLS 7 /* Thread-local storage segment */
190#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
191#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
192.\" For PT_GNU_STACK, see http://www.airs.com/blog/archives/518
193#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
b8302363 194.EE
e646a1ba 195.in
2b2581ee
MK
196.SH RETURN VALUE
197The
198.BR dl_iterate_phdr ()
199function returns whatever value was returned by the last call to
200.IR callback .
24377d40
MK
201.SH VERSIONS
202.BR dl_iterate_phdr ()
203has been supported in glibc since version 2.2.4.
1ee2274c
ZL
204.SH ATTRIBUTES
205For an explanation of the terms used in this section, see
206.BR attributes (7).
207.TS
208allbox;
209lb lb lb
210l l l.
211Interface Attribute Value
212T{
213.BR dl_iterate_phdr ()
214T} Thread safety MT-Safe
215.TE
847e0d88 216.sp 1
47297adb 217.SH CONFORMING TO
2b2581ee
MK
218The
219.BR dl_iterate_phdr ()
c9629ff8
MK
220function is not specified in any standard.
221Various other systems provide a version of this function,
222although details of the returned
223.I dl_phdr_info
224structure differ.
225On the BSDs and Solaris, the structure includes the fields
226.IR dlpi_addr ,
227.IR dlpi_name ,
228.IR dlpi_phdr ,
229and
230.IR dlpi_phnum
231in addition to other implementation-specific fields.
70476aa4
MK
232.SH NOTES
233Future versions of the C library may add further fields to the
234.IR dl_phdr_info
235structure; in that event, the
236.I size
237argument provides a mechanism for the callback function to discover
238whether it is running on a system with added fields.
847e0d88 239.PP
f1e1b550
MK
240The first object visited by
241.IR callback
242is the main program.
243For the main program, the
244.I dlpi_name
245field will be an empty string.
9b336505 246.SH EXAMPLE
c13182ef 247The following program displays a list of pathnames of the
fea681da 248shared objects it has loaded.
6736a802
MK
249For each shared object, the program lists some information
250(virtual address, size, flags, and type)
251for each of the objects ELF segments.
847e0d88 252.PP
6736a802
MK
253The following shell session demonstrates the output
254produced by the program on an x86-64 system.
255The first shared object for which output is displayed
256(where the name is an empty string)
257is the main program.
41a64b30 258.PP
6736a802 259.in +4n
b8302363 260.EX
6736a802
MK
261$ \fB./a.out\fP
262Name: "" (9 segments)
263 0: [ 0x400040; memsz: 1f8] flags: 0x5; PT_PHDR
264 1: [ 0x400238; memsz: 1c] flags: 0x4; PT_INTERP
265 2: [ 0x400000; memsz: ac4] flags: 0x5; PT_LOAD
266 3: [ 0x600e10; memsz: 240] flags: 0x6; PT_LOAD
267 4: [ 0x600e28; memsz: 1d0] flags: 0x6; PT_DYNAMIC
268 5: [ 0x400254; memsz: 44] flags: 0x4; PT_NOTE
269 6: [ 0x400970; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
270 7: [ (nil); memsz: 0] flags: 0x6; PT_GNU_STACK
271 8: [ 0x600e10; memsz: 1f0] flags: 0x4; PT_GNU_RELRO
272Name: "linux-vdso.so.1" (4 segments)
273 0: [0x7ffc6edd1000; memsz: e89] flags: 0x5; PT_LOAD
274 1: [0x7ffc6edd1360; memsz: 110] flags: 0x4; PT_DYNAMIC
275 2: [0x7ffc6edd17b0; memsz: 3c] flags: 0x4; PT_NOTE
276 3: [0x7ffc6edd17ec; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
277Name: "/lib64/libc.so.6" (10 segments)
278 0: [0x7f55712ce040; memsz: 230] flags: 0x5; PT_PHDR
279 1: [0x7f557145b980; memsz: 1c] flags: 0x4; PT_INTERP
280 2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD
281 3: [0x7f55716857a0; memsz: 9240] flags: 0x6; PT_LOAD
282 4: [0x7f5571688b80; memsz: 1f0] flags: 0x6; PT_DYNAMIC
283 5: [0x7f55712ce270; memsz: 44] flags: 0x4; PT_NOTE
284 6: [0x7f55716857a0; memsz: 78] flags: 0x4; PT_TLS
285 7: [0x7f557145b99c; memsz: 544c] flags: 0x4; PT_GNU_EH_FRAME
286 8: [0x7f55712ce000; memsz: 0] flags: 0x6; PT_GNU_STACK
287 9: [0x7f55716857a0; memsz: 3860] flags: 0x4; PT_GNU_RELRO
288Name: "/lib64/ld-linux-x86-64.so.2" (7 segments)
289 0: [0x7f557168f000; memsz: 20828] flags: 0x5; PT_LOAD
290 1: [0x7f55718afba0; memsz: 15a8] flags: 0x6; PT_LOAD
291 2: [0x7f55718afe10; memsz: 190] flags: 0x6; PT_DYNAMIC
292 3: [0x7f557168f1c8; memsz: 24] flags: 0x4; PT_NOTE
293 4: [0x7f55716acec4; memsz: 604] flags: 0x4; PT_GNU_EH_FRAME
294 5: [0x7f557168f000; memsz: 0] flags: 0x6; PT_GNU_STACK
295 6: [0x7f55718afba0; memsz: 460] flags: 0x4; PT_GNU_RELRO
b8302363 296.EE
e646a1ba 297.in
847e0d88 298.PP
6736a802
MK
299.SS Program source
300\&
e7d0bb47 301.EX
fea681da
MK
302#define _GNU_SOURCE
303#include <link.h>
304#include <stdlib.h>
305#include <stdio.h>
306
307static int
308callback(struct dl_phdr_info *info, size_t size, void *data)
309{
6736a802
MK
310 char *type;
311 int p_type, j;
312
d1a71985 313 printf("Name: \e"%s\e" (%d segments)\en", info\->dlpi_name,
6736a802 314 info\->dlpi_phnum);
fea681da 315
6736a802
MK
316 for (j = 0; j < info\->dlpi_phnum; j++) {
317 p_type = info\->dlpi_phdr[j].p_type;
318 type = (p_type == PT_LOAD) ? "PT_LOAD" :
319 (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :
320 (p_type == PT_INTERP) ? "PT_INTERP" :
321 (p_type == PT_NOTE) ? "PT_NOTE" :
322 (p_type == PT_INTERP) ? "PT_INTERP" :
323 (p_type == PT_PHDR) ? "PT_PHDR" :
324 (p_type == PT_TLS) ? "PT_TLS" :
325 (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :
326 (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :
327 (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;
230ed833 328
6736a802
MK
329 printf(" %2d: [%14p; memsz:%7lx] flags: 0x%x; ", j,
330 (void *) (info\->dlpi_addr + info\->dlpi_phdr[j].p_vaddr),
331 info\->dlpi_phdr[j].p_memsz,
332 info\->dlpi_phdr[j].p_flags);
333 if (type != NULL)
d1a71985 334 printf("%s\en", type);
6736a802 335 else
d1a71985 336 printf("[other (0x%x)]\en", p_type);
6736a802 337 }
fea681da 338
fea681da
MK
339 return 0;
340}
341
342int
343main(int argc, char *argv[])
344{
345 dl_iterate_phdr(callback, NULL);
346
347 exit(EXIT_SUCCESS);
348}
e7d0bb47 349.EE
47297adb 350.SH SEE ALSO
fea681da
MK
351.BR ldd (1),
352.BR objdump (1),
353.BR readelf (1),
a7634f01 354.BR dladdr (3),
fea681da 355.BR dlopen (3),
3f89dd3d 356.BR elf (5),
173fe7e7 357.BR ld.so (8)
847e0d88 358.PP
173fe7e7 359.IR "Executable and Linking Format Specification" ,
fea681da 360available at various locations online.