1 .\" Copyright (c) 2003, 2017 by Michael Kerrisk <mtk.manpages@gmail.com>
3 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .TH DL_ITERATE_PHDR 3 2021-03-22 "GNU" "Linux Programmer's Manual"
7 dl_iterate_phdr \- walk through list of shared objects
10 .RI ( libc ", " \-lc )
13 .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
16 .B int dl_iterate_phdr(
17 .BI " int (*" callback ")(struct dl_phdr_info *" info ,
18 .BI " size_t " size ", void *" data ),
23 .BR dl_iterate_phdr ()
24 function allows an application to inquire at run time to find
25 out which shared objects it has loaded,
26 and the order in which they were loaded.
29 .BR dl_iterate_phdr ()
30 function walks through the list of an
31 application's shared objects and calls the function
34 until either all shared objects have been processed or
36 returns a nonzero value.
40 receives three arguments:
42 which is a pointer to a structure containing information
43 about the shared object;
45 which is the size of the structure pointed to by
49 which is a copy of whatever value was passed by the calling
50 program as the second argument (also named
53 .BR dl_iterate_phdr ().
57 argument is a structure of the following type:
62 ElfW(Addr) dlpi_addr; /* Base address of object */
63 const char *dlpi_name; /* (Null\-terminated) name of
65 const ElfW(Phdr) *dlpi_phdr; /* Pointer to array of
68 ElfW(Half) dlpi_phnum; /* # of items in \fIdlpi_phdr\fP */
70 /* The following fields were added in glibc 2.4, after the first
71 version of this structure was available. Check the \fIsize\fP
72 argument passed to the dl_iterate_phdr callback to determine
73 whether or not each later member is available. */
75 unsigned long long dlpi_adds;
76 /* Incremented when a new object may
78 unsigned long long dlpi_subs;
79 /* Incremented when an object may
81 size_t dlpi_tls_modid;
82 /* If there is a PT_TLS segment, its module
83 ID as used in TLS relocations, else zero */
85 /* The address of the calling thread\(aqs instance
86 of this module\(aqs PT_TLS segment, if it has
87 one and it has been allocated in the calling
88 thread, otherwise a null pointer */
95 macro definition turns its argument into the name of an ELF data
96 type suitable for the hardware architecture.
97 For example, on a 32-bit platform,
99 yields the data type name
101 Further information on these types can be found in the
102 .IR <elf.h> " and " <link.h>
107 field indicates the base address of the shared object
108 (i.e., the difference between the virtual memory address of
109 the shared object and the offset of that object in the file
110 from which it was loaded).
113 field is a null-terminated string giving the pathname
114 from which the shared object was loaded.
116 To understand the meaning of the
120 fields, we need to be aware that an ELF shared object consists
121 of a number of segments, each of which has a corresponding
122 program header describing the segment.
125 field is a pointer to an array of the program headers for this
129 field indicates the size of this array.
131 These program headers are structures of the following form:
136 Elf32_Word p_type; /* Segment type */
137 Elf32_Off p_offset; /* Segment file offset */
138 Elf32_Addr p_vaddr; /* Segment virtual address */
139 Elf32_Addr p_paddr; /* Segment physical address */
140 Elf32_Word p_filesz; /* Segment size in file */
141 Elf32_Word p_memsz; /* Segment size in memory */
142 Elf32_Word p_flags; /* Segment flags */
143 Elf32_Word p_align; /* Segment alignment */
148 Note that we can calculate the location of a particular program header,
150 in virtual memory using the formula:
154 addr == info\->dlpi_addr + info\->dlpi_phdr[x].p_vaddr;
160 include the following (see
162 for further details):
166 #define PT_LOAD 1 /* Loadable program segment */
167 #define PT_DYNAMIC 2 /* Dynamic linking information */
168 #define PT_INTERP 3 /* Program interpreter */
169 #define PT_NOTE 4 /* Auxiliary information */
170 #define PT_SHLIB 5 /* Reserved */
171 #define PT_PHDR 6 /* Entry for header table itself */
172 #define PT_TLS 7 /* Thread\-local storage segment */
173 #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
174 #define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
175 .\" For PT_GNU_STACK, see http://www.airs.com/blog/archives/518
176 #define PT_GNU_RELRO 0x6474e552 /* Read\-only after relocation */
181 .BR dl_iterate_phdr ()
182 function returns whatever value was returned by the last call to
185 .BR dl_iterate_phdr ()
186 has been supported in glibc since version 2.2.4.
188 For an explanation of the terms used in this section, see
196 Interface Attribute Value
198 .BR dl_iterate_phdr ()
199 T} Thread safety MT-Safe
206 .BR dl_iterate_phdr ()
207 function is not specified in any standard.
208 Various other systems provide a version of this function,
209 although details of the returned
212 On the BSDs and Solaris, the structure includes the fields
218 in addition to other implementation-specific fields.
220 Future versions of the C library may add further fields to the
222 structure; in that event, the
224 argument provides a mechanism for the callback function to discover
225 whether it is running on a system with added fields.
227 The first object visited by
230 For the main program, the
232 field will be an empty string.
234 The following program displays a list of pathnames of the
235 shared objects it has loaded.
236 For each shared object, the program lists some information
237 (virtual address, size, flags, and type)
238 for each of the objects ELF segments.
240 The following shell session demonstrates the output
241 produced by the program on an x86-64 system.
242 The first shared object for which output is displayed
243 (where the name is an empty string)
249 Name: "" (9 segments)
250 0: [ 0x400040; memsz: 1f8] flags: 0x5; PT_PHDR
251 1: [ 0x400238; memsz: 1c] flags: 0x4; PT_INTERP
252 2: [ 0x400000; memsz: ac4] flags: 0x5; PT_LOAD
253 3: [ 0x600e10; memsz: 240] flags: 0x6; PT_LOAD
254 4: [ 0x600e28; memsz: 1d0] flags: 0x6; PT_DYNAMIC
255 5: [ 0x400254; memsz: 44] flags: 0x4; PT_NOTE
256 6: [ 0x400970; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
257 7: [ (nil); memsz: 0] flags: 0x6; PT_GNU_STACK
258 8: [ 0x600e10; memsz: 1f0] flags: 0x4; PT_GNU_RELRO
259 Name: "linux\-vdso.so.1" (4 segments)
260 0: [0x7ffc6edd1000; memsz: e89] flags: 0x5; PT_LOAD
261 1: [0x7ffc6edd1360; memsz: 110] flags: 0x4; PT_DYNAMIC
262 2: [0x7ffc6edd17b0; memsz: 3c] flags: 0x4; PT_NOTE
263 3: [0x7ffc6edd17ec; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
264 Name: "/lib64/libc.so.6" (10 segments)
265 0: [0x7f55712ce040; memsz: 230] flags: 0x5; PT_PHDR
266 1: [0x7f557145b980; memsz: 1c] flags: 0x4; PT_INTERP
267 2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD
268 3: [0x7f55716857a0; memsz: 9240] flags: 0x6; PT_LOAD
269 4: [0x7f5571688b80; memsz: 1f0] flags: 0x6; PT_DYNAMIC
270 5: [0x7f55712ce270; memsz: 44] flags: 0x4; PT_NOTE
271 6: [0x7f55716857a0; memsz: 78] flags: 0x4; PT_TLS
272 7: [0x7f557145b99c; memsz: 544c] flags: 0x4; PT_GNU_EH_FRAME
273 8: [0x7f55712ce000; memsz: 0] flags: 0x6; PT_GNU_STACK
274 9: [0x7f55716857a0; memsz: 3860] flags: 0x4; PT_GNU_RELRO
275 Name: "/lib64/ld\-linux\-x86\-64.so.2" (7 segments)
276 0: [0x7f557168f000; memsz: 20828] flags: 0x5; PT_LOAD
277 1: [0x7f55718afba0; memsz: 15a8] flags: 0x6; PT_LOAD
278 2: [0x7f55718afe10; memsz: 190] flags: 0x6; PT_DYNAMIC
279 3: [0x7f557168f1c8; memsz: 24] flags: 0x4; PT_NOTE
280 4: [0x7f55716acec4; memsz: 604] flags: 0x4; PT_GNU_EH_FRAME
281 5: [0x7f557168f000; memsz: 0] flags: 0x6; PT_GNU_STACK
282 6: [0x7f55718afba0; memsz: 460] flags: 0x4; PT_GNU_RELRO
295 callback(struct dl_phdr_info *info, size_t size, void *data)
300 printf("Name: \e"%s\e" (%d segments)\en", info\->dlpi_name,
303 for (int j = 0; j < info\->dlpi_phnum; j++) {
304 p_type = info\->dlpi_phdr[j].p_type;
305 type = (p_type == PT_LOAD) ? "PT_LOAD" :
306 (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :
307 (p_type == PT_INTERP) ? "PT_INTERP" :
308 (p_type == PT_NOTE) ? "PT_NOTE" :
309 (p_type == PT_INTERP) ? "PT_INTERP" :
310 (p_type == PT_PHDR) ? "PT_PHDR" :
311 (p_type == PT_TLS) ? "PT_TLS" :
312 (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :
313 (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :
314 (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;
316 printf(" %2d: [%14p; memsz:%7jx] flags: %#jx; ", j,
317 (void *) (info\->dlpi_addr + info\->dlpi_phdr[j].p_vaddr),
318 (uintmax_t) info\->dlpi_phdr[j].p_memsz,
319 (uintmax_t) info\->dlpi_phdr[j].p_flags);
321 printf("%s\en", type);
323 printf("[other (%#x)]\en", p_type);
330 main(int argc, char *argv[])
332 dl_iterate_phdr(callback, NULL);
346 .IR "Executable and Linking Format Specification" ,
347 available at various locations online.