]>
Commit | Line | Data |
---|---|---|
320054e8 DG |
1 | #include <elf.h> |
2 | #include <link.h> | |
5d8a1409 | 3 | #include "pthread_impl.h" |
320054e8 DG |
4 | #include "libc.h" |
5 | ||
6 | #define AUX_CNT 38 | |
7 | ||
8 | extern weak hidden const size_t _DYNAMIC[]; | |
9 | ||
10 | static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data) | |
11 | { | |
12 | unsigned char *p; | |
13 | ElfW(Phdr) *phdr, *tls_phdr=0; | |
14 | size_t base = 0; | |
15 | size_t n; | |
16 | struct dl_phdr_info info; | |
17 | size_t i, aux[AUX_CNT] = {0}; | |
18 | ||
19 | for (i=0; libc.auxv[i]; i+=2) | |
20 | if (libc.auxv[i]<AUX_CNT) aux[libc.auxv[i]] = libc.auxv[i+1]; | |
21 | ||
22 | for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) { | |
23 | phdr = (void *)p; | |
24 | if (phdr->p_type == PT_PHDR) | |
25 | base = aux[AT_PHDR] - phdr->p_vaddr; | |
26 | if (phdr->p_type == PT_DYNAMIC && _DYNAMIC) | |
27 | base = (size_t)_DYNAMIC - phdr->p_vaddr; | |
28 | if (phdr->p_type == PT_TLS) | |
29 | tls_phdr = phdr; | |
30 | } | |
31 | info.dlpi_addr = base; | |
32 | info.dlpi_name = "/proc/self/exe"; | |
33 | info.dlpi_phdr = (void *)aux[AT_PHDR]; | |
34 | info.dlpi_phnum = aux[AT_PHNUM]; | |
35 | info.dlpi_adds = 0; | |
36 | info.dlpi_subs = 0; | |
37 | if (tls_phdr) { | |
38 | info.dlpi_tls_modid = 1; | |
5d8a1409 | 39 | info.dlpi_tls_data = __tls_get_addr((tls_mod_off_t[]){1,0}); |
320054e8 DG |
40 | } else { |
41 | info.dlpi_tls_modid = 0; | |
42 | info.dlpi_tls_data = 0; | |
43 | } | |
44 | return (callback)(&info, sizeof (info), data); | |
45 | } | |
46 | ||
47 | weak_alias(static_dl_iterate_phdr, dl_iterate_phdr); |