Update.
[platform/upstream/glibc.git] / elf / dl-open.c
1 /* Load a shared object at runtime, relocate it, and run its initializer.
2    Copyright (C) 1996-2001, 2002 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 #include <assert.h>
21 #include <dlfcn.h>
22 #include <errno.h>
23 #include <libintl.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <sys/mman.h>           /* Check whether MAP_COPY is defined.  */
28 #include <sys/param.h>
29 #include <bits/libc-lock.h>
30 #include <ldsodefs.h>
31 #include <bp-sym.h>
32
33 #include <dl-dst.h>
34
35
36 extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
37                                     void (*dl_main) (const ElfW(Phdr) *phdr,
38                                                      ElfW(Word) phnum,
39                                                      ElfW(Addr) *user_entry));
40 weak_extern (BP_SYM (_dl_sysdep_start))
41
42 extern int __libc_multiple_libcs;       /* Defined in init-first.c.  */
43
44 extern int __libc_argc;
45 extern char **__libc_argv;
46
47 extern char **__environ;
48
49 /* Undefine the following for debugging.  */
50 /* #define SCOPE_DEBUG 1 */
51 #ifdef SCOPE_DEBUG
52 static void show_scope (struct link_map *new);
53 #endif
54
55 /* We must be carefull not to leave us in an inconsistent state.  Thus we
56    catch any error and re-raise it after cleaning up.  */
57
58 struct dl_open_args
59 {
60   const char *file;
61   int mode;
62   const void *caller;
63   struct link_map *map;
64 };
65
66
67 static int
68 add_to_global (struct link_map *new)
69 {
70   struct link_map **new_global;
71   unsigned int to_add = 0;
72   unsigned int cnt;
73
74   /* Count the objects we have to put in the global scope.  */
75   for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
76     if (new->l_searchlist.r_list[cnt]->l_global == 0)
77       ++to_add;
78
79   /* The symbols of the new objects and its dependencies are to be
80      introduced into the global scope that will be used to resolve
81      references from other dynamically-loaded objects.
82
83      The global scope is the searchlist in the main link map.  We
84      extend this list if necessary.  There is one problem though:
85      since this structure was allocated very early (before the libc
86      is loaded) the memory it uses is allocated by the malloc()-stub
87      in the ld.so.  When we come here these functions are not used
88      anymore.  Instead the malloc() implementation of the libc is
89      used.  But this means the block from the main map cannot be used
90      in an realloc() call.  Therefore we allocate a completely new
91      array the first time we have to add something to the locale scope.  */
92
93   if (GL(dl_global_scope_alloc) == 0)
94     {
95       /* This is the first dynamic object given global scope.  */
96       GL(dl_global_scope_alloc) = GL(dl_main_searchlist)->r_nlist + to_add + 8;
97       new_global = (struct link_map **)
98         malloc (GL(dl_global_scope_alloc) * sizeof (struct link_map *));
99       if (new_global == NULL)
100         {
101           GL(dl_global_scope_alloc) = 0;
102         nomem:
103           _dl_signal_error (ENOMEM, new->l_libname->name, NULL,
104                             N_("cannot extend global scope"));
105           return 1;
106         }
107
108       /* Copy over the old entries.  */
109       memcpy (new_global, GL(dl_main_searchlist)->r_list,
110               (GL(dl_main_searchlist)->r_nlist * sizeof (struct link_map *)));
111
112       GL(dl_main_searchlist)->r_list = new_global;
113     }
114   else if (GL(dl_main_searchlist)->r_nlist + to_add
115            > GL(dl_global_scope_alloc))
116     {
117       /* We have to extend the existing array of link maps in the
118          main map.  */
119       new_global = (struct link_map **)
120         realloc (GL(dl_main_searchlist)->r_list,
121                  ((GL(dl_global_scope_alloc) + to_add + 8)
122                   * sizeof (struct link_map *)));
123       if (new_global == NULL)
124         goto nomem;
125
126       GL(dl_global_scope_alloc) += to_add + 8;
127       GL(dl_main_searchlist)->r_list = new_global;
128     }
129
130   /* Now add the new entries.  */
131   for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
132     {
133       struct link_map *map = new->l_searchlist.r_list[cnt];
134
135       if (map->l_global == 0)
136         {
137           map->l_global = 1;
138           GL(dl_main_searchlist)->r_list[GL(dl_main_searchlist)->r_nlist]
139             = map;
140           ++GL(dl_main_searchlist)->r_nlist;
141         }
142     }
143
144   return 0;
145 }
146
147
148 static void
149 dl_open_worker (void *a)
150 {
151   struct dl_open_args *args = a;
152   const char *file = args->file;
153   int mode = args->mode;
154   struct link_map *new, *l;
155   const char *dst;
156   int lazy;
157   unsigned int i;
158
159   /* Maybe we have to expand a DST.  */
160   dst = strchr (file, '$');
161   if (__builtin_expect (dst != NULL, 0))
162     {
163       const void *caller = args->caller;
164       size_t len = strlen (file);
165       size_t required;
166       struct link_map *call_map;
167       char *new_file;
168
169       /* DSTs must not appear in SUID/SGID programs.  */
170       if (__libc_enable_secure)
171         /* This is an error.  */
172         _dl_signal_error (0, "dlopen", NULL,
173                           N_("DST not allowed in SUID/SGID programs"));
174
175       /* We have to find out from which object the caller is calling.  */
176       call_map = NULL;
177       for (l = GL(dl_loaded); l; l = l->l_next)
178         if (caller >= (const void *) l->l_map_start
179             && caller < (const void *) l->l_map_end)
180           {
181             /* There must be exactly one DSO for the range of the virtual
182                memory.  Otherwise something is really broken.  */
183             call_map = l;
184             break;
185           }
186
187       if (call_map == NULL)
188         /* In this case we assume this is the main application.  */
189         call_map = GL(dl_loaded);
190
191       /* Determine how much space we need.  We have to allocate the
192          memory locally.  */
193       required = DL_DST_REQUIRED (call_map, file, len, _dl_dst_count (dst, 0));
194
195       /* Get space for the new file name.  */
196       new_file = (char *) alloca (required + 1);
197
198       /* Generate the new file name.  */
199       _dl_dst_substitute (call_map, file, new_file, 0);
200
201       /* If the substitution failed don't try to load.  */
202       if (*new_file == '\0')
203         _dl_signal_error (0, "dlopen", NULL,
204                           N_("empty dynamic string token substitution"));
205
206       /* Now we have a new file name.  */
207       file = new_file;
208     }
209
210   /* Load the named object.  */
211   args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0, mode);
212
213   /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
214      set and the object is not already loaded.  */
215   if (new == NULL)
216     {
217       assert (mode & RTLD_NOLOAD);
218       return;
219     }
220
221   if (__builtin_expect (mode & __RTLD_SPROF, 0))
222     /* This happens only if we load a DSO for 'sprof'.  */
223     return;
224
225   /* It was already open.  */
226   if (new->l_searchlist.r_list != NULL)
227     {
228       /* Let the user know about the opencount.  */
229       if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))
230         _dl_debug_printf ("opening file=%s; opencount == %u\n\n",
231                           new->l_name, new->l_opencount);
232
233       /* If the user requested the object to be in the global namespace
234          but it is not so far, add it now.  */
235       if ((mode & RTLD_GLOBAL) && new->l_global == 0)
236         (void) add_to_global (new);
237
238       /* Increment just the reference counter of the object.  */
239       ++new->l_opencount;
240
241       return;
242     }
243
244   /* Load that object's dependencies.  */
245   _dl_map_object_deps (new, NULL, 0, 0, mode & __RTLD_DLOPEN);
246
247   /* So far, so good.  Now check the versions.  */
248   for (i = 0; i < new->l_searchlist.r_nlist; ++i)
249     if (new->l_searchlist.r_list[i]->l_versions == NULL)
250       (void) _dl_check_map_versions (new->l_searchlist.r_list[i], 0, 0);
251
252 #ifdef SCOPE_DEBUG
253   show_scope (new);
254 #endif
255
256   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
257   lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GL(dl_lazy);
258
259   /* Relocate the objects loaded.  We do this in reverse order so that copy
260      relocs of earlier objects overwrite the data written by later objects.  */
261
262   l = new;
263   while (l->l_next)
264     l = l->l_next;
265   while (1)
266     {
267       if (! l->l_relocated)
268         {
269 #ifdef SHARED
270           if (GL(dl_profile) != NULL)
271             {
272               /* If this here is the shared object which we want to profile
273                  make sure the profile is started.  We can find out whether
274                  this is necessary or not by observing the `_dl_profile_map'
275                  variable.  If was NULL but is not NULL afterwars we must
276                  start the profiling.  */
277               struct link_map *old_profile_map = GL(dl_profile_map);
278
279               _dl_relocate_object (l, l->l_scope, 1, 1);
280
281               if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
282                 /* We must prepare the profiling.  */
283                 _dl_start_profile (GL(dl_profile_map), GL(dl_profile_output));
284             }
285           else
286 #endif
287             _dl_relocate_object (l, l->l_scope, lazy, 0);
288         }
289
290       if (l == new)
291         break;
292       l = l->l_prev;
293     }
294
295   /* Increment the open count for all dependencies.  If the file is
296      not loaded as a dependency here add the search list of the newly
297      loaded object to the scope.  */
298   for (i = 0; i < new->l_searchlist.r_nlist; ++i)
299     if (++new->l_searchlist.r_list[i]->l_opencount > 1
300         && new->l_searchlist.r_list[i]->l_type == lt_loaded)
301       {
302         struct link_map *imap = new->l_searchlist.r_list[i];
303         struct r_scope_elem **runp = imap->l_scope;
304         size_t cnt = 0;
305
306         while (*runp != NULL)
307           {
308             /* This can happen if imap was just loaded, but during
309                relocation had l_opencount bumped because of relocation
310                dependency.  Avoid duplicates in l_scope.  */
311             if (__builtin_expect (*runp == &new->l_searchlist, 0))
312               break;
313
314             ++cnt;
315             ++runp;
316           }
317
318         if (*runp != NULL)
319           /* Avoid duplicates.  */
320           continue;
321
322         if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
323           {
324             /* The 'r_scope' array is too small.  Allocate a new one
325                dynamically.  */
326             struct r_scope_elem **newp;
327             size_t new_size = imap->l_scope_max * 2;
328
329             if (imap->l_scope == imap->l_scope_mem)
330               {
331                 newp = (struct r_scope_elem **)
332                   malloc (new_size * sizeof (struct r_scope_elem *));
333                 if (newp == NULL)
334                   _dl_signal_error (ENOMEM, "dlopen", NULL,
335                                     N_("cannot create scope list"));
336                 imap->l_scope = memcpy (newp, imap->l_scope,
337                                         cnt * sizeof (imap->l_scope[0]));
338               }
339             else
340               {
341                 newp = (struct r_scope_elem **)
342                   realloc (imap->l_scope,
343                            new_size * sizeof (struct r_scope_elem *));
344                 if (newp == NULL)
345                   _dl_signal_error (ENOMEM, "dlopen", NULL,
346                                     N_("cannot create scope list"));
347                 imap->l_scope = newp;
348               }
349
350             imap->l_scope_max = new_size;
351           }
352
353         imap->l_scope[cnt++] = &new->l_searchlist;
354         imap->l_scope[cnt] = NULL;
355       }
356
357   /* Run the initializer functions of new objects.  */
358   _dl_init (new, __libc_argc, __libc_argv, __environ);
359
360   /* Now we can make the new map available in the global scope.  */
361   if (mode & RTLD_GLOBAL)
362     /* Move the object in the global namespace.  */
363     if (add_to_global (new) != 0)
364       /* It failed.  */
365       return;
366
367   /* Mark the object as not deletable if the RTLD_NODELETE flags was
368      passed.  */
369   if (__builtin_expect (mode & RTLD_NODELETE, 0))
370     new->l_flags_1 |= DF_1_NODELETE;
371
372 #ifndef SHARED
373   /* We must be the static _dl_open in libc.a.  A static program that
374      has loaded a dynamic object now has competition.  */
375   __libc_multiple_libcs = 1;
376 #endif
377
378   /* Let the user know about the opencount.  */
379   if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))
380     _dl_debug_printf ("opening file=%s; opencount == %u\n\n",
381                       new->l_name, new->l_opencount);
382 }
383
384
385 void *
386 internal_function
387 _dl_open (const char *file, int mode, const void *caller)
388 {
389   struct dl_open_args args;
390   const char *objname;
391   const char *errstring;
392   int errcode;
393
394   if ((mode & RTLD_BINDING_MASK) == 0)
395     /* One of the flags must be set.  */
396     _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()"));
397
398   /* Make sure we are alone.  */
399   __libc_lock_lock_recursive (GL(dl_load_lock));
400
401   args.file = file;
402   args.mode = mode;
403   args.caller = caller;
404   args.map = NULL;
405   errcode = _dl_catch_error (&objname, &errstring, dl_open_worker, &args);
406
407 #ifndef MAP_COPY
408   /* We must munmap() the cache file.  */
409   _dl_unload_cache ();
410 #endif
411
412   /* Release the lock.  */
413   __libc_lock_unlock_recursive (GL(dl_load_lock));
414
415   if (__builtin_expect (errstring != NULL, 0))
416     {
417       /* Some error occurred during loading.  */
418       char *local_errstring;
419       size_t len_errstring;
420
421       /* Remove the object from memory.  It may be in an inconsistent
422          state if relocation failed, for example.  */
423       if (args.map)
424         {
425           unsigned int i;
426
427           /* Increment open counters for all objects since this has
428              not happened yet.  */
429           for (i = 0; i < args.map->l_searchlist.r_nlist; ++i)
430             ++args.map->l_searchlist.r_list[i]->l_opencount;
431
432           _dl_close (args.map);
433         }
434
435       /* Make a local copy of the error string so that we can release the
436          memory allocated for it.  */
437       len_errstring = strlen (errstring) + 1;
438       if (objname == errstring + len_errstring)
439         {
440           size_t total_len = len_errstring + strlen (objname) + 1;
441           local_errstring = alloca (total_len);
442           memcpy (local_errstring, errstring, total_len);
443           objname = local_errstring + len_errstring;
444         }
445       else
446         {
447           local_errstring = alloca (len_errstring);
448           memcpy (local_errstring, errstring, len_errstring);
449         }
450
451       if (errstring != _dl_out_of_memory)
452         free ((char *) errstring);
453
454       /* Reraise the error.  */
455       _dl_signal_error (errcode, objname, NULL, local_errstring);
456     }
457
458 #ifndef SHARED
459   DL_STATIC_INIT (args.map);
460 #endif
461
462   return args.map;
463 }
464
465
466 #ifdef SCOPE_DEBUG
467 #include <unistd.h>
468
469 static void
470 show_scope (struct link_map *new)
471 {
472   int scope_cnt;
473
474   for (scope_cnt = 0; new->l_scope[scope_cnt] != NULL; ++scope_cnt)
475     {
476       char numbuf[2];
477       unsigned int cnt;
478
479       numbuf[0] = '0' + scope_cnt;
480       numbuf[1] = '\0';
481       _dl_printf ("scope %s:", numbuf);
482
483       for (cnt = 0; cnt < new->l_scope[scope_cnt]->r_nlist; ++cnt)
484         if (*new->l_scope[scope_cnt]->r_list[cnt]->l_name)
485           _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name);
486         else
487           _dl_printf (" <main>");
488
489       _dl_printf ("\n");
490     }
491 }
492 #endif