-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrtld.h
464 lines (395 loc) · 15.5 KB
/
rtld.h
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
#ifndef __LINE_RTLD_H_
#define __LINE_RTLD_H_
#include <sys/types.h>
#include <stddef.h>
#include "elf.h"
typedef long int Lmid_t;
typedef unsigned long long int hp_timing_t;
#define __SIZEOF_PTHREAD_MUTEX_T 40
struct linux_pthread_mutex_t
{
char __fill[__SIZEOF_PTHREAD_MUTEX_T];
};
#define DL_NNS 16
struct auditstate
{
uintptr_t cookie;
unsigned int bindflags;
};
struct link_map;
struct r_scope_elem
{
/* Array of maps for the scope. */
struct link_map **r_list;
/* Number of entries in the scope. */
unsigned int r_nlist;
} __attribute__((__packed__));
struct r_search_path_elem;
struct r_search_path_struct
{
struct r_search_path_elem **dirs;
int malloced;
};
struct link_map_machine
{
Elf64_Addr plt; /* Address of .plt + 0x16 */
Elf64_Addr gotplt; /* Address of .got + 0x18 */
void *tlsdesc_table; /* Address of TLS descriptor hash table. */
};
#define DT_NUM 34
#define DT_THISPROCNUM 0
#define DT_VERSIONTAGNUM 16
#define DT_EXTRANUM 3
#define DT_VALNUM 12
#define DT_ADDRNUM 11
struct link_map
{
Elf64_Addr l_addr; /* Difference between the address in the ELF
file and the addresses in memory. */
char *l_name; /* Absolute file name object was found in. */
Elf64_Dyn* l_ld; /* Dynamic section of the shared object. */
struct link_map *l_next, *l_prev; /* Chain of loaded objects. */
/* This is an element which is only ever different from a pointer to
the very same copy of this type for ld.so when it is used in more
than one namespace. */
struct link_map *l_real;
Lmid_t l_ns;
struct libname_list *l_libname;
Elf64_Dyn *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM
+ DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM];
const Elf64_Phdr *l_phdr; /* Pointer to program header table in core. */
Elf64_Addr l_entry; /* Entry point location. */
Elf64_Half l_phnum; /* Number of program header entries. */
Elf64_Half l_ldnum; /* Number of dynamic segment entries. */
struct r_scope_elem l_searchlist;
/* We need a special searchlist to process objects marked with
DT_SYMBOLIC. */
struct r_scope_elem l_symbolic_searchlist;
/* Dependent object that first caused this object to be loaded. */
struct link_map *l_loader;
/* Array with version names. */
struct r_found_version *l_versions;
unsigned int l_nversions;
/* Symbol hash table. */
Elf_Symndx l_nbuckets;
Elf64_Word l_gnu_bitmask_idxbits;
Elf64_Word l_gnu_shift;
const Elf64_Addr *l_gnu_bitmask;
union
{
const Elf64_Word *l_gnu_buckets;
const Elf_Symndx *l_chain;
};
union
{
const Elf64_Word *l_gnu_chain_zero;
const Elf_Symndx *l_buckets;
};
unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose. */
enum /* Where this object came from. */
{
lt_executable, /* The main executable program. */
lt_library, /* Library needed by main executable. */
lt_loaded /* Extra run-time loaded shared object. */
} l_type:2;
unsigned int l_relocated:1; /* Nonzero if object's relocations done. */
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */
unsigned int l_reserved:2; /* Reserved for internal use. */
unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
to by `l_phdr' is allocated. */
unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
the l_libname list. */
unsigned int l_faked:1; /* Nonzero if this is a faked descriptor
without associated file. */
unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls)
should be called on this link map
when relocation finishes. */
unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing. */
unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module
is interested in the PLT interception.*/
unsigned int l_removed:1; /* Nozero if the object cannot be used anymore
since it is removed. */
unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
mprotected or if no holes are present at
all. */
unsigned int l_symbolic_in_local_scope:1; /* Nonzero if l_local_scope
during LD_TRACE_PRELINKING=1
contains any DT_SYMBOLIC
libraries. */
unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
freed, ie. not allocated with
the dummy malloc in ld.so. */
/* Collected information about own RPATH directories. */
struct r_search_path_struct l_rpath_dirs;
/* Collected results of relocation while profiling. */
struct reloc_result
{
Elf64_Addr addr;
struct link_map *bound;
unsigned int boundndx;
uint32_t enterexit;
unsigned int flags;
} *l_reloc_result;
/* Pointer to the version information if available. */
Elf64_Versym *l_versyms;
/* String specifying the path where this object was found. */
const char *l_origin;
/* Start and finish of memory map for this object. l_map_start
need not be the same as l_addr. */
Elf64_Addr l_map_start, l_map_end;
/* End of the executable part of the mapping. */
Elf64_Addr l_text_end;
/* Default array for 'l_scope'. */
struct r_scope_elem *l_scope_mem[4];
/* Size of array allocated for 'l_scope'. */
size_t l_scope_max;
/* This is an array defining the lookup scope for this link map.
There are initially at most three different scope lists. */
struct r_scope_elem **l_scope;
/* A similar array, this time only with the local scope. This is
used occasionally. */
struct r_scope_elem *l_local_scope[2];
/* This information is kept to check for sure whether a shared
object is the same as one already loaded. */
dev_t dev;
ino64_t ino;
/* Collected information about own RUNPATH directories. */
struct r_search_path_struct l_runpath_dirs;
/* List of object in order of the init and fini calls. */
struct link_map **l_initfini;
/* List of the dependencies introduced through symbol binding. */
struct link_map_reldeps
{
unsigned int act;
struct link_map *list[];
} *l_reldeps;
unsigned int l_reldepsmax;
/* Nonzero if the DSO is used. */
unsigned int l_used;
/* Various flag words. */
Elf64_Word l_feature_1;
Elf64_Word l_flags_1;
Elf64_Word l_flags;
/* Temporarily used in `dl_close'. */
int l_idx;
struct link_map_machine l_mach;
struct
{
const Elf64_Sym *sym;
int type_class;
struct link_map *value;
const Elf64_Sym *ret;
} l_lookup_cache;
/* Thread-local storage related info. */
/* Start of the initialization image. */
void *l_tls_initimage;
/* Size of the initialization image. */
size_t l_tls_initimage_size;
/* Size of the TLS block. */
size_t l_tls_blocksize;
/* Alignment requirement of the TLS block. */
size_t l_tls_align;
/* Offset of first byte module alignment. */
size_t l_tls_firstbyte_offset;
/* For objects present at startup time: offset in the static TLS block. */
ptrdiff_t l_tls_offset;
/* Index of the module in the dtv array. */
size_t l_tls_modid;
/* Number of thread_local objects constructed by this DSO. This is
atomically accessed and modified and is not always protected by the load
lock. See also: CONCURRENCY NOTES in cxa_thread_atexit_impl.c. */
size_t l_tls_dtor_count;
/* Information used to change permission after the relocations are
done. */
Elf64_Addr l_relro_addr;
size_t l_relro_size;
unsigned long long int l_serial;
/* Audit information. This array apparent must be the last in the
structure. Never add something after it. */
struct auditstate l_audit[0];
};
struct r_debug
{
int r_version; /* Version number for this protocol. */
struct link_map *r_map; /* Head of the chain of loaded objects. */
/* This is the address of a function internal to the run-time linker,
that will always be called when the linker begins to map in a
library or unmap it, and again when the mapping change is complete.
The debugger can set a breakpoint at this address if it wants to
notice shared object mapping changes. */
Elf64_Addr r_brk;
enum
{
/* This state value describes the mapping change taking place when
the `r_brk' address is called. */
RT_CONSISTENT, /* Mapping change is complete. */
RT_ADD, /* Beginning to add a new object. */
RT_DELETE /* Beginning to remove an object mapping. */
} r_state;
Elf64_Addr r_ldbase; /* Base address the linker is loaded at. */
};
struct link_namespaces
{
/* A pointer to the map for the main map. */
struct link_map *_ns_loaded;
/* Number of object in the _dl_loaded list. */
unsigned int _ns_nloaded;
/* Direct pointer to the searchlist of the main object. */
struct r_scope_elem *_ns_main_searchlist;
/* This is zero at program start to signal that the global scope map is
allocated by rtld. Later it keeps the size of the map. It might be
reset if in _dl_close if the last global object is removed. */
size_t _ns_global_scope_alloc;
/* Search table for unique objects. */
struct unique_sym_table
{
linux_pthread_mutex_t lock;
struct unique_sym
{
uint32_t hashval;
const char *name;
const Elf64_Sym *sym;
const struct link_map *map;
} *entries;
size_t size;
size_t n_elements;
void (*free) (void *);
} _ns_unique_sym_table;
/* Keep track of changes to each namespace' list. */
struct r_debug _ns_debug;
};
struct rtld_global
{
link_namespaces _dl_ns[DL_NNS];
size_t _dl_nns;
/* During the program run we must not modify the global data of
loaded shared object simultanously in two threads. Therefore we
protect `_dl_open' and `_dl_close' in dl-close.c.
This must be a recursive lock since the initializer function of
the loaded object might as well require a call to this function.
At this time it is not anymore a problem to modify the tables. */
linux_pthread_mutex_t _dl_load_lock;
/* This lock is used to keep __dl_iterate_phdr from inspecting the
list of loaded objects while an object is added to or removed
from that list. */
linux_pthread_mutex_t _dl_load_write_lock;
/* Incremented whenever something may have been added to dl_loaded. */
unsigned long long _dl_load_adds;
/* The object to be initialized first. */
struct link_map *_dl_initfirst;
/* Start time on CPU clock. */
hp_timing_t _dl_cpuclock_offset;
/* Map of shared object to be profiled. */
struct link_map *_dl_profile_map;
/* Counters for the number of relocations performed. */
unsigned long int _dl_num_relocations;
unsigned long int _dl_num_cache_relocations;
/* List of search directories. */
struct r_search_path_elem *_dl_all_dirs;
uint64_t pad;
// MAYBE?
void **(*_dl_error_catch_tsd) (void) __attribute__ ((const));
/* Structure describing the dynamic linker itself. We need to
reserve memory for the data the audit libraries need. */
struct link_map _dl_rtld_map;
struct auditstate audit_data[DL_NNS];
void (*_dl_rtld_lock_recursive) (void *);
void (*_dl_rtld_unlock_recursive) (void *);
/* If loading a shared object requires that we make the stack executable
when it was not, we do it by calling this function.
It returns an errno code or zero on success. */
int (*_dl_make_stack_executable_hook) (void **);
/* Prevailing state of the stack, PF_X indicating it's executable. */
Elf64_Word _dl_stack_flags;
/* Flag signalling whether there are gaps in the module ID allocation. */
bool _dl_tls_dtv_gaps;
/* Highest dtv index currently needed. */
size_t _dl_tls_max_dtv_idx;
};
enum
{
COMMON_CPUID_INDEX_1 = 0,
COMMON_CPUID_INDEX_7,
COMMON_CPUID_INDEX_80000001, /* for AMD */
/* Keep the following line at the end. */
COMMON_CPUID_INDEX_MAX
};
/* The current maximum size of the feature integer bit array. */
#define FEATURE_INDEX_MAX 1
struct cpu_features
{
enum cpu_features_kind
{
arch_kind_unknown = 0,
arch_kind_intel,
arch_kind_amd,
arch_kind_other
} kind;
int max_cpuid;
struct cpuid_registers
{
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
} cpuid[COMMON_CPUID_INDEX_MAX];
unsigned int family;
unsigned int model;
unsigned int feature[FEATURE_INDEX_MAX];
} __attribute__((__packed__));
struct rtld_global_ro
{
int _dl_debug_mask; // 4 - 0
unsigned int _dl_osversion; // 4 - 4
const char *_dl_platform; // 8 - 8
size_t _dl_platformlen; // 8 - 10
size_t _dl_pagesize; // 8 - 18
int _dl_inhibit_cache; // 4 - 20
struct r_scope_elem _dl_initial_searchlist;
int _dl_clktck;
int _dl_verbose;
int _dl_debug_fd;
int _dl_lazy;
int _dl_bind_not;
int _dl_dynamic_weak;
unsigned int _dl_fpu_control;
int _dl_correct_cache_id;
uint64_t _dl_hwcap;
uint64_t _dl_hwcap_mask;
void* _dl_auxv;
//cpu_features _dl_cpu_features;
//const char _dl_x86_cap_flags[32][8];
//const char _dl_x86_platforms[4][5];
const char *_dl_inhibit_rpath;
const char *_dl_origin_path;
uint64_t _dl_use_load_bias;
char* _dl_profile;
const char *_dl_profile_output;
const char *_dl_trace_prelink;
struct link_map *_dl_trace_prelink_map;
struct r_search_path_elem *_dl_init_all_dirs;
hp_timing_t _dl_hp_timing_overhead;
uintptr_t _dl_sysinfo;
const void* _dl_sysinfo_dso;
struct link_map *_dl_sysinfo_map;
uint64_t _dl_hwcap2;
void (*_dl_debug_printf) (const char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
int (*_dl_catch_error) (const char **, const char **, bool *, void (*) (void *), void *);
void (*_dl_signal_error) (int, const char *, const char *, const char *);
void (*_dl_mcount) (Elf64_Addr frompc, Elf64_Addr selfpc);
uint64_t (*_dl_lookup_symbol_x) (
const char *,
struct link_map *,
const Elf64_Sym **,
struct r_scope_elem *[],
const struct r_found_version *,
int, int,
struct link_map *);
int (*_dl_check_caller) (const void *, int allowmask);
void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen,
Lmid_t nsid, int argc, char *argv[], char *env[]);
void (*_dl_close) (void *map);
void *(*_dl_tls_get_addr_soft) (struct link_map *);
} __attribute__((__packed__));
#endif