Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#define _GNU_SOURCE
#include <link.h>
#include <stddef.h>
#include <dlfcn.h>
#include <stdio.h>
#include <pthread.h>
struct auditstate {
uintptr_t cookie;
unsigned int bindflags;
};
typedef struct {
pthread_mutex_t mutex;
} __rtld_lock_recursive_t;
struct unique_sym_table {
__rtld_lock_recursive_t lock;
struct unique_sym *entries;
size_t size;
size_t n_elements;
void (*free)(void *);
};
struct my_link_map {
ElfW(Addr) l_addr;
char *l_name;
ElfW(Dyn) *l_ld;
struct my_link_map *l_next;
struct my_link_map *l_prev;
struct my_link_map *l_real;
Lmid_t l_ns;
struct libname_list *l_libname;
ElfW(Dyn) *l_info[76];
const ElfW(Phdr) *l_phdr;
ElfW(Addr) l_entry;
ElfW(Half) l_phnum;
ElfW(Half) l_ldnum;
};
struct link_namespaces {
struct my_link_map *_ns_loaded;
unsigned int _ns_nloaded;
struct r_scope_elem *_ns_main_searchlist;
size_t _ns_global_scope_alloc;
struct unique_sym_table _ns_unique_sym_table;
struct r_debug _ns_debug;
};
typedef unsigned long long hp_timing_t;
struct my_rtld_global {
struct link_namespaces _dl_ns[16];
#if 0
size_t _dl_nns;
__rtld_lock_recursive_t _dl_load_lock;
__rtld_lock_recursive_t _dl_load_write_lock;
unsigned long long _dl_load_adds;
struct link_map *_dl_initfirst;
hp_timing_t _dl_cpuclock_offset;
struct link_map *_dl_profile_map;
unsigned long _dl_num_relocations;
unsigned long _dl_num_cache_relocations;
struct r_search_path_elem *_dl_all_dirs;
void **(*_dl_error_catch_tsd)(void);
struct link_map _dl_rtld_map;
struct auditstate audit_data[16];
void (*_dl_rtld_lock_recursive)(void *);
void (*_dl_rtld_unlock_recursive)(void *);
int (*_dl_make_stack_executable_hook)(void **);
Elf64_Word _dl_stack_flags;
_Bool _dl_tls_dtv_gaps;
size_t _dl_tls_max_dtv_idx;
struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list;
size_t _dl_tls_static_nelem;
size_t _dl_tls_static_size;
size_t _dl_tls_static_used;
size_t _dl_tls_static_align;
void *_dl_initial_dtv;
size_t _dl_tls_generation;
void (*_dl_init_static_tls)(struct link_map *);
void (*_dl_wait_lookup_done)(void);
struct dl_scope_free_list *_dl_scope_free_list;
#endif
};
extern struct my_rtld_global _rtld_global;
#define GL(a) _rtld_global._##a
int
zestcfi__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
size_t size, void *data), void *data)
{
struct my_link_map *l=NULL;
struct dl_phdr_info info;
int ret = 0;
/* Make sure nobody modifies the list of loaded objects. */
// __rtld_lock_lock_recursive (GL(dl_load_write_lock));
// __libc_cleanup_push (cancel_handler, NULL);
/* We have to determine the namespace of the caller since this determines
which namespace is reported. */
size_t nloaded = GL(dl_ns)[0]._ns_nloaded;
Lmid_t ns = 0;
#ifdef SHARED
const void *caller = RETURN_ADDRESS (0);
for (Lmid_t cnt = GL(dl_nns) - 1; cnt > 0; --cnt)
for (struct my_link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next)
{
/* We have to count the total number of loaded objects. */
nloaded += GL(dl_ns)[cnt]._ns_nloaded;
if (caller >= (const void *) l->l_map_start
&& caller < (const void *) l->l_map_end
&& (l->l_contiguous
|| _dl_addr_inside_object (l, (ElfW(Addr)) caller)))
ns = cnt;
}
#endif
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
{
info.dlpi_addr = l->l_real->l_addr;
info.dlpi_name = l->l_real->l_name;
info.dlpi_phdr = l->l_real->l_phdr;
info.dlpi_phnum = l->l_real->l_phnum;
// info.dlpi_adds = GL(dl_load_adds);
// info.dlpi_subs = GL(dl_load_adds) - nloaded;
// info.dlpi_tls_data = NULL;
// info.dlpi_tls_modid = l->l_real->l_tls_modid;
// if (info.dlpi_tls_modid != 0)
// info.dlpi_tls_data = GLRO(dl_tls_get_addr_soft) (l->l_real);
ret = callback (&info, sizeof (struct dl_phdr_info), data);
if (ret)
break;
}
/* Release the lock. */
// __libc_cleanup_pop (0);
// __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
return ret;
}
#ifdef TEST
int test_callback (struct dl_phdr_info *info, size_t size, void *data)
{
printf("In test_callback with info=%p, module=%s\n", info, info->dlpi_name);
return 0;
}
main()
{
printf("My impl:\t");
zestcfi__dl_iterate_phdr (test_callback, NULL);
printf("real impl:\t");
dl_iterate_phdr (test_callback, NULL);
}
#endif