1 | /* Data structure for communication from the run-time dynamic linker for |
2 | loaded ELF shared objects. |
3 | Copyright (C) 1995-2022 Free Software Foundation, Inc. |
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 |
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. |
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 |
14 | Lesser General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Lesser General Public |
17 | License along with the GNU C Library; if not, see |
18 | <https://www.gnu.org/licenses/>. */ |
19 | |
20 | #ifndef _PRIVATE_LINK_H |
21 | #define _PRIVATE_LINK_H 1 |
22 | |
23 | #ifdef _LINK_H |
24 | # error this should be impossible |
25 | #endif |
26 | |
27 | # ifndef _ISOMAC |
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. */ |
31 | # define link_map link_map_public |
32 | # define la_objopen la_objopen_wrongproto |
33 | # endif |
34 | |
35 | #include <elf/link.h> |
36 | |
37 | # ifndef _ISOMAC |
38 | |
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); |
45 | |
46 | #include <stdint.h> |
47 | #include <stddef.h> |
48 | #include <linkmap.h> |
49 | #include <dl-fileid.h> |
50 | #include <dl-lookupcfg.h> |
51 | #include <tls.h> |
52 | #include <libc-lock.h> |
53 | |
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; |
72 | }; |
73 | |
74 | |
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 | |
82 | /* Search path information computed by _dl_init_paths. */ |
83 | extern struct r_search_path_struct __rtld_search_dirs attribute_hidden; |
84 | extern struct r_search_path_struct __rtld_env_path_list attribute_hidden; |
85 | |
86 | /* Structure describing a loaded shared object. The `l_next' and `l_prev' |
87 | members form a chain of all the shared objects loaded at startup. |
88 | |
89 | These data structures exist in space used by the run-time dynamic linker; |
90 | modifying them may have disastrous results. |
91 | |
92 | This data structure might change in future, if necessary. User-level |
93 | programs must avoid defining objects of this type. */ |
94 | |
95 | struct link_map |
96 | { |
97 | /* These first few members are part of the protocol with the debugger. |
98 | This is the same format used in SVR4. */ |
99 | |
100 | ElfW(Addr) l_addr; /* Difference between the address in the ELF |
101 | file and the addresses in memory. */ |
102 | char *l_name; /* Absolute file name object was found in. */ |
103 | ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */ |
104 | struct link_map *l_next, *l_prev; /* Chain of loaded objects. */ |
105 | |
106 | /* All following members are internal to the dynamic linker. |
107 | They may change without notice. */ |
108 | |
109 | /* This is an element which is only ever different from a pointer to |
110 | the very same copy of this type for ld.so when it is used in more |
111 | than one namespace. */ |
112 | struct link_map *l_real; |
113 | |
114 | /* Number of the namespace this link map belongs to. */ |
115 | Lmid_t l_ns; |
116 | |
117 | struct libname_list *l_libname; |
118 | /* Indexed pointers to dynamic section. |
119 | [0,DT_NUM) are indexed by the processor-independent tags. |
120 | [DT_NUM,DT_NUM+DT_THISPROCNUM) are indexed by the tag minus DT_LOPROC. |
121 | [DT_NUM+DT_THISPROCNUM,DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM) are |
122 | indexed by DT_VERSIONTAGIDX(tagvalue). |
123 | [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM, |
124 | DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM) are indexed by |
125 | DT_EXTRATAGIDX(tagvalue). |
126 | [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM, |
127 | DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM) are |
128 | indexed by DT_VALTAGIDX(tagvalue) and |
129 | [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM, |
130 | DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM+DT_ADDRNUM) |
131 | are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */ |
132 | |
133 | ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM |
134 | + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM]; |
135 | const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */ |
136 | ElfW(Addr) l_entry; /* Entry point location. */ |
137 | ElfW(Half) l_phnum; /* Number of program header entries. */ |
138 | ElfW(Half) l_ldnum; /* Number of dynamic segment entries. */ |
139 | |
140 | /* Array of DT_NEEDED dependencies and their dependencies, in |
141 | dependency order for symbol lookup (with and without |
142 | duplicates). There is no entry before the dependencies have |
143 | been loaded. */ |
144 | struct r_scope_elem l_searchlist; |
145 | |
146 | /* We need a special searchlist to process objects marked with |
147 | DT_SYMBOLIC. */ |
148 | struct r_scope_elem l_symbolic_searchlist; |
149 | |
150 | /* Dependent object that first caused this object to be loaded. */ |
151 | struct link_map *l_loader; |
152 | |
153 | /* Array with version names. */ |
154 | struct r_found_version *l_versions; |
155 | unsigned int l_nversions; |
156 | |
157 | /* Symbol hash table. */ |
158 | Elf_Symndx l_nbuckets; |
159 | Elf32_Word l_gnu_bitmask_idxbits; |
160 | Elf32_Word l_gnu_shift; |
161 | const ElfW(Addr) *l_gnu_bitmask; |
162 | union |
163 | { |
164 | const Elf32_Word *l_gnu_buckets; |
165 | const Elf_Symndx *l_chain; |
166 | }; |
167 | union |
168 | { |
169 | const Elf32_Word *l_gnu_chain_zero; |
170 | const Elf_Symndx *l_buckets; |
171 | }; |
172 | |
173 | unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose. */ |
174 | enum /* Where this object came from. */ |
175 | { |
176 | lt_executable, /* The main executable program. */ |
177 | lt_library, /* Library needed by main executable. */ |
178 | lt_loaded /* Extra run-time loaded shared object. */ |
179 | } l_type:2; |
180 | unsigned int l_relocated:1; /* Nonzero if object's relocations done. */ |
181 | unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ |
182 | unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ |
183 | unsigned int l_reserved:2; /* Reserved for internal use. */ |
184 | unsigned int l_main_map:1; /* Nonzero for the map of the main program. */ |
185 | unsigned int l_visited:1; /* Used internally for map dependency |
186 | graph traversal. */ |
187 | unsigned int l_map_used:1; /* These two bits are used during traversal */ |
188 | unsigned int l_map_done:1; /* of maps in _dl_close_worker. */ |
189 | unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed |
190 | to by `l_phdr' is allocated. */ |
191 | unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in |
192 | the l_libname list. */ |
193 | unsigned int l_faked:1; /* Nonzero if this is a faked descriptor |
194 | without associated file. */ |
195 | unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls) |
196 | should be called on this link map |
197 | when relocation finishes. */ |
198 | unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing. */ |
199 | unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module |
200 | is interested in the PLT interception.*/ |
201 | unsigned int l_removed:1; /* Nozero if the object cannot be used anymore |
202 | since it is removed. */ |
203 | unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are |
204 | mprotected or if no holes are present at |
205 | all. */ |
206 | unsigned int l_symbolic_in_local_scope:1; /* Nonzero if l_local_scope |
207 | during LD_TRACE_PRELINKING=1 |
208 | contains any DT_SYMBOLIC |
209 | libraries. */ |
210 | unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be |
211 | freed, ie. not allocated with |
212 | the dummy malloc in ld.so. */ |
213 | unsigned int l_ld_readonly:1; /* Nonzero if dynamic section is readonly. */ |
214 | unsigned int l_find_object_processed:1; /* Zero if _dl_find_object_update |
215 | needs to process this |
216 | lt_library map. */ |
217 | |
218 | /* NODELETE status of the map. Only valid for maps of type |
219 | lt_loaded. Lazy binding sets l_nodelete_active directly, |
220 | potentially from signal handlers. Initial loading of an |
221 | DF_1_NODELETE object set l_nodelete_pending. Relocation may |
222 | set l_nodelete_pending as well. l_nodelete_pending maps are |
223 | promoted to l_nodelete_active status in the final stages of |
224 | dlopen, prior to calling ELF constructors. dlclose only |
225 | refuses to unload l_nodelete_active maps, the pending status is |
226 | ignored. */ |
227 | bool l_nodelete_active; |
228 | bool l_nodelete_pending; |
229 | |
230 | #include <link_map.h> |
231 | |
232 | /* Collected information about own RPATH directories. */ |
233 | struct r_search_path_struct l_rpath_dirs; |
234 | |
235 | /* Collected results of relocation while profiling. */ |
236 | struct reloc_result |
237 | { |
238 | DL_FIXUP_VALUE_TYPE addr; |
239 | struct link_map *bound; |
240 | unsigned int boundndx; |
241 | uint32_t enterexit; |
242 | unsigned int flags; |
243 | /* CONCURRENCY NOTE: This is used to guard the concurrent initialization |
244 | of the relocation result across multiple threads. See the more |
245 | detailed notes in elf/dl-runtime.c. */ |
246 | unsigned int init; |
247 | } *l_reloc_result; |
248 | |
249 | /* Pointer to the version information if available. */ |
250 | ElfW(Versym) *l_versyms; |
251 | |
252 | /* String specifying the path where this object was found. */ |
253 | const char *l_origin; |
254 | |
255 | /* Start and finish of memory map for this object. l_map_start |
256 | need not be the same as l_addr. */ |
257 | ElfW(Addr) l_map_start, l_map_end; |
258 | /* End of the executable part of the mapping. */ |
259 | ElfW(Addr) l_text_end; |
260 | |
261 | /* Default array for 'l_scope'. */ |
262 | struct r_scope_elem *l_scope_mem[4]; |
263 | /* Size of array allocated for 'l_scope'. */ |
264 | size_t l_scope_max; |
265 | /* This is an array defining the lookup scope for this link map. |
266 | There are initially at most three different scope lists. */ |
267 | struct r_scope_elem **l_scope; |
268 | |
269 | /* A similar array, this time only with the local scope. This is |
270 | used occasionally. */ |
271 | struct r_scope_elem *l_local_scope[2]; |
272 | |
273 | /* This information is kept to check for sure whether a shared |
274 | object is the same as one already loaded. */ |
275 | struct r_file_id l_file_id; |
276 | |
277 | /* Collected information about own RUNPATH directories. */ |
278 | struct r_search_path_struct l_runpath_dirs; |
279 | |
280 | /* List of object in order of the init and fini calls. */ |
281 | struct link_map **l_initfini; |
282 | |
283 | /* List of the dependencies introduced through symbol binding. */ |
284 | struct link_map_reldeps |
285 | { |
286 | unsigned int act; |
287 | struct link_map *list[]; |
288 | } *l_reldeps; |
289 | unsigned int l_reldepsmax; |
290 | |
291 | /* Nonzero if the DSO is used. */ |
292 | unsigned int l_used; |
293 | |
294 | /* Various flag words. */ |
295 | ElfW(Word) l_feature_1; |
296 | ElfW(Word) l_flags_1; |
297 | ElfW(Word) l_flags; |
298 | |
299 | /* Temporarily used in `dl_close'. */ |
300 | int l_idx; |
301 | |
302 | struct link_map_machine l_mach; |
303 | |
304 | struct |
305 | { |
306 | const ElfW(Sym) *sym; |
307 | int type_class; |
308 | struct link_map *value; |
309 | const ElfW(Sym) *ret; |
310 | } l_lookup_cache; |
311 | |
312 | /* Thread-local storage related info. */ |
313 | |
314 | /* Start of the initialization image. */ |
315 | void *l_tls_initimage; |
316 | /* Size of the initialization image. */ |
317 | size_t l_tls_initimage_size; |
318 | /* Size of the TLS block. */ |
319 | size_t l_tls_blocksize; |
320 | /* Alignment requirement of the TLS block. */ |
321 | size_t l_tls_align; |
322 | /* Offset of first byte module alignment. */ |
323 | size_t l_tls_firstbyte_offset; |
324 | #ifndef NO_TLS_OFFSET |
325 | # define NO_TLS_OFFSET 0 |
326 | #endif |
327 | #ifndef FORCED_DYNAMIC_TLS_OFFSET |
328 | # if NO_TLS_OFFSET == 0 |
329 | # define FORCED_DYNAMIC_TLS_OFFSET -1 |
330 | # elif NO_TLS_OFFSET == -1 |
331 | # define FORCED_DYNAMIC_TLS_OFFSET -2 |
332 | # else |
333 | # error "FORCED_DYNAMIC_TLS_OFFSET is not defined" |
334 | # endif |
335 | #endif |
336 | /* For objects present at startup time: offset in the static TLS block. */ |
337 | ptrdiff_t l_tls_offset; |
338 | /* Index of the module in the dtv array. */ |
339 | size_t l_tls_modid; |
340 | |
341 | /* Number of thread_local objects constructed by this DSO. This is |
342 | atomically accessed and modified and is not always protected by the load |
343 | lock. See also: CONCURRENCY NOTES in cxa_thread_atexit_impl.c. */ |
344 | size_t l_tls_dtor_count; |
345 | |
346 | /* Information used to change permission after the relocations are |
347 | done. */ |
348 | ElfW(Addr) l_relro_addr; |
349 | size_t l_relro_size; |
350 | |
351 | unsigned long long int l_serial; |
352 | }; |
353 | |
354 | #include <dl-relocate-ld.h> |
355 | |
356 | /* Information used by audit modules. For most link maps, this data |
357 | immediate follows the link map in memory. For the dynamic linker, |
358 | it is allocated separately. See link_map_audit_state in |
359 | <ldsodefs.h>. */ |
360 | struct auditstate |
361 | { |
362 | uintptr_t cookie; |
363 | unsigned int bindflags; |
364 | }; |
365 | |
366 | |
367 | /* This is the hidden instance of struct r_debug_extended used by the |
368 | dynamic linker. */ |
369 | extern struct r_debug_extended _r_debug_extended attribute_hidden; |
370 | |
371 | #if __ELF_NATIVE_CLASS == 32 |
372 | # define symbind symbind32 |
373 | # define LA_SYMBIND "la_symbind32" |
374 | #elif __ELF_NATIVE_CLASS == 64 |
375 | # define symbind symbind64 |
376 | # define LA_SYMBIND "la_symbind64" |
377 | #else |
378 | # error "__ELF_NATIVE_CLASS must be defined" |
379 | #endif |
380 | |
381 | extern int __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, |
382 | size_t size, void *data), |
383 | void *data); |
384 | hidden_proto (__dl_iterate_phdr) |
385 | |
386 | /* We use this macro to refer to ELF macros independent of the native |
387 | wordsize. `ELFW(R_TYPE)' is used in place of `ELF32_R_TYPE' or |
388 | `ELF64_R_TYPE'. */ |
389 | #define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) |
390 | |
391 | # endif /* !_ISOMAC */ |
392 | #endif /* include/link.h */ |
393 | |