lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | /* Get loaded objects program headers. |
| 2 | |
| 3 | Based on GNU C library (file: libc/elf/dl-iteratephdr.c) |
| 4 | |
| 5 | Copyright (C) 2001,2002,2003,2004,2006,2007 Free Software Foundation, Inc. |
| 6 | Contributed by Jakub Jelinek <jakub@redhat.com>, 2001. |
| 7 | |
| 8 | Copyright (C) 2008 STMicroelectronics Ltd. |
| 9 | Author: Carmelo Amoroso <carmelo.amoroso@st.com> |
| 10 | |
| 11 | Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. |
| 12 | */ |
| 13 | |
| 14 | |
| 15 | #include <link.h> |
| 16 | #include <ldso.h> |
| 17 | |
| 18 | /* we want this in libc but nowhere else */ |
| 19 | #ifdef __USE_GNU |
| 20 | |
| 21 | extern __typeof(dl_iterate_phdr) __dl_iterate_phdr; |
| 22 | |
| 23 | hidden_proto(__dl_iterate_phdr) |
| 24 | int |
| 25 | __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data) |
| 26 | { |
| 27 | int ret = 0; |
| 28 | #ifndef __ARCH_HAS_NO_SHARED__ |
| 29 | struct elf_resolve *l; |
| 30 | struct dl_phdr_info info; |
| 31 | |
| 32 | for (l = _dl_loaded_modules; l != NULL; l = l->next) { |
| 33 | info.dlpi_addr = l->loadaddr; |
| 34 | info.dlpi_name = l->libname; |
| 35 | info.dlpi_phdr = l->ppnt; |
| 36 | info.dlpi_phnum = l->n_phent; |
| 37 | ret = callback (&info, sizeof (struct dl_phdr_info), data); |
| 38 | if (ret) |
| 39 | break; |
| 40 | } |
| 41 | #endif |
| 42 | return ret; |
| 43 | } |
| 44 | hidden_def (__dl_iterate_phdr) |
| 45 | |
| 46 | # ifdef SHARED |
| 47 | |
| 48 | weak_alias(__dl_iterate_phdr, dl_iterate_phdr) |
| 49 | |
| 50 | # else |
| 51 | |
| 52 | /* dl-support.c defines these and initializes them early on. */ |
| 53 | extern ElfW(Phdr) *_dl_phdr; |
| 54 | extern size_t _dl_phnum; |
| 55 | |
| 56 | int |
| 57 | dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, |
| 58 | size_t size, void *data), void *data) |
| 59 | { |
| 60 | if (_dl_phnum != 0) |
| 61 | { |
| 62 | /* This entry describes this statically-linked program itself. */ |
| 63 | struct dl_phdr_info info; |
| 64 | int ret; |
| 65 | #if defined(__FDPIC__) |
| 66 | info.dlpi_addr.map = NULL; |
| 67 | info.dlpi_addr.got_value = NULL; |
| 68 | #elif defined(__DSBT__) |
| 69 | info.dlpi_addr.map = NULL; |
| 70 | #else |
| 71 | info.dlpi_addr = 0; |
| 72 | #endif |
| 73 | info.dlpi_name = ""; |
| 74 | info.dlpi_phdr = _dl_phdr; |
| 75 | info.dlpi_phnum = _dl_phnum; |
| 76 | ret = (*callback) (&info, sizeof (struct dl_phdr_info), data); |
| 77 | if (ret) |
| 78 | return ret; |
| 79 | } |
| 80 | /* Then invoke callback on loaded modules, if any */ |
| 81 | return __dl_iterate_phdr (callback, data); |
| 82 | } |
| 83 | |
| 84 | # endif |
| 85 | #endif |