1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #include <errno.h>
22: #include <ldsodefs.h>
23: #include <stddef.h>
24: #include <bits/libc-lock.h>
25:
26: static void
27: cancel_handler (void *arg __attribute__((unused)))
28: {
29: __rtld_lock_unlock_recursive (GL(dl_load_lock));
30: }
31:
32: hidden_proto (__dl_iterate_phdr)
33: int
34: __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
35: size_t size, void *data), void *data)
36: {
37: struct link_map *l;
38: struct dl_phdr_info info;
39: int ret = 0;
40:
41:
42: __rtld_lock_lock_recursive (GL(dl_load_lock));
43: __libc_cleanup_push (cancel_handler, 0);
44:
45:
46:
47: const void *caller = RETURN_ADDRESS (0);
48: size_t nloaded = GL(dl_ns)[0]._ns_nloaded;
49: Lmid_t ns = 0;
50: for (Lmid_t cnt = DL_NNS - 1; cnt > 0; --cnt)
51: for (struct link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next)
52: {
53:
54: nloaded += GL(dl_ns)[cnt]._ns_nloaded;
55:
56: if (caller >= (const void *) l->l_map_start
57: && caller < (const void *) l->l_map_end
58: && (l->l_contiguous
59: || _dl_addr_inside_object (l, (ElfW(Addr)) caller)))
60: ns = cnt;
61: }
62:
63: for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
64: {
65: info.dlpi_addr = l->l_addr;
66: info.dlpi_name = l->l_name;
67: info.dlpi_phdr = l->l_phdr;
68: info.dlpi_phnum = l->l_phnum;
69: info.dlpi_adds = GL(dl_load_adds);
70: info.dlpi_subs = GL(dl_load_adds) - nloaded;
71: info.dlpi_tls_modid = 0;
72: info.dlpi_tls_data = NULL;
73: info.dlpi_tls_modid = l->l_tls_modid;
74: if (info.dlpi_tls_modid != 0)
75: info.dlpi_tls_data = _dl_tls_get_addr_soft (l);
76: ret = callback (&info, sizeof (struct dl_phdr_info), data);
77: if (ret)
78: break;
79: }
80:
81:
82: __libc_cleanup_pop (0);
83: __rtld_lock_unlock_recursive (GL(dl_load_lock));
84:
85: return ret;
86: }
87: hidden_def (__dl_iterate_phdr)
88:
89: #ifdef SHARED
90:
91: weak_alias (__dl_iterate_phdr, dl_iterate_phdr);
92:
93: #else
94:
95:
96: extern ElfW(Phdr) *_dl_phdr;
97: extern size_t _dl_phnum;
98:
99: int
100: dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
101: size_t size, void *data), void *data)
102: {
103: if (_dl_phnum != 0)
104: {
105:
106: struct dl_phdr_info info;
107: int ret;
108: info.dlpi_addr = 0;
109: info.dlpi_name = "";
110: info.dlpi_phdr = _dl_phdr;
111: info.dlpi_phnum = _dl_phnum;
112: info.dlpi_adds = GL(dl_load_adds);
113: info.dlpi_subs = GL(dl_load_adds) - GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
114: ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
115: if (ret)
116: return ret;
117: }
118:
119: return __dl_iterate_phdr (callback, data);
120: }
121:
122:
123: #endif