1 /* Test for dlinfo (RTLD_DI_PHDR).
2 Copyright (C) 2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
26 #include <support/check.h>
27 #include <support/xdlfcn.h>
29 /* Used to verify that the program header array appears as expected
30 among the dl_iterate_phdr callback invocations. */
32 struct dlip_callback_args
34 struct link_map
*l
; /* l->l_addr is used to find the object. */
35 const ElfW(Phdr
) *phdr
; /* Expected program header pointed. */
36 int phnum
; /* Expected program header count. */
37 bool found
; /* True if l->l_addr has been found. */
41 dlip_callback (struct dl_phdr_info
*dlpi
, size_t size
, void *closure
)
43 TEST_COMPARE (sizeof (*dlpi
), size
);
44 struct dlip_callback_args
*args
= closure
;
46 if (dlpi
->dlpi_addr
== args
->l
->l_addr
)
48 TEST_VERIFY (!args
->found
);
50 TEST_VERIFY (args
->phdr
== dlpi
->dlpi_phdr
);
51 TEST_COMPARE (args
->phnum
, dlpi
->dlpi_phnum
);
60 /* Avoid a copy relocation. */
61 struct r_debug
*debug
= xdlsym (RTLD_DEFAULT
, "_r_debug");
62 struct link_map
*l
= (struct link_map
*) debug
->r_map
;
63 TEST_VERIFY_EXIT (l
!= NULL
);
67 printf ("info: checking link map %p (%p) for \"%s\"\n",
68 l
, l
->l_phdr
, l
->l_name
);
70 /* Cause dlerror () to return an error message. */
71 dlsym (RTLD_DEFAULT
, "does-not-exist");
73 /* Use the extension that link maps are valid dlopen handles. */
74 const ElfW(Phdr
) *phdr
;
75 int phnum
= dlinfo (l
, RTLD_DI_PHDR
, &phdr
);
76 TEST_VERIFY (phnum
>= 0);
77 /* Verify that the error message has been cleared. */
78 TEST_COMPARE_STRING (dlerror (), NULL
);
80 TEST_VERIFY (phdr
== l
->l_phdr
);
81 TEST_COMPARE (phnum
, l
->l_phnum
);
83 /* Check that we can find PT_DYNAMIC among the array. */
85 bool dynamic_found
= false;
86 for (int i
= 0; i
< phnum
; ++i
)
87 if (phdr
[i
].p_type
== PT_DYNAMIC
)
90 TEST_COMPARE ((ElfW(Addr
)) l
->l_ld
, l
->l_addr
+ phdr
[i
].p_vaddr
);
92 TEST_VERIFY (dynamic_found
);
95 /* Check that dl_iterate_phdr finds the link map with the same
98 struct dlip_callback_args args
=
105 TEST_COMPARE (dl_iterate_phdr (dlip_callback
, &args
), 0);
106 TEST_VERIFY (args
.found
);
109 if (l
->l_prev
== NULL
)
111 /* This is the executable, so the information is also
112 available via getauxval. */
113 TEST_COMPARE_STRING (l
->l_name
, "");
114 TEST_VERIFY (phdr
== (const ElfW(Phdr
) *) getauxval (AT_PHDR
));
115 TEST_COMPARE (phnum
, getauxval (AT_PHNUM
));
125 #include <support/test-driver.c>