(add_dependency): Increment object of object and all dependencies.
[kopensolaris-gnu/glibc.git] / elf / dl-lookup.c
1 /* Look up a symbol in the loaded objects.
2    Copyright (C) 1995,96,97,98,99,2000  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 Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    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    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include <alloca.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <ldsodefs.h>
25 #include "dl-hash.h"
26 #include <dl-machine.h>
27 #include <bits/libc-lock.h>
28
29 #include <assert.h>
30
31 #define VERSTAG(tag)    (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
32
33 /* We need this string more than once.  */
34 static const char undefined_msg[] = "undefined symbol: ";
35
36
37 struct sym_val
38   {
39     const ElfW(Sym) *s;
40     struct link_map *m;
41   };
42
43
44 #define make_string(string, rest...) \
45   ({                                                                          \
46     const char *all[] = { string, ## rest };                                  \
47     size_t len, cnt;                                                          \
48     char *result, *cp;                                                        \
49                                                                               \
50     len = 1;                                                                  \
51     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)                \
52       len += strlen (all[cnt]);                                               \
53                                                                               \
54     cp = result = alloca (len);                                               \
55     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)                \
56       cp = __stpcpy (cp, all[cnt]);                                           \
57                                                                               \
58     result;                                                                   \
59   })
60
61 /* Statistics function.  */
62 unsigned long int _dl_num_relocations;
63
64 /* During the program run we must not modify the global data of
65    loaded shared object simultanously in two threads.  Therefore we
66    protect `_dl_open' and `_dl_close' in dl-close.c.
67
68    This must be a recursive lock since the initializer function of
69    the loaded object might as well require a call to this function.
70    At this time it is not anymore a problem to modify the tables.  */
71 __libc_lock_define (extern, _dl_load_lock)
72
73
74 /* We have two different situations when looking up a simple: with or
75    without versioning.  gcc is not able to optimize a single function
76    definition serving for both purposes so we define two functions.  */
77 #define VERSIONED       0
78 #define PROTECTED       0
79 #include "do-lookup.h"
80
81 #define VERSIONED       1
82 #define PROTECTED       0
83 #include "do-lookup.h"
84
85
86 /* Add extra dependency on MAP to UNDEF_MAP.  */
87 static int
88 add_dependency (struct link_map *undef_map, struct link_map *map)
89 {
90   struct link_map **list;
91   unsigned int act;
92   unsigned int i;
93   int result = 0;
94
95   /* Make sure nobody can unload the object while we are at it.  */
96   __libc_lock_lock (_dl_load_lock);
97
98   /* Determine whether UNDEF_MAP already has a reference to MAP.  First
99      look in the normal dependencies.  */
100   list = undef_map->l_searchlist.r_list;
101   act = undef_map->l_searchlist.r_nlist;
102
103   for (i = 0; i < act; ++i)
104     if (list[i] == map)
105       break;
106
107   if (__builtin_expect (i == act, 1))
108     {
109       /* No normal dependency.  See whether we already had to add it
110          to the special list of dynamic dependencies.  */
111       list = undef_map->l_reldeps;
112       act = undef_map->l_reldepsact;
113
114       for (i = 0; i < act; ++i)
115         if (list[i] == map)
116           break;
117
118       if (i == act)
119         {
120           /* The object is not yet in the dependency list.  Before we add
121              it make sure just one more time the object we are about to
122              reference is still available.  There is a brief period in
123              which the object could have been removed since we found the
124              definition.  */
125           struct link_map *runp = _dl_loaded;
126
127           while (runp != NULL && runp != map)
128             runp = runp->l_next;
129
130           if (runp != NULL)
131             {
132               unsigned int j;
133
134               /* The object is still available.  Add the reference now.  */
135               if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
136                 {
137                   /* Allocate more memory for the dependency list.  Since
138                      this can never happen during the startup phase we can
139                      use `realloc'.  */
140                   void *newp;
141
142                   undef_map->l_reldepsmax += 5;
143                   newp = realloc (undef_map->l_reldeps,
144                                   undef_map->l_reldepsmax
145                                   * sizeof(struct link_map *));
146
147                   if (__builtin_expect (newp != NULL, 1))
148                     undef_map->l_reldeps = (struct link_map **) newp;
149                   else
150                     /* Correct the addition.  */
151                     undef_map->l_reldepsmax -= 5;
152                 }
153
154               /* If we didn't manage to allocate memory for the list this
155                  is no fatal mistake.  We simply increment the use counter
156                  of the referenced object and don't record the dependencies.
157                  This means this increment can never be reverted and the
158                  object will never be unloaded.  This is semantically the
159                  correct behaviour.  */
160               if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
161                 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
162
163               /* And increment the counter in the referenced object
164                  and its dependencies.  */
165               if (map->l_initfini != NULL)
166                 for (j = 1; map->l_initfini[j] != NULL; ++j)
167                   ++map->l_initfini[j]->l_opencount;
168               ++map->l_opencount;
169
170               /* Display information if we are debugging.  */
171               if (__builtin_expect (_dl_debug_files, 0))
172                 _dl_debug_message (1, "\nfile=",
173                                    map->l_name[0] ? map->l_name : _dl_argv[0],
174                                    ";  needed by ",
175                                    undef_map->l_name[0]
176                                    ? undef_map->l_name : _dl_argv[0],
177                                    " (relocation dependency)\n\n", NULL);
178             }
179           else
180             /* Whoa, that was bad luck.  We have to search again.  */
181             result = -1;
182         }
183     }
184
185   /* Release the lock.  */
186   __libc_lock_unlock (_dl_load_lock);
187
188   return result;
189 }
190
191
192 /* Search loaded objects' symbol tables for a definition of the symbol
193    UNDEF_NAME.  */
194
195 lookup_t
196 internal_function
197 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
198                    const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
199                    int reloc_type, int explicit)
200 {
201   const char *reference_name = undef_map ? undef_map->l_name : NULL;
202   const unsigned long int hash = _dl_elf_hash (undef_name);
203   struct sym_val current_value = { NULL, NULL };
204   struct r_scope_elem **scope;
205   int protected;
206   int noexec = elf_machine_lookup_noexec_p (reloc_type);
207   int noplt = elf_machine_lookup_noplt_p (reloc_type);
208
209   ++_dl_num_relocations;
210
211   /* Search the relevant loaded objects for a definition.  */
212   for (scope = symbol_scope; *scope; ++scope)
213     if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
214                    noexec, noplt))
215       {
216         /* We have to check whether this would bind UNDEF_MAP to an object
217            in the global scope which was dynamically loaded.  In this case
218            we have to prevent the latter from being unloaded unless the
219            UNDEF_MAP object is also unloaded.  */
220         if (__builtin_expect (current_value.m->l_global, 0)
221             && (__builtin_expect (current_value.m->l_type, lt_library)
222                 == lt_loaded)
223             && undef_map != current_value.m
224             /* Don't do this for explicit lookups as opposed to implicit
225                runtime lookups.  */
226             && __builtin_expect (! explicit, 1)
227             /* Add UNDEF_MAP to the dependencies.  */
228             && add_dependency (undef_map, current_value.m) < 0)
229           /* Something went wrong.  Perhaps the object we tried to reference
230              was just removed.  Try finding another definition.  */
231           return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
232                                     reloc_type, 0);
233
234         break;
235       }
236
237   if (__builtin_expect (current_value.s == NULL, 0))
238     {
239       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
240         /* We could find no value for a strong reference.  */
241         /* XXX We cannot translate the messages.  */
242         _dl_signal_cerror (0, (reference_name && reference_name[0]
243                                ? reference_name
244                                : (_dl_argv[0] ?: "<main program>")),
245                            make_string (undefined_msg, undef_name));
246       *ref = NULL;
247       return 0;
248     }
249
250   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
251
252   if (__builtin_expect (_dl_debug_bindings, 0))
253     _dl_debug_message (1, "binding file ",
254                        (reference_name && reference_name[0]
255                         ? reference_name
256                         : (_dl_argv[0] ?: "<main program>")),
257                        " to ", current_value.m->l_name[0]
258                        ? current_value.m->l_name : _dl_argv[0],
259                        ": ", protected ? "protected" : "normal",
260                        " symbol `", undef_name, "'\n", NULL);
261
262   if (__builtin_expect (protected == 0, 1))
263     {
264       *ref = current_value.s;
265       return LOOKUP_VALUE (current_value.m);
266     }
267   else
268     {
269       /* It is very tricky. We need to figure out what value to
270          return for the protected symbol */
271       struct sym_val protected_value = { NULL, NULL };
272
273       for (scope = symbol_scope; *scope; ++scope)
274         if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
275                        NULL, 0, 1))
276           break;
277
278       if (protected_value.s == NULL || protected_value.m == undef_map)
279         {
280           *ref = current_value.s;
281           return LOOKUP_VALUE (current_value.m);
282         }
283
284       return LOOKUP_VALUE (undef_map);
285     }
286 }
287
288
289 /* This function is nearly the same as `_dl_lookup_symbol' but it
290    skips in the first list all objects until SKIP_MAP is found.  I.e.,
291    it only considers objects which were loaded after the described
292    object.  If there are more search lists the object described by
293    SKIP_MAP is only skipped.  */
294 lookup_t
295 internal_function
296 _dl_lookup_symbol_skip (const char *undef_name,
297                         struct link_map *undef_map, const ElfW(Sym) **ref,
298                         struct r_scope_elem *symbol_scope[],
299                         struct link_map *skip_map)
300 {
301   const char *reference_name = undef_map ? undef_map->l_name : NULL;
302   const unsigned long int hash = _dl_elf_hash (undef_name);
303   struct sym_val current_value = { NULL, NULL };
304   struct r_scope_elem **scope;
305   size_t i;
306   int protected;
307
308   ++_dl_num_relocations;
309
310   /* Search the relevant loaded objects for a definition.  */
311   scope = symbol_scope;
312   for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
313     assert (i < (*scope)->r_nduplist);
314
315   if (i >= (*scope)->r_nlist
316          || ! do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
317                          skip_map, 0, 0))
318     while (*++scope)
319       if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
320                      skip_map, 0, 0))
321         break;
322
323   if (__builtin_expect (current_value.s == NULL, 0))
324     {
325       *ref = NULL;
326       return 0;
327     }
328
329   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
330
331   if (__builtin_expect (_dl_debug_bindings, 0))
332     _dl_debug_message (1, "binding file ",
333                        (reference_name && reference_name[0]
334                         ? reference_name
335                         : (_dl_argv[0] ?: "<main program>")),
336                        " to ", current_value.m->l_name[0]
337                        ? current_value.m->l_name : _dl_argv[0],
338                        ": ", protected ? "protected" : "normal",
339                        " symbol `", undef_name, "'\n", NULL);
340
341   if (__builtin_expect (protected == 0, 1))
342     {
343       *ref = current_value.s;
344       return LOOKUP_VALUE (current_value.m);
345     }
346   else
347     {
348       /* It is very tricky.  We need to figure out what value to
349          return for the protected symbol.  */
350       struct sym_val protected_value = { NULL, NULL };
351
352       if (i >= (*scope)->r_nlist
353           || !do_lookup (undef_name, hash, *ref, &protected_value, *scope, i,
354                          skip_map, 0, 1))
355         while (*++scope)
356           if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
357                          skip_map, 0, 1))
358             break;
359
360       if (protected_value.s == NULL || protected_value.m == undef_map)
361         {
362           *ref = current_value.s;
363           return LOOKUP_VALUE (current_value.m);
364         }
365
366       return LOOKUP_VALUE (undef_map);
367     }
368 }
369
370
371 /* This function works like _dl_lookup_symbol but it takes an
372    additional arguement with the version number of the requested
373    symbol.
374
375    XXX We'll see whether we need this separate function.  */
376 lookup_t
377 internal_function
378 _dl_lookup_versioned_symbol (const char *undef_name,
379                              struct link_map *undef_map, const ElfW(Sym) **ref,
380                              struct r_scope_elem *symbol_scope[],
381                              const struct r_found_version *version,
382                              int reloc_type, int explicit)
383 {
384   const char *reference_name = undef_map ? undef_map->l_name : NULL;
385   const unsigned long int hash = _dl_elf_hash (undef_name);
386   struct sym_val current_value = { NULL, NULL };
387   struct r_scope_elem **scope;
388   int protected;
389   int noexec = elf_machine_lookup_noexec_p (reloc_type);
390   int noplt = elf_machine_lookup_noplt_p (reloc_type);
391
392   ++_dl_num_relocations;
393
394   /* Search the relevant loaded objects for a definition.  */
395   for (scope = symbol_scope; *scope; ++scope)
396     {
397       int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
398                                      *scope, 0, version, NULL, noexec, noplt);
399       if (res > 0)
400         {
401           /* We have to check whether this would bind UNDEF_MAP to an object
402              in the global scope which was dynamically loaded.  In this case
403              we have to prevent the latter from being unloaded unless the
404              UNDEF_MAP object is also unloaded.  */
405           if (__builtin_expect (current_value.m->l_global, 0)
406               && (__builtin_expect (current_value.m->l_type, lt_library)
407                   == lt_loaded)
408               && undef_map != current_value.m
409               /* Don't do this for explicit lookups as opposed to implicit
410                  runtime lookups.  */
411               && __builtin_expect (! explicit, 1)
412               /* Add UNDEF_MAP to the dependencies.  */
413               && add_dependency (undef_map, current_value.m) < 0)
414             /* Something went wrong.  Perhaps the object we tried to reference
415                was just removed.  Try finding another definition.  */
416             return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
417                                                 symbol_scope, version,
418                                                 reloc_type, 0);
419
420           break;
421         }
422
423       if (__builtin_expect (res, 0) < 0)
424         {
425           /* Oh, oh.  The file named in the relocation entry does not
426              contain the needed symbol.  */
427           /* XXX We cannot translate the message.  */
428           _dl_signal_cerror (0, (reference_name && reference_name[0]
429                                  ? reference_name
430                                  : (_dl_argv[0] ?: "<main program>")),
431                              make_string ("symbol ", undef_name, ", version ",
432                                           version->name,
433                                           " not defined in file ",
434                                           version->filename,
435                                           " with link time reference",
436                                           res == -2
437                                           ? " (no version symbols)" : ""));
438           *ref = NULL;
439           return 0;
440         }
441     }
442
443   if (__builtin_expect (current_value.s == NULL, 0))
444     {
445       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
446         /* We could find no value for a strong reference.  */
447         /* XXX We cannot translate the message.  */
448         _dl_signal_cerror (0, (reference_name && reference_name[0]
449                                ? reference_name
450                                : (_dl_argv[0] ?: "<main program>")),
451                            make_string (undefined_msg, undef_name,
452                                         ", version ", version->name ?: NULL));
453       *ref = NULL;
454       return 0;
455     }
456
457   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
458
459   if (__builtin_expect (_dl_debug_bindings, 0))
460     _dl_debug_message (1, "binding file ",
461                        (reference_name && reference_name[0]
462                         ? reference_name
463                         : (_dl_argv[0] ?: "<main program>")),
464                        " to ", current_value.m->l_name[0]
465                        ? current_value.m->l_name : _dl_argv[0],
466                        ": ", protected ? "protected" : "normal",
467                        " symbol `", undef_name, "' [", version->name,
468                        "]\n", NULL);
469
470   if (__builtin_expect (protected == 0, 1))
471     {
472       *ref = current_value.s;
473       return LOOKUP_VALUE (current_value.m);
474     }
475   else
476     {
477       /* It is very tricky. We need to figure out what value to
478          return for the protected symbol */
479       struct sym_val protected_value = { NULL, NULL };
480
481       for (scope = symbol_scope; *scope; ++scope)
482         if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
483                                  *scope, 0, version, NULL, 0, 1))
484           break;
485
486       if (protected_value.s == NULL || protected_value.m == undef_map)
487         {
488           *ref = current_value.s;
489           return LOOKUP_VALUE (current_value.m);
490         }
491
492       return LOOKUP_VALUE (undef_map);
493     }
494 }
495
496
497 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
498    with the version we are looking for.  */
499 lookup_t
500 internal_function
501 _dl_lookup_versioned_symbol_skip (const char *undef_name,
502                                   struct link_map *undef_map,
503                                   const ElfW(Sym) **ref,
504                                   struct r_scope_elem *symbol_scope[],
505                                   const struct r_found_version *version,
506                                   struct link_map *skip_map)
507 {
508   const char *reference_name = undef_map ? undef_map->l_name : NULL;
509   const unsigned long int hash = _dl_elf_hash (undef_name);
510   struct sym_val current_value = { NULL, NULL };
511   struct r_scope_elem **scope;
512   size_t i;
513   int protected;
514
515   ++_dl_num_relocations;
516
517   /* Search the relevant loaded objects for a definition.  */
518   scope = symbol_scope;
519   for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
520     assert (i < (*scope)->r_nduplist);
521
522   if (i >= (*scope)->r_nlist
523       || ! do_lookup_versioned (undef_name, hash, *ref, &current_value,
524                                 *scope, i, version, skip_map, 0, 0))
525     while (*++scope)
526       if (do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope,
527                                0, version, skip_map, 0, 0))
528         break;
529
530   if (__builtin_expect (current_value.s == NULL, 0))
531     {
532       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
533         {
534           /* We could find no value for a strong reference.  */
535           const size_t len = strlen (undef_name);
536           char buf[sizeof undefined_msg + len];
537           __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
538                      undef_name, len + 1);
539           /* XXX We cannot translate the messages.  */
540           _dl_signal_cerror (0, (reference_name && reference_name[0]
541                                  ? reference_name
542                                  : (_dl_argv[0] ?: "<main program>")), buf);
543         }
544       *ref = NULL;
545       return 0;
546     }
547
548   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
549
550   if (__builtin_expect (_dl_debug_bindings, 0))
551     _dl_debug_message (1, "binding file ",
552                        (reference_name && reference_name[0]
553                         ? reference_name
554                         : (_dl_argv[0] ?: "<main program>")),
555                        " to ", current_value.m->l_name[0]
556                        ? current_value.m->l_name : _dl_argv[0],
557                        ": ", protected ? "protected" : "normal",
558                        " symbol `", undef_name, "' [", version->name,
559                        "]\n", NULL);
560
561   if (__builtin_expect (protected == 0, 1))
562     {
563       *ref = current_value.s;
564       return LOOKUP_VALUE (current_value.m);
565     }
566   else
567     {
568       /* It is very tricky. We need to figure out what value to
569          return for the protected symbol */
570       struct sym_val protected_value = { NULL, NULL };
571
572       if (i >= (*scope)->r_nlist
573           || !do_lookup_versioned (undef_name, hash, *ref, &protected_value,
574                                    *scope, i, version, skip_map, 0, 1))
575         while (*++scope)
576           if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
577                                    *scope, 0, version, skip_map, 0, 1))
578             break;
579
580       if (protected_value.s == NULL || protected_value.m == undef_map)
581         {
582           *ref = current_value.s;
583           return LOOKUP_VALUE (current_value.m);
584         }
585
586       return LOOKUP_VALUE (undef_map);
587     }
588 }
589
590
591 /* Cache the location of MAP's hash table.  */
592
593 void
594 internal_function
595 _dl_setup_hash (struct link_map *map)
596 {
597   Elf_Symndx *hash;
598   Elf_Symndx nchain;
599
600   if (!map->l_info[DT_HASH])
601     return;
602   hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
603
604   map->l_nbuckets = *hash++;
605   nchain = *hash++;
606   map->l_buckets = hash;
607   hash += map->l_nbuckets;
608   map->l_chain = hash;
609 }