]>
Commit | Line | Data |
---|---|---|
7e6d3809 UD |
1 | /* Data structure for communication from the run-time dynamic linker for |
2 | loaded ELF shared objects. | |
04277e02 | 3 | Copyright (C) 1995-2019 Free Software Foundation, Inc. |
7e6d3809 UD |
4 | This file is part of the GNU C Library. |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either | |
9 | version 2.1 of the License, or (at your option) any later version. | |
7e6d3809 UD |
10 | |
11 | The GNU C Library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 14 | Lesser General Public License for more details. |
7e6d3809 | 15 | |
41bdb6e2 | 16 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 | 17 | License along with the GNU C Library; if not, see |
5a82c748 | 18 | <https://www.gnu.org/licenses/>. */ |
7e6d3809 | 19 | |
d78efd9f RM |
20 | #ifndef _PRIVATE_LINK_H |
21 | #define _PRIVATE_LINK_H 1 | |
7e6d3809 | 22 | |
d78efd9f RM |
23 | #ifdef _LINK_H |
24 | # error this should be impossible | |
25 | #endif | |
26 | ||
47755784 | 27 | # ifndef _ISOMAC |
d78efd9f RM |
28 | /* Get most of the contents from the public header, but we define a |
29 | different `struct link_map' type for private use. The la_objopen | |
30 | prototype uses the type, so we have to declare it separately. */ | |
47755784 ZW |
31 | # define link_map link_map_public |
32 | # define la_objopen la_objopen_wrongproto | |
33 | # endif | |
34 | ||
d78efd9f | 35 | #include <elf/link.h> |
47755784 ZW |
36 | |
37 | # ifndef _ISOMAC | |
38 | ||
d78efd9f RM |
39 | #undef link_map |
40 | #undef la_objopen | |
41 | ||
42 | struct link_map; | |
43 | extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid, | |
44 | uintptr_t *__cookie); | |
7e6d3809 | 45 | |
e054f494 | 46 | #include <stdint.h> |
d78efd9f | 47 | #include <stddef.h> |
522e02ab | 48 | #include <linkmap.h> |
c01ae97e | 49 | #include <dl-fileid.h> |
a334319f | 50 | #include <dl-lookupcfg.h> |
b52bbc1b | 51 | #include <tls.h> |
ec999b8e | 52 | #include <libc-lock.h> |
7e6d3809 | 53 | |
7e6d3809 UD |
54 | |
55 | /* Some internal data structures of the dynamic linker used in the | |
56 | linker map. We only provide forward declarations. */ | |
57 | struct libname_list; | |
58 | struct r_found_version; | |
59 | struct r_search_path_elem; | |
60 | ||
61 | /* Forward declaration. */ | |
62 | struct link_map; | |
63 | ||
64 | /* Structure to describe a single list of scope elements. The lookup | |
65 | functions get passed an array of pointers to such structures. */ | |
66 | struct r_scope_elem | |
67 | { | |
68 | /* Array of maps for the scope. */ | |
69 | struct link_map **r_list; | |
70 | /* Number of entries in the scope. */ | |
71 | unsigned int r_nlist; | |
7e6d3809 UD |
72 | }; |
73 | ||
74 | ||
f55727ca UD |
75 | /* Structure to record search path and allocation mechanism. */ |
76 | struct r_search_path_struct | |
77 | { | |
78 | struct r_search_path_elem **dirs; | |
79 | int malloced; | |
80 | }; | |
81 | ||
f63b7381 FW |
82 | /* Type used by the l_nodelete member. */ |
83 | enum link_map_nodelete | |
84 | { | |
85 | /* This link map can be deallocated. */ | |
86 | link_map_nodelete_inactive = 0, /* Zero-initialized in _dl_new_object. */ | |
87 | ||
88 | /* This link map cannot be deallocated. */ | |
89 | link_map_nodelete_active, | |
90 | ||
91 | /* This link map cannot be deallocated after dlopen has succeded. | |
92 | dlopen turns this into link_map_nodelete_active. dlclose treats | |
93 | this intermediate state as link_map_nodelete_active. */ | |
94 | link_map_nodelete_pending, | |
95 | }; | |
96 | ||
f55727ca | 97 | |
7e6d3809 UD |
98 | /* Structure describing a loaded shared object. The `l_next' and `l_prev' |
99 | members form a chain of all the shared objects loaded at startup. | |
100 | ||
101 | These data structures exist in space used by the run-time dynamic linker; | |
102 | modifying them may have disastrous results. | |
103 | ||
104 | This data structure might change in future, if necessary. User-level | |
105 | programs must avoid defining objects of this type. */ | |
106 | ||
107 | struct link_map | |
108 | { | |
109 | /* These first few members are part of the protocol with the debugger. | |
110 | This is the same format used in SVR4. */ | |
111 | ||
542f9466 JK |
112 | ElfW(Addr) l_addr; /* Difference between the address in the ELF |
113 | file and the addresses in memory. */ | |
7e6d3809 UD |
114 | char *l_name; /* Absolute file name object was found in. */ |
115 | ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */ | |
116 | struct link_map *l_next, *l_prev; /* Chain of loaded objects. */ | |
117 | ||
118 | /* All following members are internal to the dynamic linker. | |
119 | They may change without notice. */ | |
120 | ||
c0f62c56 UD |
121 | /* This is an element which is only ever different from a pointer to |
122 | the very same copy of this type for ld.so when it is used in more | |
123 | than one namespace. */ | |
124 | struct link_map *l_real; | |
125 | ||
126 | /* Number of the namespace this link map belongs to. */ | |
127 | Lmid_t l_ns; | |
128 | ||
7e6d3809 UD |
129 | struct libname_list *l_libname; |
130 | /* Indexed pointers to dynamic section. | |
131 | [0,DT_NUM) are indexed by the processor-independent tags. | |
132 | [DT_NUM,DT_NUM+DT_THISPROCNUM) are indexed by the tag minus DT_LOPROC. | |
32e6df36 UD |
133 | [DT_NUM+DT_THISPROCNUM,DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM) are |
134 | indexed by DT_VERSIONTAGIDX(tagvalue). | |
7e6d3809 | 135 | [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM, |
32e6df36 UD |
136 | DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM) are indexed by |
137 | DT_EXTRATAGIDX(tagvalue). | |
138 | [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM, | |
139 | DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM) are | |
140 | indexed by DT_VALTAGIDX(tagvalue) and | |
141 | [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM, | |
142 | DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM+DT_ADDRNUM) | |
143 | are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */ | |
7e6d3809 UD |
144 | |
145 | ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM | |
11bf311e | 146 | + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM]; |
7e6d3809 UD |
147 | const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */ |
148 | ElfW(Addr) l_entry; /* Entry point location. */ | |
149 | ElfW(Half) l_phnum; /* Number of program header entries. */ | |
871b9158 | 150 | ElfW(Half) l_ldnum; /* Number of dynamic segment entries. */ |
7e6d3809 UD |
151 | |
152 | /* Array of DT_NEEDED dependencies and their dependencies, in | |
153 | dependency order for symbol lookup (with and without | |
154 | duplicates). There is no entry before the dependencies have | |
155 | been loaded. */ | |
156 | struct r_scope_elem l_searchlist; | |
157 | ||
158 | /* We need a special searchlist to process objects marked with | |
159 | DT_SYMBOLIC. */ | |
160 | struct r_scope_elem l_symbolic_searchlist; | |
161 | ||
162 | /* Dependent object that first caused this object to be loaded. */ | |
163 | struct link_map *l_loader; | |
164 | ||
341c566f UD |
165 | /* Array with version names. */ |
166 | struct r_found_version *l_versions; | |
167 | unsigned int l_nversions; | |
168 | ||
7e6d3809 UD |
169 | /* Symbol hash table. */ |
170 | Elf_Symndx l_nbuckets; | |
871b9158 UD |
171 | Elf32_Word l_gnu_bitmask_idxbits; |
172 | Elf32_Word l_gnu_shift; | |
173 | const ElfW(Addr) *l_gnu_bitmask; | |
174 | union | |
175 | { | |
176 | const Elf32_Word *l_gnu_buckets; | |
177 | const Elf_Symndx *l_chain; | |
178 | }; | |
179 | union | |
180 | { | |
181 | const Elf32_Word *l_gnu_chain_zero; | |
182 | const Elf_Symndx *l_buckets; | |
183 | }; | |
7e6d3809 | 184 | |
c0f62c56 | 185 | unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose. */ |
7e6d3809 UD |
186 | enum /* Where this object came from. */ |
187 | { | |
188 | lt_executable, /* The main executable program. */ | |
189 | lt_library, /* Library needed by main executable. */ | |
190 | lt_loaded /* Extra run-time loaded shared object. */ | |
191 | } l_type:2; | |
192 | unsigned int l_relocated:1; /* Nonzero if object's relocations done. */ | |
193 | unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ | |
194 | unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ | |
195 | unsigned int l_reserved:2; /* Reserved for internal use. */ | |
196 | unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed | |
197 | to by `l_phdr' is allocated. */ | |
c91bc73e UD |
198 | unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in |
199 | the l_libname list. */ | |
a881e0a0 UD |
200 | unsigned int l_faked:1; /* Nonzero if this is a faked descriptor |
201 | without associated file. */ | |
adc12574 UD |
202 | unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls) |
203 | should be called on this link map | |
204 | when relocation finishes. */ | |
9dcafc55 UD |
205 | unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing. */ |
206 | unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module | |
207 | is interested in the PLT interception.*/ | |
20fe49b9 UD |
208 | unsigned int l_removed:1; /* Nozero if the object cannot be used anymore |
209 | since it is removed. */ | |
9be09e06 UD |
210 | unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are |
211 | mprotected or if no holes are present at | |
212 | all. */ | |
4ad43b62 UD |
213 | unsigned int l_symbolic_in_local_scope:1; /* Nonzero if l_local_scope |
214 | during LD_TRACE_PRELINKING=1 | |
215 | contains any DT_SYMBOLIC | |
216 | libraries. */ | |
0479b305 AS |
217 | unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be |
218 | freed, ie. not allocated with | |
219 | the dummy malloc in ld.so. */ | |
9dcafc55 | 220 | |
f63b7381 FW |
221 | /* Actually of type enum link_map_nodelete. Separate byte due to |
222 | a read in add_dependency in elf/dl-lookup.c outside the loader | |
223 | lock. Only valid for l_type == lt_loaded. */ | |
224 | unsigned char l_nodelete; | |
225 | ||
4a306ef1 L |
226 | #include <link_map.h> |
227 | ||
7e6d3809 | 228 | /* Collected information about own RPATH directories. */ |
f55727ca | 229 | struct r_search_path_struct l_rpath_dirs; |
7e6d3809 UD |
230 | |
231 | /* Collected results of relocation while profiling. */ | |
9dcafc55 UD |
232 | struct reloc_result |
233 | { | |
6aa10807 | 234 | DL_FIXUP_VALUE_TYPE addr; |
9dcafc55 UD |
235 | struct link_map *bound; |
236 | unsigned int boundndx; | |
237 | uint32_t enterexit; | |
238 | unsigned int flags; | |
e5d262ef TMQMF |
239 | /* CONCURRENCY NOTE: This is used to guard the concurrent initialization |
240 | of the relocation result across multiple threads. See the more | |
241 | detailed notes in elf/dl-runtime.c. */ | |
242 | unsigned int init; | |
9dcafc55 | 243 | } *l_reloc_result; |
7e6d3809 UD |
244 | |
245 | /* Pointer to the version information if available. */ | |
246 | ElfW(Versym) *l_versyms; | |
247 | ||
248 | /* String specifying the path where this object was found. */ | |
249 | const char *l_origin; | |
250 | ||
251 | /* Start and finish of memory map for this object. l_map_start | |
252 | need not be the same as l_addr. */ | |
253 | ElfW(Addr) l_map_start, l_map_end; | |
eec8b6ca UD |
254 | /* End of the executable part of the mapping. */ |
255 | ElfW(Addr) l_text_end; | |
7e6d3809 | 256 | |
b98e518f | 257 | /* Default array for 'l_scope'. */ |
c0a777e8 | 258 | struct r_scope_elem *l_scope_mem[4]; |
b98e518f UD |
259 | /* Size of array allocated for 'l_scope'. */ |
260 | size_t l_scope_max; | |
7e6d3809 | 261 | /* This is an array defining the lookup scope for this link map. |
c69136ae | 262 | There are initially at most three different scope lists. */ |
c0a777e8 | 263 | struct r_scope_elem **l_scope; |
7e6d3809 UD |
264 | |
265 | /* A similar array, this time only with the local scope. This is | |
266 | used occasionally. */ | |
267 | struct r_scope_elem *l_local_scope[2]; | |
268 | ||
269 | /* This information is kept to check for sure whether a shared | |
270 | object is the same as one already loaded. */ | |
c01ae97e | 271 | struct r_file_id l_file_id; |
7e6d3809 UD |
272 | |
273 | /* Collected information about own RUNPATH directories. */ | |
f55727ca | 274 | struct r_search_path_struct l_runpath_dirs; |
7e6d3809 UD |
275 | |
276 | /* List of object in order of the init and fini calls. */ | |
277 | struct link_map **l_initfini; | |
278 | ||
279 | /* List of the dependencies introduced through symbol binding. */ | |
385b4cf4 UD |
280 | struct link_map_reldeps |
281 | { | |
282 | unsigned int act; | |
283 | struct link_map *list[]; | |
284 | } *l_reldeps; | |
2af63968 UD |
285 | unsigned int l_reldepsmax; |
286 | ||
287 | /* Nonzero if the DSO is used. */ | |
288 | unsigned int l_used; | |
bf8b3e74 UD |
289 | |
290 | /* Various flag words. */ | |
291 | ElfW(Word) l_feature_1; | |
292 | ElfW(Word) l_flags_1; | |
ec70c011 | 293 | ElfW(Word) l_flags; |
69c33254 UD |
294 | |
295 | /* Temporarily used in `dl_close'. */ | |
20fe49b9 | 296 | int l_idx; |
370f00c3 UD |
297 | |
298 | struct link_map_machine l_mach; | |
680254fe UD |
299 | |
300 | struct | |
301 | { | |
302 | const ElfW(Sym) *sym; | |
cf5a372e | 303 | int type_class; |
680254fe | 304 | struct link_map *value; |
680254fe UD |
305 | const ElfW(Sym) *ret; |
306 | } l_lookup_cache; | |
5d6feea8 UD |
307 | |
308 | /* Thread-local storage related info. */ | |
309 | ||
5d6feea8 UD |
310 | /* Start of the initialization image. */ |
311 | void *l_tls_initimage; | |
312 | /* Size of the initialization image. */ | |
313 | size_t l_tls_initimage_size; | |
314 | /* Size of the TLS block. */ | |
315 | size_t l_tls_blocksize; | |
877e0d8e | 316 | /* Alignment requirement of the TLS block. */ |
3fb55878 | 317 | size_t l_tls_align; |
99fe3b0e UD |
318 | /* Offset of first byte module alignment. */ |
319 | size_t l_tls_firstbyte_offset; | |
11bf311e UD |
320 | #ifndef NO_TLS_OFFSET |
321 | # define NO_TLS_OFFSET 0 | |
4c533566 UD |
322 | #endif |
323 | #ifndef FORCED_DYNAMIC_TLS_OFFSET | |
324 | # if NO_TLS_OFFSET == 0 | |
67cbf9a2 | 325 | # define FORCED_DYNAMIC_TLS_OFFSET -1 |
4c533566 UD |
326 | # elif NO_TLS_OFFSET == -1 |
327 | # define FORCED_DYNAMIC_TLS_OFFSET -2 | |
328 | # else | |
329 | # error "FORCED_DYNAMIC_TLS_OFFSET is not defined" | |
330 | # endif | |
11bf311e | 331 | #endif |
5d6feea8 UD |
332 | /* For objects present at startup time: offset in the static TLS block. */ |
333 | ptrdiff_t l_tls_offset; | |
334 | /* Index of the module in the dtv array. */ | |
335 | size_t l_tls_modid; | |
ed20b3d9 | 336 | |
90b37cac SP |
337 | /* Number of thread_local objects constructed by this DSO. This is |
338 | atomically accessed and modified and is not always protected by the load | |
339 | lock. See also: CONCURRENCY NOTES in cxa_thread_atexit_impl.c. */ | |
ba384f6e SP |
340 | size_t l_tls_dtor_count; |
341 | ||
ed20b3d9 UD |
342 | /* Information used to change permission after the relocations are |
343 | done. */ | |
344 | ElfW(Addr) l_relro_addr; | |
345 | size_t l_relro_size; | |
9dcafc55 | 346 | |
b90395e6 | 347 | unsigned long long int l_serial; |
9dcafc55 UD |
348 | }; |
349 | ||
e21a7867 FW |
350 | /* Information used by audit modules. For most link maps, this data |
351 | immediate follows the link map in memory. For the dynamic linker, | |
352 | it is allocated separately. See link_map_audit_state in | |
353 | <ldsodefs.h>. */ | |
354 | struct auditstate | |
355 | { | |
356 | uintptr_t cookie; | |
357 | unsigned int bindflags; | |
358 | }; | |
359 | ||
9dcafc55 UD |
360 | |
361 | #if __ELF_NATIVE_CLASS == 32 | |
362 | # define symbind symbind32 | |
9dcafc55 UD |
363 | #elif __ELF_NATIVE_CLASS == 64 |
364 | # define symbind symbind64 | |
365 | #else | |
366 | # error "__ELF_NATIVE_CLASS must be defined" | |
367 | #endif | |
368 | ||
48ab1c2f UD |
369 | extern int __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, |
370 | size_t size, void *data), | |
371 | void *data); | |
a0aef783 | 372 | hidden_proto (__dl_iterate_phdr) |
48ab1c2f | 373 | |
81b035fe L |
374 | /* We use this macro to refer to ELF macros independent of the native |
375 | wordsize. `ELFW(R_TYPE)' is used in place of `ELF32_R_TYPE' or | |
376 | `ELF64_R_TYPE'. */ | |
377 | #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) | |
378 | ||
47755784 | 379 | # endif /* !_ISOMAC */ |
d78efd9f | 380 | #endif /* include/link.h */ |