]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-iteratephdr.c
tst-pidfd.c: UNSUPPORTED if we get EPERM on valid pidfd_getfd call
[thirdparty/glibc.git] / elf / dl-iteratephdr.c
CommitLineData
48ab1c2f 1/* Get loaded objects program headers.
581c785b 2 Copyright (C) 2001-2022 Free Software Foundation, Inc.
48ab1c2f 3 This file is part of the GNU C Library.
48ab1c2f
UD
4
5 The GNU C Library is free software; you can redistribute it and/or
cc7375ce
RM
6 modify it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
48ab1c2f
UD
8 License, or (at your option) any later version.
9
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
cc7375ce 13 Lesser General Public License for more details.
48ab1c2f 14
cc7375ce 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; see the file COPYING.LIB. If
5a82c748 17 not, see <https://www.gnu.org/licenses/>. */
48ab1c2f
UD
18
19#include <errno.h>
20#include <ldsodefs.h>
21#include <stddef.h>
ec999b8e 22#include <libc-lock.h>
48ab1c2f 23
e07bb02a
UD
24static void
25cancel_handler (void *arg __attribute__((unused)))
26{
5a2a1d75 27 __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
e07bb02a
UD
28}
29
48ab1c2f
UD
30int
31__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
32 size_t size, void *data), void *data)
33{
34 struct link_map *l;
35 struct dl_phdr_info info;
36 int ret = 0;
37
5a2a1d75
AS
38 /* Make sure nobody modifies the list of loaded objects. */
39 __rtld_lock_lock_recursive (GL(dl_load_write_lock));
2ae1ae5c 40 __libc_cleanup_push (cancel_handler, NULL);
48ab1c2f 41
c0f62c56
UD
42 /* We have to determine the namespace of the caller since this determines
43 which namespace is reported. */
c0f62c56
UD
44 size_t nloaded = GL(dl_ns)[0]._ns_nloaded;
45 Lmid_t ns = 0;
3a2edc79
UD
46#ifdef SHARED
47 const void *caller = RETURN_ADDRESS (0);
22c83193 48 for (Lmid_t cnt = GL(dl_nns) - 1; cnt > 0; --cnt)
c0f62c56
UD
49 for (struct link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next)
50 {
51 /* We have to count the total number of loaded objects. */
52 nloaded += GL(dl_ns)[cnt]._ns_nloaded;
53
54 if (caller >= (const void *) l->l_map_start
9be09e06
UD
55 && caller < (const void *) l->l_map_end
56 && (l->l_contiguous
57 || _dl_addr_inside_object (l, (ElfW(Addr)) caller)))
c0f62c56
UD
58 ns = cnt;
59 }
3a2edc79 60#endif
c0f62c56
UD
61
62 for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
48ab1c2f 63 {
74718d13
UD
64 info.dlpi_addr = l->l_real->l_addr;
65 info.dlpi_name = l->l_real->l_name;
66 info.dlpi_phdr = l->l_real->l_phdr;
67 info.dlpi_phnum = l->l_real->l_phnum;
bed12f78 68 info.dlpi_adds = GL(dl_load_adds);
c0f62c56 69 info.dlpi_subs = GL(dl_load_adds) - nloaded;
d78efd9f 70 info.dlpi_tls_data = NULL;
74718d13 71 info.dlpi_tls_modid = l->l_real->l_tls_modid;
d78efd9f 72 if (info.dlpi_tls_modid != 0)
74718d13 73 info.dlpi_tls_data = GLRO(dl_tls_get_addr_soft) (l->l_real);
48ab1c2f
UD
74 ret = callback (&info, sizeof (struct dl_phdr_info), data);
75 if (ret)
76 break;
77 }
78
79 /* Release the lock. */
e07bb02a 80 __libc_cleanup_pop (0);
5a2a1d75 81 __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
48ab1c2f
UD
82
83 return ret;
84}
27d640be 85hidden_def (__dl_iterate_phdr)
48ab1c2f 86
48ab1c2f 87weak_alias (__dl_iterate_phdr, dl_iterate_phdr);