]>
Commit | Line | Data |
---|---|---|
266180eb | 1 | /* Support for dynamic linking code in static libc. |
d6b5d570 | 2 | Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc. |
afd4eb37 | 3 | This file is part of the GNU C Library. |
266180eb | 4 | |
afd4eb37 | 5 | The GNU C Library is free software; you can redistribute it and/or |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
266180eb | 9 | |
afd4eb37 UD |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
266180eb | 14 | |
41bdb6e2 AJ |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
266180eb | 19 | |
266180eb RM |
20 | /* This file defines some things that for the dynamic linker are defined in |
21 | rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */ | |
22 | ||
3c720987 | 23 | #include <errno.h> |
8e17ea58 | 24 | #include <libintl.h> |
b13927da | 25 | #include <stdlib.h> |
0a54e401 | 26 | #include <unistd.h> |
a42195db | 27 | #include <ldsodefs.h> |
0a54e401 | 28 | #include <dl-machine.h> |
cf197e41 | 29 | #include <bits/libc-lock.h> |
5688da55 | 30 | #include <dl-cache.h> |
74955460 UD |
31 | #include <dl-librecon.h> |
32 | #include <unsecvars.h> | |
3b5c1b57 | 33 | #include <hp-timing.h> |
b13927da | 34 | |
266180eb RM |
35 | extern char *__progname; |
36 | char **_dl_argv = &__progname; /* This is checked for some error messages. */ | |
37 | ||
0a54e401 UD |
38 | /* Name of the architecture. */ |
39 | const char *_dl_platform; | |
40 | size_t _dl_platformlen; | |
3c720987 | 41 | |
62dcee57 | 42 | int _dl_debug_mask; |
12b5b6b7 | 43 | int _dl_lazy; |
8a0e201e UD |
44 | /* XXX I know about at least one case where we depend on the old weak |
45 | behavior (it has to do with librt). Until we get DSO groups implemented | |
46 | we have to make this the default. Bummer. --drepper */ | |
47 | #if 0 | |
dec126b4 | 48 | int _dl_dynamic_weak; |
8a0e201e UD |
49 | #else |
50 | int _dl_dynamic_weak = 1; | |
51 | #endif | |
0a54e401 | 52 | |
b13927da UD |
53 | /* If nonzero print warnings about problematic situations. */ |
54 | int _dl_verbose; | |
55 | ||
3996f34b UD |
56 | /* We never do profiling. */ |
57 | const char *_dl_profile; | |
3996f34b | 58 | |
fcf70d41 UD |
59 | /* Names of shared object for which the RUNPATHs and RPATHs should be |
60 | ignored. */ | |
b0a01055 | 61 | const char *_dl_inhibit_rpath; |
310930c1 | 62 | |
a3d6fb9b UD |
63 | /* The map for the object we will profile. */ |
64 | struct link_map *_dl_profile_map; | |
65 | ||
c0fb8a56 UD |
66 | /* This is the address of the last stack address ever used. */ |
67 | void *__libc_stack_end; | |
68 | ||
f787edde UD |
69 | /* Path where the binary is found. */ |
70 | const char *_dl_origin_path; | |
71 | ||
f53c03c2 UD |
72 | /* Nonzero if runtime lookup should not update the .got/.plt. */ |
73 | int _dl_bind_not; | |
74 | ||
be935610 UD |
75 | /* Initially empty list of loaded objects. */ |
76 | struct link_map *_dl_loaded; | |
1ebba33e UD |
77 | /* Number of object in the _dl_loaded list. */ |
78 | unsigned int _dl_nloaded; | |
be935610 UD |
79 | |
80 | /* Fake scope. In dynamically linked binaries this is the scope of the | |
604510f7 | 81 | main application but here we don't have something like this. So |
be935610 | 82 | create a fake scope containing nothing. */ |
604510f7 | 83 | struct r_scope_elem _dl_initial_searchlist; |
be935610 | 84 | /* Variable which can be used in lookup to process the global scope. */ |
604510f7 | 85 | struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL }; |
be935610 UD |
86 | /* This is a global pointer to this structure which is public. It is |
87 | used by dlopen/dlclose to add and remove objects from what is regarded | |
88 | to be the global scope. */ | |
604510f7 | 89 | struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist; |
be935610 | 90 | |
9ad04ff7 UD |
91 | /* Nonzero during startup. */ |
92 | int _dl_starting_up = 1; | |
93 | ||
ccdf0cab UD |
94 | /* Get architecture specific initializer. */ |
95 | #include <dl-procinfo.c> | |
96 | ||
eaad82e0 UD |
97 | /* We expect less than a second for relocation. */ |
98 | #ifdef HP_SMALL_TIMING_AVAIL | |
99 | # undef HP_TIMING_AVAIL | |
100 | # define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL | |
101 | #endif | |
102 | ||
5fc48cd7 | 103 | /* Initial value of the CPU clock. */ |
eaad82e0 | 104 | #ifndef HP_TIMING_NONAVAIL |
3b5c1b57 | 105 | hp_timing_t _dl_cpuclock_offset; |
5fc48cd7 UD |
106 | #endif |
107 | ||
d6b5d570 UD |
108 | /* This is zero at program start to signal that the global scope map is |
109 | allocated by rtld. Later it keeps the size of the map. It might be | |
110 | reset if in _dl_close if the last global object is removed. */ | |
111 | size_t _dl_global_scope_alloc; | |
112 | ||
113 | size_t _dl_pagesize; | |
114 | ||
115 | unsigned int _dl_osversion; | |
116 | ||
117 | /* All known directories in sorted order. */ | |
118 | struct r_search_path_elem *_dl_all_dirs; | |
119 | ||
120 | /* All directories after startup. */ | |
121 | struct r_search_path_elem *_dl_init_all_dirs; | |
122 | ||
123 | /* The object to be initialized first. */ | |
124 | struct link_map *_dl_initfirst; | |
125 | ||
5688da55 UD |
126 | /* Descriptor to write debug messages to. */ |
127 | int _dl_debug_fd = STDERR_FILENO; | |
128 | ||
129 | int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID; | |
130 | ||
cf197e41 UD |
131 | /* During the program run we must not modify the global data of |
132 | loaded shared object simultanously in two threads. Therefore we | |
133 | protect `_dl_open' and `_dl_close' in dl-close.c. | |
134 | ||
135 | This must be a recursive lock since the initializer function of | |
136 | the loaded object might as well require a call to this function. | |
137 | At this time it is not anymore a problem to modify the tables. */ | |
138 | __libc_lock_define_initialized_recursive (, _dl_load_lock) | |
139 | ||
96f208a4 UD |
140 | #ifdef USE_TLS |
141 | /* Beginning of the list of link maps for objects which contain | |
142 | thread-local storage sections. This will be traversed to | |
143 | initialize new TLS blocks. */ | |
144 | struct link_map *_dl_initimage_list; | |
145 | ||
3fb55878 UD |
146 | /* Highest dtv index currently needed. */ |
147 | size_t _dl_tls_max_dtv_idx; | |
148 | /* Flag signalling whether there are gaps in the module ID allocation. */ | |
149 | bool _dl_tls_dtv_gaps; | |
cd30b01e UD |
150 | |
151 | /* Size of the static TLS block. */ | |
152 | size_t _dl_tls_static_size; | |
153 | /* Alignment requirement of the static TLS block. */ | |
154 | size_t _dl_tls_static_align; | |
96f208a4 UD |
155 | #endif |
156 | ||
f8f900ec | 157 | |
e4a5f77d | 158 | #ifdef HAVE_AUX_VECTOR |
d6b5d570 | 159 | int _dl_clktck; |
0a54e401 | 160 | |
e4a5f77d UD |
161 | void |
162 | internal_function | |
163 | _dl_aux_init (ElfW(auxv_t) *av) | |
b13927da | 164 | { |
f8f900ec UD |
165 | for (; av->a_type != AT_NULL; ++av) |
166 | switch (av->a_type) | |
167 | { | |
168 | case AT_PAGESZ: | |
d6b5d570 | 169 | GL(dl_pagesize) = av->a_un.a_val; |
f8f900ec | 170 | break; |
f8f900ec | 171 | case AT_CLKTCK: |
d6b5d570 | 172 | GL(dl_clktck) = av->a_un.a_val; |
f8f900ec UD |
173 | break; |
174 | } | |
e4a5f77d | 175 | } |
155fd00c | 176 | #endif |
f8f900ec | 177 | |
e4a5f77d UD |
178 | static void non_dynamic_init (void) __attribute__ ((unused)); |
179 | ||
180 | static void | |
181 | non_dynamic_init (void) | |
182 | { | |
eaad82e0 UD |
183 | if (HP_TIMING_AVAIL) |
184 | HP_TIMING_NOW (_dl_cpuclock_offset); | |
5fc48cd7 | 185 | |
f8f900ec UD |
186 | if (!_dl_pagesize) |
187 | _dl_pagesize = __getpagesize (); | |
188 | ||
189 | _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; | |
e34b0f29 | 190 | |
0a54e401 UD |
191 | /* Initialize the data structures for the search paths for shared |
192 | objects. */ | |
b4debac9 | 193 | _dl_init_paths (getenv ("LD_LIBRARY_PATH")); |
0a54e401 | 194 | |
12b5b6b7 UD |
195 | _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; |
196 | ||
f53c03c2 UD |
197 | _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; |
198 | ||
dec126b4 UD |
199 | _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; |
200 | ||
74955460 UD |
201 | if (__libc_enable_secure) |
202 | { | |
203 | static const char *unsecure_envvars[] = | |
204 | { | |
205 | UNSECURE_ENVVARS, | |
206 | #ifdef EXTRA_UNSECURE_ENVVARS | |
207 | EXTRA_UNSECURE_ENVVARS | |
208 | #endif | |
209 | }; | |
210 | size_t cnt; | |
211 | ||
212 | for (cnt = 0; | |
213 | cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]); | |
214 | ++cnt) | |
215 | unsetenv (unsecure_envvars[cnt]); | |
216 | ||
217 | if (__access ("/etc/suid-debug", F_OK) != 0) | |
218 | unsetenv ("MALLOC_CHECK_"); | |
219 | } | |
220 | ||
0a54e401 UD |
221 | #ifdef DL_PLATFORM_INIT |
222 | DL_PLATFORM_INIT; | |
223 | #endif | |
224 | ||
225 | /* Now determine the length of the platform string. */ | |
226 | if (_dl_platform != NULL) | |
227 | _dl_platformlen = strlen (_dl_platform); | |
b13927da | 228 | } |
0a54e401 | 229 | text_set_element (__libc_subinit, non_dynamic_init); |
3c720987 UD |
230 | |
231 | const struct r_strlenpair * | |
232 | internal_function | |
233 | _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, | |
234 | size_t *max_capstrlen) | |
235 | { | |
821563a9 UD |
236 | static struct r_strlenpair result; |
237 | static char buf[1]; | |
3c720987 | 238 | |
821563a9 UD |
239 | result.str = buf; /* Does not really matter. */ |
240 | result.len = 0; | |
3c720987 UD |
241 | |
242 | *sz = 1; | |
821563a9 | 243 | return &result; |
3c720987 | 244 | } |