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 (dst != NULL)
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,
212                                     mode);
213
214   /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
215      set and the object is not already loaded.  */
216   if (new == NULL)
217     {
218       assert (mode & RTLD_NOLOAD);
219       return;
220     }
221
222   if (__builtin_expect (mode & __RTLD_SPROF, 0))
223     /* This happens only if we load a DSO for 'sprof'.  */
224     return;
225
226   /* It was already open.  */
227   if (new->l_searchlist.r_list != NULL)
228     {
229       /* Let the user know about the opencount.  */
230       if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))
231         _dl_debug_printf ("opening file=%s; opencount == %u\n\n",
232                           new->l_name, new->l_opencount);
233
234       /* If the user requested the object to be in the global namespace
235          but it is not so far, add it now.  */
236       if ((mode & RTLD_GLOBAL) && new->l_global == 0)
237         (void) add_to_global (new);
238
239       /* Increment just the reference counter of the object.  */
240       ++new->l_opencount;
241
242       return;
243     }
244
245   /* Load that object's dependencies.  */
246   _dl_map_object_deps (new, NULL, 0, 0);
247
248   /* So far, so good.  Now check the versions.  */
249   for (i = 0; i < new->l_searchlist.r_nlist; ++i)
250     if (new->l_searchlist.r_list[i]->l_versions == NULL)
251       (void) _dl_check_map_versions (new->l_searchlist.r_list[i], 0, 0);
252
253 #ifdef SCOPE_DEBUG
254   show_scope (new);
255 #endif
256
257   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
258   lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GL(dl_lazy);
259
260   /* Relocate the objects loaded.  We do this in reverse order so that copy
261      relocs of earlier objects overwrite the data written by later objects.  */
262
263   l = new;
264   while (l->l_next)
265     l = l->l_next;
266   while (1)
267     {
268       if (! l->l_relocated)
269         {
270 #ifdef SHARED
271           if (GL(dl_profile) != NULL)
272             {
273               /* If this here is the shared object which we want to profile
274                  make sure the profile is started.  We can find out whether
275                  this is necessary or not by observing the `_dl_profile_map'
276                  variable.  If was NULL but is not NULL afterwars we must
277                  start the profiling.  */
278               struct link_map *old_profile_map = GL(dl_profile_map);
279
280               _dl_relocate_object (l, l->l_scope, 1, 1);
281
282               if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
283                 /* We must prepare the profiling.  */
284                 _dl_start_profile (GL(dl_profile_map), GL(dl_profile_output));
285             }
286           else
287 #endif
288             _dl_relocate_object (l, l->l_scope, lazy, 0);
289         }
290
291       if (l == new)
292         break;
293       l = l->l_prev;
294     }
295
296   /* Increment the open count for all dependencies.  If the file is
297      not loaded as a dependency here add the search list of the newly
298      loaded object to the scope.  */
299   for (i = 0; i < new->l_searchlist.r_nlist; ++i)
300     if (++new->l_searchlist.r_list[i]->l_opencount > 1
301         && new->l_searchlist.r_list[i]->l_type == lt_loaded)
302       {
303         struct link_map *imap = new->l_searchlist.r_list[i];
304         struct r_scope_elem **runp = imap->l_scope;
305         size_t cnt = 0;
306
307         while (*runp != NULL)
308           {
309             /* This can happen if imap was just loaded, but during
310                relocation had l_opencount bumped because of relocation
311                dependency.  Avoid duplicates in l_scope.  */
312             if (__builtin_expect (*runp == &new->l_searchlist, 0))
313               break;
314
315             ++cnt;
316             ++runp;
317           }
318
319         if (*runp != NULL)
320           /* Avoid duplicates.  */
321           continue;
322
323         if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
324           {
325             /* The 'r_scope' array is too small.  Allocate a new one
326                dynamically.  */
327             struct r_scope_elem **newp;
328             size_t new_size = imap->l_scope_max * 2;
329
330             if (imap->l_scope == imap->l_scope_mem)
331               {
332                 newp = (struct r_scope_elem **)
333                   malloc (new_size * sizeof (struct r_scope_elem *));
334                 if (newp == NULL)
335                   _dl_signal_error (ENOMEM, "dlopen", NULL,
336                                     N_("cannot create scope list"));
337                 imap->l_scope = memcpy (newp, imap->l_scope,
338                                         cnt * sizeof (imap->l_scope[0]));
339               }
340             else
341               {
342                 newp = (struct r_scope_elem **)
343                   realloc (imap->l_scope,
344                            new_size * sizeof (struct r_scope_elem *));
345                 if (newp == NULL)
346                   _dl_signal_error (ENOMEM, "dlopen", NULL,
347                                     N_("cannot create scope list"));
348                 imap->l_scope = newp;
349               }
350
351             imap->l_scope_max = new_size;
352           }
353
354         imap->l_scope[cnt++] = &new->l_searchlist;
355         imap->l_scope[cnt] = NULL;
356       }
357
358   /* Run the initializer functions of new objects.  */
359   _dl_init (new, __libc_argc, __libc_argv, __environ);
360
361   /* Now we can make the new map available in the global scope.  */
362   if (mode & RTLD_GLOBAL)
363     /* Move the object in the global namespace.  */
364     if (add_to_global (new) != 0)
365       /* It failed.  */
366       return;
367
368   /* Mark the object as not deletable if the RTLD_NODELETE flags was
369      passed.  */
370   if (__builtin_expect (mode & RTLD_NODELETE, 0))
371     new->l_flags_1 |= DF_1_NODELETE;
372
373 #ifndef SHARED
374   /* We must be the static _dl_open in libc.a.  A static program that
375      has loaded a dynamic object now has competition.  */
376   __libc_multiple_libcs = 1;
377 #endif
378
379   /* Let the user know about the opencount.  */
380   if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))
381     _dl_debug_printf ("opening file=%s; opencount == %u\n\n",
382                       new->l_name, new->l_opencount);
383 }
384
385
386 void *
387 internal_function
388 _dl_open (const char *file, int mode, const void *caller)
389 {
390   struct dl_open_args args;
391   const char *objname;
392   const char *errstring;
393   int errcode;
394
395   if ((mode & RTLD_BINDING_MASK) == 0)
396     /* One of the flags must be set.  */
397     _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()"));
398
399   /* Make sure we are alone.  */
400   __libc_lock_lock_recursive (GL(dl_load_lock));
401
402   args.file = file;
403   args.mode = mode;
404   args.caller = caller;
405   args.map = NULL;
406   errcode = _dl_catch_error (&objname, &errstring, dl_open_worker, &args);
407
408 #ifndef MAP_COPY
409   /* We must munmap() the cache file.  */
410   _dl_unload_cache ();
411 #endif
412
413   /* Release the lock.  */
414   __libc_lock_unlock_recursive (GL(dl_load_lock));
415
416   if (errstring)
417     {
418       /* Some error occurred during loading.  */
419       char *local_errstring;
420       size_t len_errstring;
421
422       /* Remove the object from memory.  It may be in an inconsistent
423          state if relocation failed, for example.  */
424       if (args.map)
425         {
426           unsigned int i;
427
428           /* Increment open counters for all objects since this has
429              not happened yet.  */
430           for (i = 0; i < args.map->l_searchlist.r_nlist; ++i)
431             ++args.map->l_searchlist.r_list[i]->l_opencount;
432
433           _dl_close (args.map);
434         }
435
436       /* Make a local copy of the error string so that we can release the
437          memory allocated for it.  */
438       len_errstring = strlen (errstring) + 1;
439       if (objname == errstring + len_errstring)
440         {
441           size_t total_len = len_errstring + strlen (objname) + 1;
442           local_errstring = alloca (total_len);
443           memcpy (local_errstring, errstring, total_len);
444           objname = local_errstring + len_errstring;
445         }
446       else
447         {
448           local_errstring = alloca (len_errstring);
449           memcpy (local_errstring, errstring, len_errstring);
450         }
451
452       if (errstring != _dl_out_of_memory)
453         free ((char *) errstring);
454
455       /* Reraise the error.  */
456       _dl_signal_error (errcode, objname, NULL, local_errstring);
457     }
458
459 #ifndef SHARED
460   DL_STATIC_INIT (args.map);
461 #endif
462
463   return args.map;
464 }
465
466
467 #ifdef SCOPE_DEBUG
468 #include <unistd.h>
469
470 static void
471 show_scope (struct link_map *new)
472 {
473   int scope_cnt;
474
475   for (scope_cnt = 0; new->l_scope[scope_cnt] != NULL; ++scope_cnt)
476     {
477       char numbuf[2];
478       unsigned int cnt;
479
480       numbuf[0] = '0' + scope_cnt;
481       numbuf[1] = '\0';
482       _dl_printf ("scope %s:", numbuf);
483
484       for (cnt = 0; cnt < new->l_scope[scope_cnt]->r_nlist; ++cnt)
485         if (*new->l_scope[scope_cnt]->r_list[cnt]->l_name)
486           _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name);
487         else
488           _dl_printf (" <main>");
489
490       _dl_printf ("\n");
491     }
492 }
493 #endif