Update.
[platform/upstream/glibc.git] / elf / dl-support.c
1 /* Support for dynamic linking code in static libc.
2    Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
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.
9
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
13    Lesser General Public License for more details.
14
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.  */
19
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
23 #include <errno.h>
24 #include <libintl.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <ldsodefs.h>
28 #include <dl-machine.h>
29 #include <bits/libc-lock.h>
30 #include <dl-cache.h>
31 #include <dl-librecon.h>
32 #include <unsecvars.h>
33 #include <hp-timing.h>
34
35 extern char *__progname;
36 char **_dl_argv = &__progname;  /* This is checked for some error messages.  */
37
38 /* Name of the architecture.  */
39 const char *_dl_platform;
40 size_t _dl_platformlen;
41
42 int _dl_debug_mask;
43 int _dl_lazy;
44 ElfW(Addr) _dl_use_load_bias = -2;
45 int _dl_dynamic_weak;
46
47 /* If nonzero print warnings about problematic situations.  */
48 int _dl_verbose;
49
50 /* We never do profiling.  */
51 const char *_dl_profile;
52
53 /* Names of shared object for which the RUNPATHs and RPATHs should be
54    ignored.  */
55 const char *_dl_inhibit_rpath;
56
57 /* The map for the object we will profile.  */
58 struct link_map *_dl_profile_map;
59
60 /* This is the address of the last stack address ever used.  */
61 void *__libc_stack_end;
62
63 /* Path where the binary is found.  */
64 const char *_dl_origin_path;
65
66 /* Nonzero if runtime lookup should not update the .got/.plt.  */
67 int _dl_bind_not;
68
69 /* Initially empty list of loaded objects.  */
70 struct link_map *_dl_loaded;
71 /* Number of object in the _dl_loaded list.  */
72 unsigned int _dl_nloaded;
73
74 /* Incremented whenever something may have been added to dl_loaded. */
75 unsigned long long _dl_load_adds;
76
77 /* Fake scope.  In dynamically linked binaries this is the scope of the
78    main application but here we don't have something like this.  So
79    create a fake scope containing nothing.  */
80 struct r_scope_elem _dl_initial_searchlist;
81 /* Variable which can be used in lookup to process the global scope.  */
82 struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL };
83 /* This is a global pointer to this structure which is public.  It is
84    used by dlopen/dlclose to add and remove objects from what is regarded
85    to be the global scope.  */
86 struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist;
87
88 /* Nonzero during startup.  */
89 int _dl_starting_up = 1;
90
91 /* Get architecture specific initializer.  */
92 #include <dl-procinfo.c>
93
94 /* We expect less than a second for relocation.  */
95 #ifdef HP_SMALL_TIMING_AVAIL
96 # undef HP_TIMING_AVAIL
97 # define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
98 #endif
99
100 /* Initial value of the CPU clock.  */
101 #ifndef HP_TIMING_NONAVAIL
102 hp_timing_t _dl_cpuclock_offset;
103 #endif
104
105 #ifdef USE_TLS
106 void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
107 #endif
108
109 /* This is zero at program start to signal that the global scope map is
110    allocated by rtld.  Later it keeps the size of the map.  It might be
111    reset if in _dl_close if the last global object is removed.  */
112 size_t _dl_global_scope_alloc;
113
114 size_t _dl_pagesize;
115
116 unsigned int _dl_osversion;
117
118 /* All known directories in sorted order.  */
119 struct r_search_path_elem *_dl_all_dirs;
120
121 /* All directories after startup.  */
122 struct r_search_path_elem *_dl_init_all_dirs;
123
124 /* The object to be initialized first.  */
125 struct link_map *_dl_initfirst;
126
127 /* Descriptor to write debug messages to.  */
128 int _dl_debug_fd = STDERR_FILENO;
129
130 int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
131
132 ElfW(Phdr) *_dl_phdr;
133 size_t _dl_phnum;
134 unsigned long int _dl_hwcap __attribute__ ((nocommon));
135
136 /* Prevailing state of the stack, PF_X indicating it's executable.  */
137 ElfW(Word) _dl_stack_flags = PF_R|PF_W|PF_X;
138
139 /* If loading a shared object requires that we make the stack executable
140    when it was not, we do it by calling this function.
141    It returns an errno code or zero on success.  */
142 int (*_dl_make_stack_executable_hook) (void **) internal_function
143   = _dl_make_stack_executable;
144
145
146 #ifdef NEED_DL_SYSINFO
147 /* Needed for improved syscall handling on at least x86/Linux.  */
148 uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
149 /* Address of the ELF headers in the vsyscall page.  */
150 const ElfW(Ehdr) *_dl_sysinfo_dso;
151 #endif
152
153 /* During the program run we must not modify the global data of
154    loaded shared object simultanously in two threads.  Therefore we
155    protect `_dl_open' and `_dl_close' in dl-close.c.
156
157    This must be a recursive lock since the initializer function of
158    the loaded object might as well require a call to this function.
159    At this time it is not anymore a problem to modify the tables.  */
160 __rtld_lock_define_initialized_recursive (, _dl_load_lock)
161
162
163 #ifdef HAVE_AUX_VECTOR
164 int _dl_clktck;
165
166 void
167 internal_function
168 _dl_aux_init (ElfW(auxv_t) *av)
169 {
170   int seen = 0;
171   uid_t uid = 0;
172   gid_t gid = 0;
173
174   for (; av->a_type != AT_NULL; ++av)
175     switch (av->a_type)
176       {
177       case AT_PAGESZ:
178         GL(dl_pagesize) = av->a_un.a_val;
179         break;
180       case AT_CLKTCK:
181         GL(dl_clktck) = av->a_un.a_val;
182         break;
183       case AT_PHDR:
184         GL(dl_phdr) = av->a_un.a_ptr;
185         break;
186       case AT_PHNUM:
187         GL(dl_phnum) = av->a_un.a_val;
188         break;
189       case AT_HWCAP:
190         GL(dl_hwcap) = av->a_un.a_val;
191         break;
192 #ifdef NEED_DL_SYSINFO
193       case AT_SYSINFO:
194         GL(dl_sysinfo) = av->a_un.a_val;
195         break;
196 #endif
197       case AT_UID:
198         uid ^= av->a_un.a_val;
199         seen |= 1;
200         break;
201       case AT_EUID:
202         uid ^= av->a_un.a_val;
203         seen |= 2;
204         break;
205       case AT_GID:
206         gid ^= av->a_un.a_val;
207         seen |= 4;
208         break;
209       case AT_EGID:
210         gid ^= av->a_un.a_val;
211         seen |= 8;
212         break;
213       case AT_SECURE:
214         seen = -1;
215         __libc_enable_secure = av->a_un.a_val;
216         __libc_enable_secure_decided = 1;
217         break;
218       }
219   if (seen == 0xf)
220     {
221       __libc_enable_secure = uid != 0 || gid != 0;
222       __libc_enable_secure_decided = 1;
223     }
224 }
225 #endif
226
227
228 void
229 internal_function
230 _dl_non_dynamic_init (void)
231 {
232   if (HP_TIMING_AVAIL)
233     HP_TIMING_NOW (_dl_cpuclock_offset);
234
235   if (!_dl_pagesize)
236     _dl_pagesize = __getpagesize ();
237
238   _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
239
240   /* Initialize the data structures for the search paths for shared
241      objects.  */
242   _dl_init_paths (getenv ("LD_LIBRARY_PATH"));
243
244   _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
245
246   _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
247
248   _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
249
250   if (__libc_enable_secure)
251     {
252       static const char *unsecure_envvars[] =
253       {
254         UNSECURE_ENVVARS,
255 #ifdef EXTRA_UNSECURE_ENVVARS
256         EXTRA_UNSECURE_ENVVARS
257 #endif
258       };
259       size_t cnt;
260
261       for (cnt = 0;
262            cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]);
263            ++cnt)
264         unsetenv (unsecure_envvars[cnt]);
265
266       if (__access ("/etc/suid-debug", F_OK) != 0)
267         unsetenv ("MALLOC_CHECK_");
268     }
269
270 #ifdef DL_PLATFORM_INIT
271   DL_PLATFORM_INIT;
272 #endif
273
274 #ifdef DL_OSVERSION_INIT
275   DL_OSVERSION_INIT;
276 #endif
277
278   /* Now determine the length of the platform string.  */
279   if (_dl_platform != NULL)
280     _dl_platformlen = strlen (_dl_platform);
281
282   /* Scan for a program header telling us the stack is nonexecutable.  */
283   if (_dl_phdr != NULL)
284     for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
285       if (_dl_phdr[i].p_type == PT_GNU_STACK)
286         {
287           _dl_stack_flags = _dl_phdr[i].p_flags;
288           break;
289         }
290 }
291
292
293 const struct r_strlenpair *
294 internal_function
295 _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
296                       size_t *max_capstrlen)
297 {
298   static struct r_strlenpair result;
299   static char buf[1];
300
301   result.str = buf;     /* Does not really matter.  */
302   result.len = 0;
303
304   *sz = 1;
305   return &result;
306 }
307
308
309 #ifdef DL_SYSINFO_IMPLEMENTATION
310 DL_SYSINFO_IMPLEMENTATION
311 #endif